The standard says
A variable is introduced by the declaration of an object. The variable's name denotes the object.
But what does this definition actually mean?
Does a variable give a name to an object, i.e. are variables just a naming mechanism for otherwise anonymous objects? Or is a variable the name itself?
Or is a variable a named object in the sense that every variable is also an object?
Or is a variable just a "proxy" with a name that "delegates" all operations to the real object?
To confuse things further, many C++ books seem to treat variables and objects as synonyms.
What is your take on this?
About entities, quoting from the C++0x draft:
An entity is a value, object, reference, function [...]
Every name that denotes an entity is introduced by a declaration.
A variable is introduced by the declaration of an object
From these statements I draw the conclusion that a variable is a name and thus cannot be an object. This is really confusing the hell out of me :)
Variables are named objects. The following create objects that are not variables
new int // create one int object
std::string() // create one string object
The following creates one array variable with name "foo" and 5 unnamed (sub-) objects of type "int"
int foo[5];
The following is not a variable in C++03, but has become a variable in C++0x (declared references are variables in C++0x, for details see the link)
extern int &r;
Does a variable give a name to an object, i.e. are variables just a naming mechanism for otherwise anonymous objects?
Variables are objects (or references respectively). The entity list (3/3 in C++03) of C++ contains multiple such is-a relationships. For instance, a sub-object is-a object and an array element is-a object and a class-member is-a object or function or type or template or enumerator.
The entity list of C++0x looks a bit cleaner to me, and it doesn't contain "variables", "instance of a function" (what that kind of entity even is has never been apparent to me), "sub-object" and "array element" anymore. Instead it added "template specialization" which either are functions, classes or templates (partial specializations).
The C++ object model at 1.8 says
An object can have a name (clause 3).
So if you like, you can formulate the statement as "The object's name denotes the object.".
Variables are names that you give to objects, so yes, objects are, by and large, anonymous.
Here's the definition from the C++17 standard:
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.
My take on this, quite frankly, is that that's not really a definition. It tells us what introduces a variable, but it doesn't define what a variable is.
Consider, for example:
int foo = 42;
This is a declaration of an object, so it "introduces" a variable. But what is the variable? Is the object named foo a variable? I would have thought so, but the definition doesn't actually say that. Apparently the "variable" has a name (in this case "foo") and that name denotes the object. Since it has a name, presumably the name itself is not the variable. And it would have been easy enough to say that the variable is the object, rather than that the variable's name denotes the object, if that were the intent.
What is a "variable" in C++? I really don't know, and I don't believe it's possible to answer the question based on the wording in the standard. (And I'd like that to be corrected in a future edition.)
(The C standard deals with this by not defining "variable" and, for the most part, not using it except as an adjective or informally.)
A variable is simply an entity with a type and a name
As I have learned
What are variables
A variable is an identifier that is bind to a value stored in the system's memory(imperative languages) or an expression that can be evaluated(functional languages).
Why we need variables
provide names for storage chunks to store data temporarily during the lifespan of a computer program.
are also used in programming to transfer information from one part of the program to another part(Eg: parameters, global variables).
A variable is really a name given to an object in memory and hence an object is an anonymous type in that respect just at the point before compilation, when the compilation occurs, the variable is kept track of during the syntactical and parsing phase, then when the linker kicks in, that variable will have a memory address assigned to it, although at run-time, that memory address will be correctly off-setted somewhere to take into account of dynamic linking or static linking. Hence the variable can then be easily referenced aka the memory address that the variable is assigned to.
Really, in a nutshell, the variable is to help the programmer to work out the junction points of execution where that variable is referenced in terms of machine code.
What is your take on this?
Variable is a block of memory on stack or in code segment, or a value in a register (if the size of variable is small enough, although normally it is still value in a memory while registers hold temporary results), with name provided for programmer's convenience. Name of variable does not exist after compilation (we're not talking about macro tricks here). Any access to the variable is resolved into memory access, so technically variable is an address of corresponding data block, and that address isn't stored anywhere. Think about declaration of variables in assembly languages - variable "kinda" exists, but it is still merely an offset to the data block.
I think that this definition is quite clear.
The variable is introduced by declaration and denotes the object. Who introduces the variable? You do of course, and thus it is you who uses it.
A variable is really only a convenience for you the developer. It is a fundamental aspect of most programming languages not just C++. A variable mearly gives a symbolic name to a useable entity that occupies storage, such that it can be referenced and used at a future point in your source code.
For example if you declare a variable in a method as such:
int x = 5;
This will be reduced by the compiler to some offset from the stack pointer, say SP + 0x003.
At some point later you can say:
x = 52;
In this case the area of stack memory SP + 0x003 will contain the bytes that describe the number 52.
You declare the variable to be of a certain type so that the compiler can work out how much space the data occupies in memory.
Without variables, you would have to manage all of the arrangement of information yourself and you would probably be coding in assembly or lower.
Variable is a name for the object. You access the object through this named entity.
Related
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.
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.
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.
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.
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."
Picture of text
To read something, we need somewhere to read into; that is, we need somewhere in the computer's memory to place what we read. We call such a "place" an object. An object is a region of memory with a type that specifies what kind of information can be placed in it. A named object is called a variable. For example, character strings are put into string variables and integers are put into int variables. You can think of an object as a "box" into which you can put a value of the object's type
An object is a region of memory with a type that specifies what kind of information can be placed in it? Here they give an example with ints and strings which are like built in datatypes, I already know some oop so I was kinda confused because like I thought an object was kinda its own separate entity with its own user created datatype? I get that all objects have their own region of memory but they're basically calling a variable of type int, age, with the value 42 an object. Is this correct?
This is the wording from the C++ standard [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]).
There is more to read about objects, I just picked this paragraph from the intro so you can see that the term "object" in C++ is more general than "instance of a user defined class". Note how the last sentence is quite similar with what Bjarne wrote in the book. What you refer to (instance of a class) is called "class object".
A perhaps more readable introduction to objects in C++ can be found here: https://en.cppreference.com/w/cpp/language/object.
PS: I am not a historian, but I suppose that the term "object" was already in wide-spread use before Object Orientation came into existance. There have been objects before. They were not invented by OOP, just put into the focus. Also note that C++ is not a (pure) OOP language, but rather multi-paradigm.
but they're basically calling a variable of type int, age, with the value 42 an object. Is this correct?
They're correct.
I already know some oop
Modern OOP nomenclature is different from nomenclature of C++.
and strings which are like built in datatypes
The std::string type is a class i.e. a "user defined" data type (although it is provided by the standard library).
I've been quite confused about what a closure is in C++. I've read this What is a 'Closure'? but nearly all answers are referring to JavaScript but I think there are some differences about closure between C++ and JavaScript. So I found it difficult to match the JavaScript description of closure to C++.
For example, nearly all answers are taking a function returning a function as an example to demostrate closure in JavaScript. But I don't find the similar pattern in C++.
What's more, in JavaScript there is no such thing called "capture list".
I was told that if a function uses non-local variables (from outer scope or global scope), then it's a closure. Is it correct?
Example 1:
int a = 3;
int am_I_a_closure(int c){
return c + a;
}
int main(){
}
Why capture list is required? Can't lambda in C++ just work like JavaScript nested functions?
Or in another way of speaking, can't lambda in C++ just work like the same way as global function accessing global(non-local) variables?
I mean, through normal name look-up proccess, if a name is not found in the current scope, then find it in the outer scoper, then more outer scoper...
Why capture list is needed? Why need to capture outer scope variables? Can't that be done through normal name look-up?
Example 2:
int main(){
int a = 3;
{
int b = 5;
{
int c = 4;
{
std::cout << a+b+c <<std::endl;
}
}
}
}
Example 3:
int main(){
std::vector<int> values = {1,5,3,4,3};
int a = 3;
std::find_if(values.begin(), values.end(), [](int value) {return value > a; }); //Error, `a` is not captured.
}
Again, in Example 3, why a is need to be captured instead of normal name look-up as in Example 1 and Example 2?
It's important to understand that "closure" is a concept that has a very specific meaning in functional programming. C++ however is not a functional language; it doesn't care all that much about strict adherence to functional programming terminology. It simply defines various functionality, some of which may or may not map well onto that terminology.
JavaScript and C++ are different languages. In JavaScript, a function has a property called being a "first-class object". This means that, when you execute the code to create a "function", you are creating an object that represents that function.A variable containing a function is fundamentally no different from a variable containing a string or a variable containing an array or whatever else. You can overwrite a variable that contains a function with an array, or vice-versa.
In particular, functions as first-class objects can have state associated with them at the point of their creation. If such a function reaches out of its scope to access a local variable, then that scope can be stored as part of the function's state; this state will be accessed automatically when you attempt to use that variable in the function. So it appears that you're reaching "out" of the function's scope, but you're not; the scope was brought "in" with you, and you're just accessing that.
In C++, a function is not a first-class object. You can get a pointer to a function, but function pointers are explicitly distinct from object pointers (casting between the two is not even required to be valid). A function is not "created" or "destroyed" as far as the C++ language is concerned; every function is always there, from the start of the program to its end.
C++ functions can access global variables, but that's because they're global. The location of a global variable is baked into the executable at compile/link time, so no special state needs to be stored with the function in order to access it.
However, C++ does have a useful concept that can help to create the effect of a first-class function object. Namely, a class type can overload the function call operator operator(). This allows an instance of a class to be called as if it were a function. Class instances are objects and can have internal state (aka: member variables), and the operator() overload is just a member function of the type.
Given all of that, you can create something that simulates a properly scoped function object. All you need is a class that has member variables that correspond to the variables outside of the function's scope which it references. These members can be initialized in the class's constructor by passing the external values to the constructor. Then you have a valid object which you can call, and it can access those "external" variables by using its member variables.
This is all a C++ lambda is. It wraps all of this up in "nice, neat" syntax. It writes a class for you; it writes the member variables you "capture" from the external world for you, and it calls the constructor and passes those variables for you.
However, C++ is a language that tries hard not to make something more expensive than you need it to be. The more external variables you use, the more internal member variables the lambda will need, and thus the bigger the class will be and the longer it will take to initialize/copy/etc. Therefore, if you want to use some external variable (which is implemented as a member variable), C++ requires you to either explicitly list it (so that you know that you meant to capture it) or to use the default capture mechanisms [=] or [&] (so that you are explicitly giving up your right to complain about accidentally making your lambda type huge and/or slow).
Furthermore, in JavaScript, everything is a reference. Variables store references to arrays, functions, dictionaries, etc. JavaScript is a reference-based language.
C++ is a value-oriented language. A variable in JavaScript references an object; a variable in C++ is an object. You cannot replace one object with another in C++; you may copy over the value of an object, but it is still that object.
As such, how a lambda ought to capture a particular variable becomes relevant. You can capture variables by value (copying the value into the hidden member) or by reference (referencing the object).
This is of particular importance because C++ is not garbage collected. That means that, just because you have a reference to an object does not mean the object still exists. If you have a variable on the stack, and you get a reference to it, and that reference exists past the point where the stack variable goes out of scope... that reference is now useless. In JavaScript, it'd be fine because of garbage collecting. But C++ doesn't do that. You have a reference to a destroyed object, which cannot be used.
So if you want a lambda to capture local variables and you want the lambda to persist past the point where the variables no longer exist, you will need to capture such variables by value, not by reference.
Capturing by value or by reference is determined by how you list the variable in the list of captures. &x means to capture by reference, while x is a capture by value. The default capture [=] means to capture by value by default, with [&] meaning reference capture by default.
if I have some expression on c++:
const int x = 3;
can I say that x is a variable? It seems very strange cause x is not variable cause I can't change it, thanks in advance for any expanations
Edited
P.S. thanks for all answers, I understood that by definition of C++, answer for my question may be yes, do You know some other languages, in which the answer for my question will be no?
Yes. x is a variable, even though you cannot (legitimately) change its value.
Effectively, in C++, an object that has a name is a "variable."
This is philosophical , it cannot be modifiable, in fact some compiler like GCC stores it in the Text-section.
So or is a non-modifiable variable, or a constant.
In C++ terminology the term variable is almost synonymous with the term object: any declared object is a variable. Whether the object is changeable or not makes no difference. So, within the official terminology yes, x is a variable.
In the ISO language definition for C++ such an object is referred to as a const variable, meaning a read-only variable. In conceptual terms and in natural language semantics it is a nonetheless constant.
I imagine the term is merely used to differentiate a constant object (such as x in your example) from a literal constant, (such as 3), where one is an addressable object, and the other is not. The term const object is not used because an object refers to the instance in memory, while a variable refers a name or identifier associated with an object.
BTW it is useful for a function declaration, for example
void ReadStuff(const int a)
This means that you actually can give the function a non static variable but
it will be treated as a constant (ie. the function will not change it).
The standard says
A variable is introduced by the declaration of an object. The variable's name denotes the object.
But what does this definition actually mean?
Does a variable give a name to an object, i.e. are variables just a naming mechanism for otherwise anonymous objects? Or is a variable the name itself?
Or is a variable a named object in the sense that every variable is also an object?
Or is a variable just a "proxy" with a name that "delegates" all operations to the real object?
To confuse things further, many C++ books seem to treat variables and objects as synonyms.
What is your take on this?
About entities, quoting from the C++0x draft:
An entity is a value, object, reference, function [...]
Every name that denotes an entity is introduced by a declaration.
A variable is introduced by the declaration of an object
From these statements I draw the conclusion that a variable is a name and thus cannot be an object. This is really confusing the hell out of me :)
Variables are named objects. The following create objects that are not variables
new int // create one int object
std::string() // create one string object
The following creates one array variable with name "foo" and 5 unnamed (sub-) objects of type "int"
int foo[5];
The following is not a variable in C++03, but has become a variable in C++0x (declared references are variables in C++0x, for details see the link)
extern int &r;
Does a variable give a name to an object, i.e. are variables just a naming mechanism for otherwise anonymous objects?
Variables are objects (or references respectively). The entity list (3/3 in C++03) of C++ contains multiple such is-a relationships. For instance, a sub-object is-a object and an array element is-a object and a class-member is-a object or function or type or template or enumerator.
The entity list of C++0x looks a bit cleaner to me, and it doesn't contain "variables", "instance of a function" (what that kind of entity even is has never been apparent to me), "sub-object" and "array element" anymore. Instead it added "template specialization" which either are functions, classes or templates (partial specializations).
The C++ object model at 1.8 says
An object can have a name (clause 3).
So if you like, you can formulate the statement as "The object's name denotes the object.".
Variables are names that you give to objects, so yes, objects are, by and large, anonymous.
Here's the definition from the C++17 standard:
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.
My take on this, quite frankly, is that that's not really a definition. It tells us what introduces a variable, but it doesn't define what a variable is.
Consider, for example:
int foo = 42;
This is a declaration of an object, so it "introduces" a variable. But what is the variable? Is the object named foo a variable? I would have thought so, but the definition doesn't actually say that. Apparently the "variable" has a name (in this case "foo") and that name denotes the object. Since it has a name, presumably the name itself is not the variable. And it would have been easy enough to say that the variable is the object, rather than that the variable's name denotes the object, if that were the intent.
What is a "variable" in C++? I really don't know, and I don't believe it's possible to answer the question based on the wording in the standard. (And I'd like that to be corrected in a future edition.)
(The C standard deals with this by not defining "variable" and, for the most part, not using it except as an adjective or informally.)
A variable is simply an entity with a type and a name
As I have learned
What are variables
A variable is an identifier that is bind to a value stored in the system's memory(imperative languages) or an expression that can be evaluated(functional languages).
Why we need variables
provide names for storage chunks to store data temporarily during the lifespan of a computer program.
are also used in programming to transfer information from one part of the program to another part(Eg: parameters, global variables).
A variable is really a name given to an object in memory and hence an object is an anonymous type in that respect just at the point before compilation, when the compilation occurs, the variable is kept track of during the syntactical and parsing phase, then when the linker kicks in, that variable will have a memory address assigned to it, although at run-time, that memory address will be correctly off-setted somewhere to take into account of dynamic linking or static linking. Hence the variable can then be easily referenced aka the memory address that the variable is assigned to.
Really, in a nutshell, the variable is to help the programmer to work out the junction points of execution where that variable is referenced in terms of machine code.
What is your take on this?
Variable is a block of memory on stack or in code segment, or a value in a register (if the size of variable is small enough, although normally it is still value in a memory while registers hold temporary results), with name provided for programmer's convenience. Name of variable does not exist after compilation (we're not talking about macro tricks here). Any access to the variable is resolved into memory access, so technically variable is an address of corresponding data block, and that address isn't stored anywhere. Think about declaration of variables in assembly languages - variable "kinda" exists, but it is still merely an offset to the data block.
I think that this definition is quite clear.
The variable is introduced by declaration and denotes the object. Who introduces the variable? You do of course, and thus it is you who uses it.
A variable is really only a convenience for you the developer. It is a fundamental aspect of most programming languages not just C++. A variable mearly gives a symbolic name to a useable entity that occupies storage, such that it can be referenced and used at a future point in your source code.
For example if you declare a variable in a method as such:
int x = 5;
This will be reduced by the compiler to some offset from the stack pointer, say SP + 0x003.
At some point later you can say:
x = 52;
In this case the area of stack memory SP + 0x003 will contain the bytes that describe the number 52.
You declare the variable to be of a certain type so that the compiler can work out how much space the data occupies in memory.
Without variables, you would have to manage all of the arrangement of information yourself and you would probably be coding in assembly or lower.
Variable is a name for the object. You access the object through this named entity.