3

In C++, is an object a storage location (container) or a value (content)?

With this sentence from [intro.object]/1, one can assume it is a value (bold emphasis mine):

An object occupies a region of storage in its period of construction ([class.cdtor]), throughout its lifetime, and in its period of destruction ([class.cdtor]).

With this sentence from [basic.types.general]/2, one can assume it is a storage location (bold emphasis mine):

For any object (other than a potentially-overlapping subobject) of trivially copyable type T, whether or not the object holds a valid value of type T, the underlying bytes ([intro.memory]) making up the object can be copied into an array of char, unsigned char, or std​::​byte ([cstddef.syn]).

Géry Ogam
  • 6,336
  • 4
  • 38
  • 67
  • An unitialized object occupies storage but does not hold a valid value. – molbdnilo Oct 28 '21 at 07:47
  • a storage locations that holds a value maybe even if it is not initialized – Anis Belaid Oct 28 '21 at 07:54
  • An object is a value *and* the storage it occupies. – alex_noname Oct 28 '21 at 08:32
  • An object is an object. – Language Lawyer Oct 28 '21 at 11:10
  • 1
    An object is a region of storage and a set of operations that can be performed on that region of storage. Some objects have values because assigning and reading are valid operations on their storage. – Pete Becker Oct 28 '21 at 13:57
  • @PeteBecker _An object is a region of storage_ Fortunately, this is no longer the case. – Language Lawyer Oct 28 '21 at 14:10
  • @LanguageLawyer Could you elaborate? – Géry Ogam Nov 01 '21 at 08:08
  • @PeteBecker You are confusing objects with class objects. An `int` is an object yet it does not have methods. – Géry Ogam Nov 01 '21 at 08:10
  • @Maggyero `+` is an operation that can be performed on an `int` object. "a set of operations" != "member functions" – Caleth Nov 01 '21 at 09:07
  • 2
    @Maggyero: Herb Sutter has even argued that the set of operations for **classes** is more than their members; it should also include the free functions defined in their header. Pete Becker has an entirely valid point. In Comp.Sci terms, operations define the type, and the chief properties of an object are its type and position in memory. – MSalters Nov 01 '21 at 09:52
  • 1
    See also https://stackoverflow.com/questions/3601602/what-are-rvalues-lvalues-xvalues-glvalues-and-prvalues for a more thorough analysis. – MSalters Nov 01 '21 at 09:55
  • @MSalters ‘chief properties of an object are its type and position in memory.’ Interesting. But non-objects such as references and functions also have a type, don’t they? – Géry Ogam Nov 01 '21 at 10:19
  • @Maggyero: True, and more importantly expressions such as `2+2` have type. Type is a property of objects, but it's not unique to objects. – MSalters Nov 01 '21 at 10:27
  • @MSalters So isn’t the chief (distinguishing) property of an object its location (so object ≠ value)? – Géry Ogam Nov 01 '21 at 10:39
  • 1
    @Maggyero: It's very important, but that location may coincide with the location of a sub-object (member or base). You need both type and location. – MSalters Nov 01 '21 at 11:33
  • @Maggyero -- I didn't (and don't) use the word "methods". Read what I said. An `int` object has operations that can be performed on it: you can store a value, read the stored value, increment the stored value, decrement the stored value, etc. – Pete Becker Nov 01 '21 at 12:22
  • @MSalters ‘It's very important, but that location may coincide with the location of a sub-object (member or base). You need both type and location.’ I see, you mean that without specifying its type, a derived object would be confused with its base object, as [\[intro.object\]/6](https://timsong-cpp.github.io/cppwp/basic#intro.object-6) specifies: ‘If a complete object, a member subobject, or an array element is of class type, its type is considered the most derived class, to distinguish it from the class type of any base class subobject;’ – Géry Ogam Nov 01 '21 at 18:52
  • @PeteBecker My bad, I thought you were only referring to member functions. Now where does the standard specify that an object has a set of operations? It specifies that it has a type, at [\[intro.object\]/1](https://timsong-cpp.github.io/cppwp/basic#intro.object-1), so I am assuming that you derived that from there, but then where is a type specified that way? – Géry Ogam Nov 01 '21 at 19:08
  • @Maggyero -- that's a compiler writer's notion of an object. It offers a very helpful perspective. – Pete Becker Nov 01 '21 at 19:14
  • @PeteBecker I like your clear definition (object = storage location + type). Didn’t you forget the *storage duration*, since different objects can have the same storage location at non-overlapping time periods (object = storage location + storage duration + type)? – Géry Ogam Nov 04 '21 at 06:42
  • @MSalters Do you agree with my last comment to PeteBecker? – Géry Ogam Nov 16 '21 at 11:05
  • @Maggyero: No. _Storage duration_ is a specific term in C++. I suspect you mean _lifetime_. Since you're trying to be hyper-precise here, the differences between those terms is huge. There are only a few possible storage durations. (auto, static, thread) – MSalters Nov 16 '21 at 12:10
  • @MSalters Yes sorry, I meant *object lifetime*, which is just a subset of storage duration (duration of storage allocation). So I meant object = storage location + lifetime + type. Do you agree with this definition? – Géry Ogam Nov 19 '21 at 07:45
  • 1
    @Maggyero: Those are indeed the minimal properties. Some objects have more properties, e.g. a name. And note that since C++11, lifetimes are only restricted by _sequenced-after_ and _sequenced-before_ constraints. – MSalters Nov 19 '21 at 09:17
  • @MSalters I see. Can objects change location during their lifetime in memory in C++ like objects in the real world, or they can only have a fixed location? – Géry Ogam Nov 24 '21 at 07:04
  • @Maggyero: According to the standard, no, but in real-life the as-if optimization rules kick in. Therefore, creating a pointer to an object can prevent optimizations – MSalters Nov 24 '21 at 20:28
  • @MSalters Thanks. SergeBallesta made the interesting comment that move construction can be seen as a way to change an object’s location in memory (like we would move a cup of tea in real space). In this view, an object (besides its type) is no more a *single* fixed storage location and a lifetime, but a *sequence* of storage locations at different times. – Géry Ogam Nov 25 '21 at 09:51
  • 1
    @Maggyero: Well, that's just conceptual. C++ makes it very explicit : moving involves calling the "move constructor", which like all constructors creates a new object in a new location. Afterwards, typically the destructor is called on the moved-from object, but this can be quite a bit later. In the mean time, two objects exist. – MSalters Nov 25 '21 at 14:26

1 Answers1

4

An object is an entity that has a type (a set of operations that can be performed on it) and occupies some allocated storage region with the proper size (given by the operator sizeof) and alignment (given by the operator alignof) for the type. The storage region has an address (given by the operator &) and holds a representation which is a sequence of bytes, a subset of which represents a value. An object finally has a lifetime which starts at the end of its initialization, and ends at the start of its finalization or when its storage region is deallocated or reused by another object.

Using an object outside its lifetime is undefined behaviour.

As a programmer can change the representation of an object at any time by directly accessing its bytes, an object can hold a valid value or not. Invalid values for basic types are known as trap representation and using an object containing such a trap representation is undefined behaviour.

So an object is neither a storage region nor a value, but a complex thing that is called object in C language.

Géry Ogam
  • 6,336
  • 4
  • 38
  • 67
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • Thanks. All the properties that you give seem to apply to a storage location (has address and therefore has value, has type, and has size), except the lifetime property which bounds the time extent of the storage location. So do you agree that an object is a storage location *at a given period* (i.e. a spatio-*temporal* extent)? – Géry Ogam Nov 01 '21 at 10:04
  • 1
    You are forgotting about the type... An object has a type and accessing it with an incorrect type (except for the character types) is explicitely UB. – Serge Ballesta Nov 01 '21 at 13:44
  • Okay, so object = storage location + storage duration + type? – Géry Ogam Nov 04 '21 at 06:34
  • 1
    @Maggyero: I cannot think of other key attributes. So yes, it is all that. – Serge Ballesta Nov 04 '21 at 08:06
  • Sorry, I meant object = storage location + lifetime + type. Can objects change location during their lifetime in memory in C++ like objects in the real world, or they can only have a fixed location? – Géry Ogam Nov 24 '21 at 07:42
  • 1
    @Maggyero: The address of an object cannot change. But an object can be *moved* in which case you will get a strictly equivalent object in a different location. But the move will end the lifetime of the original object and create a new (even if not really independant) one. – Serge Ballesta Nov 24 '21 at 11:05
  • That is a very interesting insight, I hadn’t thought about seeing move construction as a way to change an object’s location in memory, like we would move a cup of tea in real space. In this view, an object (besides its type) is no more a *single* fixed storage location and a lifetime, but a *sequence* of storage locations at different times. – Géry Ogam Nov 25 '21 at 09:55
  • _An object is an entity_ Inclusion of objects into [entities](https://timsong-cpp.github.io/cppwp/n4868/basic.pre#def:entity) is likely a defect. – Language Lawyer Nov 25 '21 at 12:30