In the doc, it says

bytes: Dynamically-sized byte array, see Arrays. Not a value-type!

string: Dynamically-sized UTF-8-encoded string, see Arrays. Not a value-type!

Not a value-type!

If bytes/string are not value-types, why are these placed in Value Types section?

  • You can report an issue to the github solidity compiler repo, and sent a pull request to fix the problem.
    – Ismael
    May 24, 2018 at 3:28
  • Ok. I just did. Let's see how it goes.
    – bbusdriver
    May 24, 2018 at 5:25

1 Answer 1


In Solidity's documentation, the term "value types" is sometimes used in a broad sense to include any type that can be assigned a value directly. This can be a bit confusing because "value type" in many programming language contexts refers to types that are passed by value (i.e., a copy is made on assignment or when passed to functions).

In the case of Solidity:

  • Value types are types that have their data directly stored in the location you assign it to. This is opposed to reference types, where the location contains a pointer to the actual data. The basic data types like bool, int, uint, and fixed-size byte arrays like bytes1, bytes2, ..., bytes32 are typical value types because they are passed by value — a copy is made when they are passed to functions or used in assignments.

  • Dynamic types like bytes and string are a bit different. They behave like value types in the sense that you can assign values to them directly, but they're stored in a way that's more akin to reference types. For these types, the variable that you interact with actually holds a reference to the location of the data, not the data itself, because the size of the data can change.

The Solidity documentation places bytes and string under the "Value Types" section likely because they are not objects or structs, which are traditional reference types in many languages. However, the term "Not a value-type!" is there to clarify that they are not value types in the strictest sense — they are special cases.

Here's why bytes and string are special:

  • They are dynamically-sized, meaning they can grow in length, which is not something value types can typically do.
  • They are passed by reference in function calls internally to save on gas costs, even though syntactically they are treated as value types.
  • They do not have a fixed size at compile time; their size is determined at runtime.

This distinction is important for understanding how data is stored and how it is passed around in your smart contracts. It affects how you interact with the data, how you optimize for gas costs, and how you manage memory and storage.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.