2

I am learning C++ using the books listed here. My question is that is there a difference between a variable and an object. Consider the following example:

int i = 0; //i is an object of type int. Or we can say i is a variable of type int
int &refI = i; //refI is a "reference variable" of "reference type `int&`. But here refI is not an object. 

My current understanding is that both of the terms variable and object overlaps to a large extent. But in some contexts like in case of refI above, there can be some differences. In particular, refI is a reference variable of reference type int& and refI is not an object because a reference is an alias for some other object. While i is both an object and a variable.

My question is that am i correctly analyzing the refI case above? If not, what does the standard say about this.

My second question is that, does the standard C++ strictly differentiate between these two terms. If yes, how and where. For example something like,

a variable may be defined as an object with a name. And any object without a name is not a variable.

Here the user says that a variable and object are different.

Edit

I am also asking this question because i am aware that in Python(as it is a dynamically typed language) there is a clear distinction between variables and objects. Does the C++ standard also make such a clear distinction.

Jason
  • 36,170
  • 5
  • 26
  • 60
  • IMHO, a variable is just a name for something which allows you to deal with stuff. It can be a primitive, an object, a reference, a pointer, a function (lambda), anything. – Thomas Weller Mar 18 '22 at 17:37
  • @DrewDormann Are prvalues objects? I don't even know at this point. :/ – HolyBlackCat Mar 18 '22 at 17:45
  • @HolyBlackCat oh boy... I'm strongly inclined to say "yes, absolutely" but then you might ask me if I've ever been terribly wrong about C++ minutiae. I would say that a prvalue is always an object, and now I'm following this question to hear the blowback. – Drew Dormann Mar 18 '22 at 17:46
  • My answer to the linked question is borderline too informal for the "language-lawyer" tag. I'll stay away from this one. All I do know is that reference bind variables (and anonymous temporaries). Good question by the way, +1. – Bathsheba Mar 18 '22 at 17:47
  • 1
    _"**Please respect the language-lawyer tag.**"_ means what exactly? Edit your question in constructive ways, if you do. – πάντα ῥεῖ Mar 18 '22 at 17:48
  • 7
    @πάνταῥεῖ: It means that charlatans like me shouldn't attempt to answer it ;-) – Bathsheba Mar 18 '22 at 17:49
  • @πάνταῥεῖ It means that people's answer should not include words like *"IMO"* or *"IMHO"*. And they should provide official source. Because i have seen many answers that ignores the language-lawyer tag completely. – Jason Mar 18 '22 at 17:49
  • 3
    I'm a bit concerned here. The question is phrased as though it's a beginner C++ question, but it's tagged language-lawyer. The beginner C++ answer to "what's the difference between an object and a variable" is *very* different than the expert answer that would cite the standard. If you're just starting out, I have to recommend removing that tag, as it's only going to confuse you right now. I was programming in C++ for nearly a decade before I was able to understand any part of the C++ standard; it's not built to be a tutorial but a reference guide for experts. – Silvio Mayolo Mar 18 '22 at 17:50
  • @Anya then you probably misunderstood the meaning of the [tag:language-lawyer] tag at all. – πάντα ῥεῖ Mar 18 '22 at 17:51
  • @πάνταῥεῖ How? Language-lawyer tag is used when we want an exact quote from official documentation chapter. – Jason Mar 18 '22 at 17:52
  • 2
    The C++ standard is not like, say, python.org. I check python.org all the time when writing Python. I only check the C++ standard to answer technicality question on SO, not when doing "normal" programming. It's not intended to be used that way. – Silvio Mayolo Mar 18 '22 at 17:55
  • @SilvioMayolo This is a question on specifics of terminology, which in my opinion is well suited to be answered by the standard if such a definition is provided by it. – François Andrieux Mar 18 '22 at 17:58
  • @DrewDormann _`0` is also an object_ It is not – Language Lawyer Mar 18 '22 at 18:00
  • @Anya _"It means that people's answer should not include words like "IMO" or "IMHO"."_ it doesn't. It means you need to cite a specific standard section, provide the behavior of specific c++ compiler implementations, conflicting with these (established) standards. But that's just my HO. – πάντα ῥεῖ Mar 18 '22 at 18:00
  • Another funny question which points us to the pretty well defined language which is easy to understand, to handle and to describe... :-) For me it feels in the last weeks we have seen some of such type of questions which results more or less in "we can't really give a good answer" because the standard is not so well defined as someone would believe. If we really can't answer such a question, it may end in a DR :-) – Klaus Mar 18 '22 at 18:01
  • @LanguageLawyer 0 is an integer literal and not an object. Integer literals have no address while objects do. – Goswin von Brederlow Mar 19 '22 at 01:33

4 Answers4

4

Difference between an object and a variable in C++

Variable is a programming language level concept. A variable has a type and it (usually) has a name. A variable can denote an object, or a reference.

There's no concise definition for the meaning of "variable" in the standard nor a section dedicated to them alone, but closest individual rule to specifying its meaning is:

[basic.pre]

A variable is introduced by the declaration of a reference other than a non-static data member or of an object. The variable's name, if any, denotes the reference or object.


Object is a concept in the level of the abstract machine that the language defines. It is mostly specified in the section "Object model [intro.object]" which begins:

[intro.object]

The constructs in a C++ program create, destroy, refer to, access, and manipulate objects. An object is created by a definition, by a new-expression ([expr.new]), by an operation that implicitly creates objects (see below), when implicitly changing the active member of a union, or when a temporary object is created ([conv.rval], [class.temporary]). 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]).


 int i = 0; //i is an object of type int. Or we can say i is a variable of type int

i is a variable of type int. The variable's name denotes an object.

int &refI = i; //refI is a "reference variable" of "reference type `int&`. But here refI is not an object. 

refI is a variable of type int&. The variable's name denotes a reference. The reference is bound to the object named by i and can be seen as another name for the same object.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Seems odd to me that nameless objects can be considered variables. I had the impression that a variable had to be referred to by name. But I guess the standard is the standard. – François Andrieux Mar 18 '22 at 18:04
  • @FrançoisAndrieux Specifically, look up anonymous union. – eerorika Mar 18 '22 at 18:08
  • _A variable can denote an object, or a reference._ Where the last part is useful/noticeable? From name lookup POV, name (id-expression) denotes a variable. From expression evaluation POV, it is an lvalue denoting an object. – Language Lawyer Mar 18 '22 at 18:24
  • _Unnamed variables can only be member variables_ What is member variable? A static data member? I don't think they can be unnamed. @FrançoisAndrieux _I had the impression that a variable had to be referred to by name_ Don't give a function- or a `catch`-clause parameter a name (`void f(int) { … }` or `catch (int) { … }`) — it will be an unnamed variable. – Language Lawyer Mar 18 '22 at 18:26
  • @LanguageLawyer `A static data member? I don't think they can be unnamed.` No, but non-static data members are also member variables, and they can be unnamed (in the specific case of anonymous union). But indeed, unnamed parameters are another example of such variables. – eerorika Mar 18 '22 at 18:31
  • @eerorika _non-static data members are also member variables_ Ehm... no. At least, this is the intent. – Language Lawyer Mar 18 '22 at 19:29
  • @LanguageLawyer Based on a quick search, it appears that the standard itself doesn't seem to define such thing as "member variable" at all. There's at least one indirect mention contrasting with non-member variables. *"... ordinary (non-member) variables ..."* that suggests the existence of member variables. Outside of the standard, I've seen "member variable" sometimes used interchangeably with "data member", but also used to mean "non-static data member" specifically in which case "static data member" would sometimes be called "class variable". Do you have a source that contradicts? – eerorika Mar 18 '22 at 19:44
  • @eerorika Will it be correct to say that: *"all variables are necessarily objects but not all objects are necessarily variables"* . I have also added this question at the end of my edited question to clarify the discussion even more. – Jason Mar 19 '22 at 05:12
2

Your understanding seems to be correct. I'm going to reuse the quote from @RichardCritten answer, but with a different explanation.


[basic.pre]/6

A variable is introduced by the declaration of a reference other than a non-static data member or of an object. The variable's name, if any, denotes the reference or object.

So a variable is one of:

  • A named object, e.g. int i = 1;. Non-static data members don't count. Functions don't count, since they're not objects, see below. Named objects are always created by declarations.
  • An unnamed object that has a declaration. The only ones I'm aware of are unnamed function parameters (and structured bindings, see below).
  • A named reference, e.g. int &j = i;. Non-static data members don't count. Named references are always created by declarations.
  • An unnamed reference that has a declaration. The only ones I'm aware of are unnamed function parameters (and structured bindings, see below). As far as I'm aware, there are no unnamed references without declarations, since expressions can't have reference types.
  • A structured binding: there's a single unnamed object or reference per structured binding (regardless of the number of identifiers), AND, if this structured binding was initialized with a std::tuple-like class (as opposed to an array or a class with magically detected members), there's also one reference per each member (unnamed, surprisingly - the identifiers magically refer to those references, they are not their names).

[intro.object]

The constructs in a C++ program create, destroy, refer to, access, and manipulate objects. An object is created by a definition, by a new-expression, by an operation that implicitly creates objects (see below), when implicitly changing the active member of a union, or when a temporary object is created. An object occupies a region of storage in its period of construction, throughout its lifetime, and in its period of destruction.

[Note 1: A function is not an object, regardless of whether or not it occupies storage in the way that objects do. — end note]

The properties of an object are determined when the object is created. An object can have a name. An object has a storage duration which influences its lifetime. An object has a type.

The above explains what counts as an object.

But I find it easier to remember what isn't one:

  • Functions are not objects. (see quote above)
  • References are not objects. (again, note that expressions can't have reference types; there are no temporary unnamed references)
  • Prvalues are not objects (since C++17).
  • If the "object" doesn't exist, it isn't an object (i.e. if its lifetime hasn't started or has already ended, AND its constructor nor destructor are currently running).
  • Obviously, labels are not objects, and neither are macros.
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
  • It isn't clear to me why data members aren't variables according to that definition. They are declarations, are they not considered objects? I guess that makes sense, a pointer-to-data-member doesn't point to an object, it points to a member. But I think reasoning should be elaborated upon to help complete the answer. – François Andrieux Mar 18 '22 at 18:21
  • 1
    @FrançoisAndrieux, data members are definitely objects. They occupy storage, have lifetimes etc. And you can also get a regular pointer to a data member. – Fatih BAKIR Mar 18 '22 at 18:25
  • @FrançoisAndrieux They're not variables because the standard explicitly says so (in the first quote). They are objects though. I guess the intent was that variables can't be nested. – HolyBlackCat Mar 18 '22 at 18:26
  • @HolyBlackCat My reading of that passage is that part only applies to references, the restriction is before the "or". "A variable is introduced by the declaration (of a reference other than a non-static data member) or (of an object)." – François Andrieux Mar 18 '22 at 18:34
  • @FatihBAKIR Both interpretations can be argued depending on context. Data members are objects when you talk about a data member of a instance. In the context of a class definition it is just a declaration. – François Andrieux Mar 18 '22 at 18:36
  • @HolyBlackCat Regarding the second point in your answer. Take the following code example: `struct Name {}; int main() { int{};//is this a variable or an object Name();//is this also a variable? or just an object }` . In your 2nd point you said that *"The only ones I'm aware of are unnamed function parameters (and structured bindings,"*. But in my [demo](https://onlinegdb.com/ChL1tmCwh) the statement `int{};` and `Name();` also creates unnamed objects so according to your 2nd point these should be variables as well? Are these variables or just objects. – Jason Mar 19 '22 at 04:46
  • @Anya Those are not declarations, so the second point doesn't apply. Those are just objects, not variables. – HolyBlackCat Mar 19 '22 at 05:29
1

Ignoring the language-lawyer tag since you are just learning. You don't need to know the exact wording of the standard to be able to understand the example you gave.

int i = 0; //i is an object of type int. Or we can say i is a variable of type int
int &refI = i; //refI is a "reference variable" of "reference type `int&`. But here refI is not an object. 

Both i and refI are variables. Anything you give a name is a variable.

But both i and refI are also objects. Every variable has an address in memory where it lives and that makes it an object. There are objects that are not variables, for example the C string literal "Hello, world!". The string is placed somewhere in memory and has an address, it is an object. But it has no name so it isn't a variable.

Note: If nothing uses the address of an object the compiler may, and often will, optimize. Often the data is only kept in CPU registers and never actually stored in memory.

So to summarize: All variables are objects but not all objects are variables.

Goswin von Brederlow
  • 11,875
  • 2
  • 24
  • 42
0

Current Draft Standard basic.pre.6 "A variable is introduced by the declaration of a reference other than a non-static data member or of an object. The variable's name, if any, denotes the reference or object."

Richard Critten
  • 2,138
  • 3
  • 13
  • 16
  • @HolyBlackCat agree with your thinking but that's what the standard says _"...or of an object..."_ for the moment I can't refute it. Will remove my last para. – Richard Critten Mar 18 '22 at 17:54
  • I believe a variable requires an object declaration, so objects which are not declared wouldn't be variables. And static references can be variable, just non-static data member ones aren't. Edit : my reading is "the declaration (of a reference [...]) or (of an object). where "the declaration" is associated with both cases. – François Andrieux Mar 18 '22 at 17:54
  • 1
    And let's not forget *temporary* objects, which don't have variable declarations. – Remy Lebeau Mar 18 '22 at 18:10