This question already has answers here:
How does the Comma Operator work
(9 answers)
Closed 9 years ago.
I simply have the line as follows:
int player = 1, i, choice;
My question is, what is assigned to i and what is assigned to choice? I was always taught that a variable could not be assigned to multiple values.
That code is equivalent to saying
int player = 1;
int i;
int choice;
You are not assigning 1, i, and choice into the integer variable player.
Nothing is assigned anywhere in this -- it's doing initialization not assignment.
player is obviously initialized to 1.
If this definition is at namespace scope so i and choice have static storage duration, then they will be zero-initialized.
If this definition is local to a function, i and choice will be default-initialized, which (in the case of int) means they aren't given a predictable value.
If this definition is inside a class, then i and choice can be initialized by a constructor. A constructor generated by the compiler will default-initialize them.
They (i and choice) have unspecified values. They can be pretty much any value, really. Unless you explicitly set them to a value, they are given some "junk" value (typically whatever is already in that memory location that they've been assigned).
You're not assigning to player multiple times. You're creating 3 variables, and assigned 1 to player. It's the same as if you had written:
int player = 1;
int i;
int choice;
Think of this as:
int player = 1;
int i;
int choice;
In c++ you are allowed to declare multiple of the same data type on the same line, like
char c1, c2, c3;
and it is also accepted to give one of these a value in their declaration, like what your line is doing. So as simonc said, there will be no value in i or choice.
What you have there is definition & initialization, definition, definition;
int player = 1;
int i;// = most probably 'random' trash from heap/stack memory
int choice;// = most probably 'random' trash from heap/stack memory
i and choice aren't defined. What happens is, you are saying:
I want to declare player as int and asign 1 to it then a sequens interupt sign(,), says the type specifier has reference to the next sequenz. Means also to declare i and choice as int (but without asigning anythign)
Related
I was recently reviewing some code and I came across something that I was confused about. Say I have a functions, int getNewNumber(int num, int dir), implemented like this:
int getNewNumber(int num, int dir) {
int newNum = num;
if(dir == 1) {
newNum++;
} else {
newNum--;
}
return newNum;
}
Now, when calling the function, I have something like this:
int number = getNewNumber(number, 1);
Is it initialized to 0 before being passed into newNum? I'm confused about how you can use the variable as an argument when it's being initialized.
Is it initialized to 0 before being passed into newNum?
Maybe. It depends on context. If the variable is a global static, then it is zero initialized before dynamic initialization.
If it is an automatic variable, then the value passed into getNewNumber is indeterminate and using that value has undefined behaviour. A decent compiler will warn you.
I'm confused about how you can use the variable as an argument when it's being initialized.
If the variable wasn't initialized statically, then you can't use its value in its own initialization in a way that would have defined behaviour.
If the variable was zero initialized before dynamic initialization, then you can use the value, but you might as well use literal zero, and that would be clearer to the reader of the program. I don't think there is any useful way to use the value of a variable in its own initialization.
I really think it depends on the compiler. In general I'd call it unsafe - in the best case you'll get a a value, that has the same type, or can be converted to this type. In the worst case - the program will simply crash.
This question already has answers here:
What do the following phrases mean in C++: zero-, default- and value-initialization?
(2 answers)
Closed 6 years ago.
Question1:
struct S
{
size_t size;
int j;
int k;
int l;
};
S s={sizeof(S)};
Doest C++ standard say,the above {} will initialize "j,k,l" to 0?
Seems it will do, is it part of cpp standard?
Question2:
int main()
{
int* pi=new int[5];
for(int i=0;i<5;++i)
cout<<pi[i]<<',';
return 0;
}
Here the elements in pointer to array(pi) are not initialized, my running result may look like
6785200,6782912,0,0,0,
But if I change it to
int main()
{
int* pi=new int[5]();//use ()
for(int i=0;i<5;++i)
cout<<pi[i]<<',';
return 0;
}
Then, all pi elements are "0". Seems "()" will give elements a "0" value. Is this part of cpp standard?
I also tried to give another value using "()" like this:
int* pi=new int[5](7);
But it fails compilation. How could I give initialization values to an pointer to array with all elements having same value?
Question 1
Yes, it is guarantied by aggregate initialization
in particular:
If the number of initializer clauses is less than the number of members [and bases (since C++17)] or initializer list is completely empty, the remaining members [and bases (since C++17)] are initialized [by their default initializers, if provided in the class definition, and otherwise (since C++14)] by empty lists, which performs value-initialization. If a member of a reference type is one of these remaining members, the program is ill-formed (references cannot be value-initialized).
.
Question 2
Use std::vector:
std::vector<int> pi(5, 7);
There is a perfect answer to question 1 already, I will answer question 2.
Yes, your observation is correct. Adding () after the new turns default initialization of the elements into value initialization. The first form does nothing with created objects (so you observe random numbers), but the value initialization will initialize members - and in this case, will set elements to 0. Unfortunately, there is no way to perform a specific initialization for dynamic int arrays - you can either leave them uninititalized or value-initialize them (to 0).
Using std::vector solves this problem.
I've only recently started learning C++ as part of my 10th Grade syllabus, and am only aware of the basics, thus simple answers (if possible) will be appreciated.
I'm rather confused between initialization and assignment.
//Case 1
int a=5; //This is initialization
a=6; //This is assignment
From what I've understood, a variable is initialized when you give it a value to hold while declaring it. Changing this later in the code will be an assignment. Right?
What about :
//Case 2
int b;
{
//Block of code which does not call variable b
.
.
.
//End of block
}
b=6; // Is this initialization as well?
While 'b' is uninitialized when we declare, we later assign the value '6'. Can we say the 'b' is initialized now? Or are the terms initialized and uninitialized not applicable to 'b' anymore?
I read the an uninitialized variable holds "garbage values" till it isn't initialized. What exactly are "garbage values"?
What is the difference between the following initializers : '()', '{}', and '='?
Okay, once you declare a variable without assigning any value, like
int b;
that means that the compiler reserves some space in the memory to hold the value (to be exact, in this case the memory is reserved on the stack). But since you didn't assign any value to the variable, it still holds the value, that the assigned space in memory had before. And that can be anything. Those are garbage values.
Initializers:
int b(1);
assigns the value 1 to be (in general, it calls a constructor of the type)
The brackets can be used to initialize arrays like this (edit):
int b[] = {1, 3, 5, 7};
And the = just assigns a value. The difference between this and the first will only become interesting when dealing with more complex types (classes), where you have constructors
Easilly spoken:
Uninitialize variable:
int a;
You are declare a variable that means you allocate memory but dont assign a value to it. So its compiler dependend if the value is set to 0 or not. So there could be anything in. Thats waht you called garbage values.
Initialized variable:
int a = 0;
You are declare a variable that means you allocate memory and assigne a value to it.
Assigne Values:
a = 10;
You assigne a rvalue (in this case 10) to a lvalue ( a). So you dont allocate new memory.
You're basically right.
Some older texts call the first assignment to an uninitialised variable an "initialisation", although this is not strictly accurate.
"Garbage values" are arbitrary values. They could look meaningful or could be totally random.
Initialization serves to initialize an uninitialized value.
It can be done my means of copy constructor, i.e. int a = 1; or int a(1);, it can be done by means of assignment, i.e. int a; a = 1;, it can be done via a function, i.e. int a; init(a);. Initialization is not a "language thing", it is just the act of specifying an unspecified value.
A "garbage value" is an arbitrary value. Some storage will be given to the uninitialized object, and attempting to read it will produce a value of whatever happened to be in that memory.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Do all "real" C++ compilers don't have default initialization with zeros of built-in types? I'm asking 'cos I've found on-line compilers that is claimed to be gcc, and it does zero initialization of built-in types
int h=6548;
for (int i; i < 10; ++i) {
cout<<i<<"\n";
}
for this code its output is
0
1
2
3
4
5
6
7
8
9
What initialization. In your example, accessing i is
undefined behavior, since it wasn't initialized. Some compilers
do initialize it, at least in debug mode, but generally with
something like 0xDEADBEEF or 0xCCCCCCCC, so that you can
easily recognize in a debugger that you're accessing
uninitialized memory (and so that the program is likely to crash
if you use it as a pointer), but this is not required.
The only time built-in types are implicitly initialized is when
they have static storage duration: variables defined at
namespace scope (include static class members), or local
variables which have been declared static.
You don't show the context of your code, but if it is directly
in main, or in the first function called from main, int i
will be the first use of this actual memory. And the OS
probably will have set it to 0, for security reasons. You might
want to try something like:
void scribble()
{
int x = 0x12345678;
}
void testit()
{
for ( int i; i < 10; ++ i ) {
std::cout << i << '\n';
}
}
int
main()
{
scribble();
testit();
return 0;
}
The call to std::operator<<( std::ostream&, char const* ) is
might have left something different from 0 in this
particular memory cell. (Or the compiler has optimized it out.
Try this with all optimization turned off.) Neither g++ nor
VC++ initialize the i in testit.
Whether or not the values are initialized is undefined behaviour and implementation dependant. You must not rely on that.
1. C++11, 8.5/11
If no initializer is specified for an object, the object is default-initialized; if no initialization is performed, an object with automatic or dynamic storage duration has indeterminate value. [ Note: Objects with static or thread storage duration are zero-initialized, see 3.6.2. —end note ]
If you use int i; this results in an uninitialized integer which has "indeterminate value"! You can't predict what will happen if you access it's value.
2. C++11, 8.5/10
An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
If you use int i = int(); you have a value-initialized i. Now, what is value-initialized?
3. C++11, 8.5/7
To value-initialize an object of type T means:
[...] (some options where T may be class or array type)
otherwise, the object is zero-initialized.
Ok now we know that int i = int(); means having i=0.
Be aware of the following:
Note: Since () is not permitted by the syntax for initializer,
X a();
is not the declaration of a value-initialized object of class X, but the declaration of a function taking no argument and returning an X.
Emphasis on standard quotes are mine.
Both the C and C++ standards are VERY clear that there is only one kind of memory that is initialize, and that is the memory for static storage.
Variable with static storage duration are guaranteed to be zero (that aren't initialized or have a constructor). Everything else is "uninitialized", which means "you don't know what it will be" - and one of the options is of course that it is zero.
All other variables are almost guaranteed to not be zero, at least under some circumstances - and it may well be that you can't find those circumstances with a simple test program.
For example, malloc (or new) memory is often zero for "virgin" memory, but fill it with something, then free it and use it again, and it's no longer zero.
Variables on the stack almost inevitably will have different values depending on what the previous call was (and thus, what stuff got put on the stack in the previous function that the code visited).
NO one compiler initialize with zero. I can say that somehow you were lucky.
Try this in online compiler you gave.
for(int i;i < 10; ++i)
{
int a;
cout << a << endl;
a = 1;
}
And you will see that first time a is equal 0 and next 9 times it's equal 1.
It may depend on compilers to compilers, but it is better to make initialization a habit because you may not know which old compiler you may end up with and you may get screwed up by using the uninitialized garbage values....
Another compiler is http://codepad.org/ which also initializes on its part..
I generally see examples of initialisation vs assignment like this:
int funct1(void)
{int a = 5; /*initialization*/
a = 6;} /*assignment*/
Obviously something left as garbage or undefined somehow is uninitialized.
But could some one please define if initialization is reserved for definition statements and/or whether assignments can be called initialisation?
int funct2(void)
{int b;
b = 5;} /*assignment, initialization or both??*/
Is there much of a technical reason why we can't say int b is initialised to garbage (from the compilers point of view)?
Also if possible could this be compared with initializing and assinging on non-primitive data types.
I'll resurrect this thread to add an important point of view, since the puzzlement about terminology by the OP is understandable. As #OliCharlesworth pointed out (and he's perfectly right about that) as far as the C language standard is concerned initialization and assignment are two completely different things. For example (assuming local scope):
int n = 1; // definition, declaration and **initialization**
int k; // just definition + declaration, but no initialization
n = 12; // assignment of a previously initialized variable
k = 42; // assignment of a previously UNinitialized variable
The problem is that many books that teach programming aren't so picky about terminology, so they call "initialization" any "operation" that gives a variable its first meaningful value. So, in the example above, n = 12 wouldn't be an initialization, whereas k = 42 would. Of course this terminology is vague, imprecise and may be misleading (although it is used too often, especially by teachers when introducing programming to newbies). As a simple example of such an ambiguity let's recast the previous example taking global scope into account:
// global scope
int n = 1; // definition, declaration and **initialization**
int k; // definition, declaration and **implicit initialization to 0**
int main(void)
{
n = 12; // assignment of a previously initialized variable
k = 42; // assignment of a previously initialized variable
// ... other code ...
}
What would you say about the assignments in main? The first is clearly only an assignment, but is it the second an initialization, according to the vague, generic terminology? Is the default value 0 given to k its first "meaningful" value or not?
Moreover a variable is commonly said to be uninitialized if no initialization or assignment has been applied to it. Given:
int x;
x = 42;
one would commonly say that x is uninitialized before the assignment, but not after it. The terms assignment and initializer are defined syntactically, but terms like "initialization" and "uninitialized" are often used to refer to the semantics (in somewhat informal usage). [Thanks to Keith Thompson for this last paragraph].
I dislike this vague terminology, but one should be aware that it is used and, alas, not too rare.
As far as the language standard is concerned, only statements of the form int a = 5; are initialisation. Everything of the form b = 5; is an assignment.
The same is true of non-primitive types.
And to "Is there much of a technical reason why we can't say int b is initialised to garbage", well, if you don't put any value into a memory location, it's not "initialisation". From the compiler's point of view, no machine language instruction is generated to write to the location, so nothing happens.