Confusion about array initialization in C
Clash Royale CLAN TAG#URR8PPP
up vote
87
down vote
favorite
In C language, if initialize an array like this:
int a[5] = 1,2;
then all the elements of the array that are not initialized explicitly will be initialized implicitly with zeroes.
But, if I initialize an array like this:
int a[5]=a[2]=1;
printf("%d %d %d %d %dn", a[0], a[1],a[2], a[3], a[4]);
output:
1 0 1 0 0
I don't understand, why does a[0]
print 1
instead of 0
? Is it undefined behaviour?
Note: This question was asked in an interview.
c arrays initialization language-lawyer
 |Â
show 11 more comments
up vote
87
down vote
favorite
In C language, if initialize an array like this:
int a[5] = 1,2;
then all the elements of the array that are not initialized explicitly will be initialized implicitly with zeroes.
But, if I initialize an array like this:
int a[5]=a[2]=1;
printf("%d %d %d %d %dn", a[0], a[1],a[2], a[3], a[4]);
output:
1 0 1 0 0
I don't understand, why does a[0]
print 1
instead of 0
? Is it undefined behaviour?
Note: This question was asked in an interview.
c arrays initialization language-lawyer
31
The expressiona[2]=1
evaluates to1
.
â tkausl
Sep 13 at 6:01
14
A very deep question. I wonder if the interviewer knows the answer themselves. I don't. Indeed ostensibly the value of the expressiona[2] = 1
is1
, but I'm not sure if you are are allowed to take the result of a designated initialiser expression as the value of the first element. The fact you've added the lawyer tag means I think we need an answer citing the standard.
â Bathsheba
Sep 13 at 6:59
15
Well if that's their favourite question, you may well have dodged a bullet. Personally I prefer a written programming exercise (with access to a compiler and debugger) to be taken over a few hours rather than "ace" style questions such as the above. I could conject an answer, but I don't think it would have any real factual basis.
â Bathsheba
Sep 13 at 7:04
1
@Bathsheba I would do the opposite, as the answer here now answers both questions.
â Kami Kaze
Sep 13 at 7:36
1
@Bathsheba would be the best. Still I would give the credit for the question to OP, as he came up with the topic. But this is not for me to decide just what I feel would be "the right thing".
â Kami Kaze
Sep 13 at 7:39
 |Â
show 11 more comments
up vote
87
down vote
favorite
up vote
87
down vote
favorite
In C language, if initialize an array like this:
int a[5] = 1,2;
then all the elements of the array that are not initialized explicitly will be initialized implicitly with zeroes.
But, if I initialize an array like this:
int a[5]=a[2]=1;
printf("%d %d %d %d %dn", a[0], a[1],a[2], a[3], a[4]);
output:
1 0 1 0 0
I don't understand, why does a[0]
print 1
instead of 0
? Is it undefined behaviour?
Note: This question was asked in an interview.
c arrays initialization language-lawyer
In C language, if initialize an array like this:
int a[5] = 1,2;
then all the elements of the array that are not initialized explicitly will be initialized implicitly with zeroes.
But, if I initialize an array like this:
int a[5]=a[2]=1;
printf("%d %d %d %d %dn", a[0], a[1],a[2], a[3], a[4]);
output:
1 0 1 0 0
I don't understand, why does a[0]
print 1
instead of 0
? Is it undefined behaviour?
Note: This question was asked in an interview.
c arrays initialization language-lawyer
c arrays initialization language-lawyer
edited Sep 13 at 14:28
Jesse de Bruijne
2,29631125
2,29631125
asked Sep 13 at 5:58
rsp
17.5k455115
17.5k455115
31
The expressiona[2]=1
evaluates to1
.
â tkausl
Sep 13 at 6:01
14
A very deep question. I wonder if the interviewer knows the answer themselves. I don't. Indeed ostensibly the value of the expressiona[2] = 1
is1
, but I'm not sure if you are are allowed to take the result of a designated initialiser expression as the value of the first element. The fact you've added the lawyer tag means I think we need an answer citing the standard.
â Bathsheba
Sep 13 at 6:59
15
Well if that's their favourite question, you may well have dodged a bullet. Personally I prefer a written programming exercise (with access to a compiler and debugger) to be taken over a few hours rather than "ace" style questions such as the above. I could conject an answer, but I don't think it would have any real factual basis.
â Bathsheba
Sep 13 at 7:04
1
@Bathsheba I would do the opposite, as the answer here now answers both questions.
â Kami Kaze
Sep 13 at 7:36
1
@Bathsheba would be the best. Still I would give the credit for the question to OP, as he came up with the topic. But this is not for me to decide just what I feel would be "the right thing".
â Kami Kaze
Sep 13 at 7:39
 |Â
show 11 more comments
31
The expressiona[2]=1
evaluates to1
.
â tkausl
Sep 13 at 6:01
14
A very deep question. I wonder if the interviewer knows the answer themselves. I don't. Indeed ostensibly the value of the expressiona[2] = 1
is1
, but I'm not sure if you are are allowed to take the result of a designated initialiser expression as the value of the first element. The fact you've added the lawyer tag means I think we need an answer citing the standard.
â Bathsheba
Sep 13 at 6:59
15
Well if that's their favourite question, you may well have dodged a bullet. Personally I prefer a written programming exercise (with access to a compiler and debugger) to be taken over a few hours rather than "ace" style questions such as the above. I could conject an answer, but I don't think it would have any real factual basis.
â Bathsheba
Sep 13 at 7:04
1
@Bathsheba I would do the opposite, as the answer here now answers both questions.
â Kami Kaze
Sep 13 at 7:36
1
@Bathsheba would be the best. Still I would give the credit for the question to OP, as he came up with the topic. But this is not for me to decide just what I feel would be "the right thing".
â Kami Kaze
Sep 13 at 7:39
31
31
The expression
a[2]=1
evaluates to 1
.â tkausl
Sep 13 at 6:01
The expression
a[2]=1
evaluates to 1
.â tkausl
Sep 13 at 6:01
14
14
A very deep question. I wonder if the interviewer knows the answer themselves. I don't. Indeed ostensibly the value of the expression
a[2] = 1
is 1
, but I'm not sure if you are are allowed to take the result of a designated initialiser expression as the value of the first element. The fact you've added the lawyer tag means I think we need an answer citing the standard.â Bathsheba
Sep 13 at 6:59
A very deep question. I wonder if the interviewer knows the answer themselves. I don't. Indeed ostensibly the value of the expression
a[2] = 1
is 1
, but I'm not sure if you are are allowed to take the result of a designated initialiser expression as the value of the first element. The fact you've added the lawyer tag means I think we need an answer citing the standard.â Bathsheba
Sep 13 at 6:59
15
15
Well if that's their favourite question, you may well have dodged a bullet. Personally I prefer a written programming exercise (with access to a compiler and debugger) to be taken over a few hours rather than "ace" style questions such as the above. I could conject an answer, but I don't think it would have any real factual basis.
â Bathsheba
Sep 13 at 7:04
Well if that's their favourite question, you may well have dodged a bullet. Personally I prefer a written programming exercise (with access to a compiler and debugger) to be taken over a few hours rather than "ace" style questions such as the above. I could conject an answer, but I don't think it would have any real factual basis.
â Bathsheba
Sep 13 at 7:04
1
1
@Bathsheba I would do the opposite, as the answer here now answers both questions.
â Kami Kaze
Sep 13 at 7:36
@Bathsheba I would do the opposite, as the answer here now answers both questions.
â Kami Kaze
Sep 13 at 7:36
1
1
@Bathsheba would be the best. Still I would give the credit for the question to OP, as he came up with the topic. But this is not for me to decide just what I feel would be "the right thing".
â Kami Kaze
Sep 13 at 7:39
@Bathsheba would be the best. Still I would give the credit for the question to OP, as he came up with the topic. But this is not for me to decide just what I feel would be "the right thing".
â Kami Kaze
Sep 13 at 7:39
 |Â
show 11 more comments
7 Answers
7
active
oldest
votes
up vote
85
down vote
accepted
TL;DR: I don't think the behavior of int a[5]=a[2]=1;
is well defined, at least in C99.
The funny part is that the only bit that makes sense to me is the part you're asking about: a[0]
is set to 1
because the assignment operator returns the value that was assigned. It's everything else that's unclear.
If the code had been int a[5] = [2] = 1
, everything would've been easy: That's a designated initializer setting a[2]
to 1
and everything else to 0
. But with a[2] = 1
we have a non-designated initializer containing an assignment expression, and we fall down a rabbit hole.
Here's what I've found so far:
a
must be a local variable.
6.7.8 Initialization
- All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.
a[2] = 1
is not a constant expression, soa
must have automatic storage.a
is in scope in its own initialization.
6.2.1 Scopes of identifiers
- Structure, union, and enumeration tags have scope that begins just after the appearance of
the tag in a type specifier that declares the tag. Each enumeration constant has scope that
begins just after the appearance of its defining enumerator in an enumerator list. Any
other identifier has scope that begins just after the completion of its declarator.
The declarator is
a[5]
, so variables are in scope in their own initialization.- Structure, union, and enumeration tags have scope that begins just after the appearance of
a
is alive in its own initialization.
6.2.4 Storage durations of objects
An object whose identifier is declared with no linkage and without the storage-class
specifierstatic
has automatic storage duration.For such an object that does not have a variable length array type, its lifetime extends
from entry into the block with which it is associated until execution of that block ends in
any way. (Entering an enclosed block or calling a function suspends, but does not end,
execution of the current block.) If the block is entered recursively, a new instance of the
object is created each time. The initial value of the object is indeterminate. If an
initialization is specified for the object, it is performed each time the declaration is
reached in the execution of the block; otherwise, the value becomes indeterminate each
time the declaration is reached.
There is a sequence point after
a[2]=1
.
6.8 Statements and blocks
- A full expression is an expression that is not part of another expression or of a declarator.
Each of the following is a full expression: an initializer; the expression in an expression
statement; the controlling expression of a selection statement (if
orswitch
); the
controlling expression of awhile
ordo
statement; each of the (optional) expressions of
afor
statement; the (optional) expression in areturn
statement. The end of a full
expression is a sequence point.
Note that e.g. in
int foo = 1, 2, 3
the1, 2, 3
part is a brace-enclosed list of initializers, each of which has a sequence point after it.- A full expression is an expression that is not part of another expression or of a declarator.
Initialization is performed in initializer list order.
6.7.8 Initialization
- Each brace-enclosed initializer list has an associated current object. When no
designations are present, subobjects of the current object are initialized in order according
to the type of the current object: array elements in increasing subscript order, structure members in declaration order, and the first named member of a union. [...]
Â
- The initialization shall occur in initializer list order, each initializer provided for a
particular subobject overriding any previously listed initializer for the same subobject; all
subobjects that are not initialized explicitly shall be initialized implicitly the same as
objects that have static storage duration.
- Each brace-enclosed initializer list has an associated current object. When no
However, initializer expressions are not necessarily evaluated in order.
6.7.8 Initialization
- The order in which any side effects occur among the initialization list expressions is
unspecified.
- The order in which any side effects occur among the initialization list expressions is
However, that still leaves some questions unanswered:
Are sequence points even relevant? The basic rule is:
6.5 Expressions
- Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression. Furthermore, the prior value
shall be read only to determine the value to be stored.
a[2] = 1
is an expression, but initialization is not.This is slightly contradicted by Annex J:
J.2 Undefined behavior
- Between two sequence points, an object is modified more than once, or is modified
and the prior value is read other than to determine the value to be stored (6.5).
Annex J says any modification counts, not just modifications by expressions. But given that annexes are non-normative, we can probably ignore that.
- Between the previous and next sequence point an object shall have its stored value
How are the subobject initializations sequenced with respect to initializer expressions? Are all initializers evaluated first (in some order), then the subobjects are initialized with the results (in initializer list order)? Or can they be interleaved?
I think int a[5] = a[2] = 1
is executed as follows:
- Storage for
a
is allocated when its containing block is entered. The contents are indeterminate at this point. - The (only) initializer is executed (
a[2] = 1
), followed by a sequence point. This stores1
ina[2]
and returns1
. - That
1
is used to initializea[0]
(the first initializer initializes the first subobject).
But here things get fuzzy because the remaining elements (a[1]
, a[2]
, a[3]
, a[4]
) are supposed to be initialized to 0
, but it's not clear when: Does it happen before a[2] = 1
is evaluated? If so, a[2] = 1
would "win" and overwrite a[2]
, but would that assignment have undefined behavior because there is no sequence point between the zero initialization and the assignment expression? Are sequence points even relevant (see above)? Or does zero initialization happen after all initializers are evaluated? If so, a[2]
should end up being 0
.
Because the C standard does not clearly define what happens here, I believe the behavior is undefined (by omission).
1
Instead of undefined I would argue that it's unspecified, which leave things open for interpretation by the implementations.
â Some programmer dude
Sep 13 at 8:24
1
"we fall into a rabbit hole" LOL! Never heard that for an UB or unspecified stuff.
â BÃÂþòøÃÂ
Sep 13 at 9:16
2
@Someprogrammerdude I don't think it can be unspecified ("behavior where this International Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance") because the standard doesn't really provide any possibilities among which to choose. It simply doesn't say what happens, which I believe falls under "Undefined behavior is [...] indicated in this International Standard [...] by the omission of any explicit definition of behavior."
â melpomene
Sep 13 at 15:52
2
@BÃÂþòøàIt's also a very nice description not only for undefined behaviour, but also for defined behaviour that needs a thread like this one to explain.
â gnasher729
Sep 13 at 22:40
1
@JohnBollinger The difference is that you cannot actually initialize thea[0]
subobject before evaluating its initializer, and evaluating any initializer includes a sequence point (because it's a "full expression"). Therefore I believe modifying the subobject we're initializing is fair game.
â melpomene
Sep 14 at 19:41
 |Â
show 10 more comments
up vote
21
down vote
I don't understand, why does
a[0]
print1
instead of0
?
Presumably a[2]=1
initializes a[2]
first, and the result of the expression is used to initialize a[0]
.
From N2176 (C17 draft):
6.7.9 Initialization
- The evaluations of the initialization list expressions are indeterminately sequenced with respect to
one another and thus the order in which any side effects occur is unspecified. 154)
So it would seem that output 1 0 0 0 0
would also have been possible.
Conclusion: Don't write initializers that modifies the initialized variable on the fly.
1
That part does not apply: There is only one initializer expression here, so it doesn't need to be sequenced with anything.
â melpomene
Sep 13 at 7:43
@melpomene There is the...
expression which initializesa[2]
to0
, anda[2]=1
sub-expression which initializesa[2]
to1
.
â user694733
Sep 13 at 7:47
1
...
is a braced initializer list. It is not an expression.
â melpomene
Sep 13 at 7:49
@melpomene Ok, you may be right there. But I would still argue there are still 2 competing side-effects so that paragraph stands.
â user694733
Sep 13 at 8:03
@melpomene there are two things to be sequenced: the first initializer, and the setting of other elements to 0
â M.M
Sep 13 at 9:01
 |Â
show 1 more comment
up vote
5
down vote
I think the C11 standard covers this behaviour and says that the result
is unspecified, and I don't think C18 made any relevant changes in
this area.
The standard language is not easy to parse.
The relevant section of the standard is
ç6.7.9 Initialization.
The syntax is documented as:
initializer:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂassignment-expression
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂinitializer-list
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂinitializer-list ,
initializer-list:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignation
opt
ÃÂ initializer
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂinitializer-list , designation
opt
ÃÂ initializer
designation:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignator-list =
designator-list:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignator
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignator-list designator
designator:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ[ constant-expression ]
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ. identifier
Note that one of the terms is assignment-expression, and since a[2] = 1
is indubitably an assignment expression, it is allowed inside
initializers for arrays with non-static duration:
ç4 All the expressions in an initializer for an object that has
static or thread storage duration shall be constant expressions or
string literals.
One of the key paragraphs is:
ç19 The initialization shall occur in initializer list order, each
initializer provided for a particular subobject overriding any
previously listed initializer for the same subobject;151)
all subobjects that are not initialized explicitly shall be
initialized implicitly the same as objects that have static storage
duration.
151) Any initializer for the subobject which is overridden
and so not used to initialize that subobject might not be evaluated at
all.
And another key paragraph is:
ç23 The evaluations of the initialization list expressions are
indeterminately sequenced with respect to one another and thus the
order in which any side effects occur is unspecified.152)
152) In particular, the evaluation order need not be the
same as the order of subobject initialization.
I'm fairly sure that paragraph ç23 indicates that the notation in the
question:
int a[5] = a[2] = 1 ;
leads to unspecified behaviour.
The assignment to a[2]
is a side-effect, and the evaluation order of the
expressions are indeterminately sequenced with respect to one another.
Consequently, I don't think there is a way to appeal to the standard and
claim that a particular compiler is handling this correctly or incorrectly.
add a comment |Â
up vote
3
down vote
My Understanding is a[2]=1
returns value 1 so code becomes
int a[5]=a[2]=1 --> int a[5]=1
int a[5]=1
assign value for a[0]=1
Hence it print 1 for a[0]
For example
char str[10]=âÂÂHâÂÂ,âÂÂaâÂÂ,âÂÂiâÂÂ;
char str[0] = âÂÂHâÂÂ;
char str[1] = âÂÂaâÂÂ;
char str[2] = âÂÂi;
1
This is a [language-lawyer] question, but this is not an answer that works with the standard, thus making it irrelevant. Plus there are also 2 much more in-depth answers available and your answer does not seem to add anything.
â Kami Kaze
Sep 14 at 8:20
I have a doubt.Is the concept I posted wrong?Could you clarify me with this?
â Karthika
Sep 14 at 9:56
You just speculate for reasons, while there is a very good answer already given with relevant parts of the standard. Just saying how it could happen is not what the the question is about. It is about what the standard says should happen.
â Kami Kaze
Sep 14 at 10:00
But the person who posted above question asked the reason and why does it happen? So only i dropped this answer.But concept is correct.Right?
â Karthika
Sep 14 at 10:23
OP asked "Is it undefined behaviour?". Your answer doesn't say.
â melpomene
Sep 14 at 12:12
 |Â
show 1 more comment
up vote
1
down vote
I try to give a short and simple answer for the puzzle: int a[5] = a[2] = 1 ;
- First
a[2] = 1
is set. That means the array says:0 0 1 0 0
- But behold, given that you did it in the
1
) and sets that toa[0]
. It is as ifint a[5] = a[2] ;
would remain, where we already gota[2] = 1
. The resulting array is now:1 0 1 0 0
Another example: int a[6] = a[3] = 1, a[4] = 2, a[5] = 3 ;
- Even though the order is somewhat arbitrary, assuming it goes from left to right, it would go in these 6 steps:
0 0 0 1 0 0
1 0 0 1 0 0
1 0 0 1 2 0
1 2 0 1 2 0
1 2 0 1 2 3
1 2 3 1 2 3
1
A = B = C = 5
is not a declaration (or initialization). It's a normal expression that parses asA = (B = (C = 5))
because the=
operator is right associative. That doesn't really help with explaining how initialization works. The array actually starts existing when the block it is defined in is entered, which can be long before the actual definition is executed.
â melpomene
Sep 13 at 15:48
1
"It goes from left to right, each starting with the internal declaration" is incorrect. The C standard explicitly says "The order in which any side effects occur among the initialization list expressions is unspecified."
â melpomene
Sep 14 at 12:14
1
"You test the code from my example sufficient times and see if the results are consistent." That's not how it works. You don't seem to understand what undefined behavior is. Everything in C has undefined behavior by default; it's just that some parts have behavior that is defined by the standard. To prove that something has defined behavior, you must cite the standard and show where it defines what should happen. In the absence of such a definition, the behavior is undefined.
â melpomene
Sep 14 at 14:49
1
The assertion in point (1) is an enormous leap over the key question here: does the implicit initialization of element a[2] to 0 occur before the side effect of thea[2] = 1
initializer expression is applied? The observed result is as if it was, but the standard does not appear to specify that that should be the case. That is the center of the controversy, and this answer completely overlooks it.
â John Bollinger
Sep 14 at 15:02
1
"Undefined behavior" is a technical term with a narrow meaning. It doesn't mean "behavior we're not really sure about". The key insight here is that no test, with no compiler, can ever show a particular program is or is not well-behaved according to the standard, because if a program has undefined behavior, the compiler is allowed to do anything -- including working in a perfectly predictable and reasonable manner. It's not simply a quality of implementation issue where the compiler writers document things -- that's unspecified or implementation-defined behavior.
â Jeroen Mostert
Sep 14 at 16:04
 |Â
show 9 more comments
up vote
0
down vote
The assignment a[2]= 1
is an expression that has the value 1
, and you essentially wrote int a[5]= 1 ;
(with the side effect that a[2]
is assigned 1
as well).
add a comment |Â
up vote
-3
down vote
Order of operations.
First, the assignment occurs and the assignment is evaluated as this:
int a[5] = 1
, which yields the following:
1, 0, 0, 0, 0
. We get 1
because a[2]=1
evaluates to true and is implicitly cast to 1 in the assignment series.
Second, the expression within the curly brackets is executed, which results in actually assigning 1 to the array at index 2.
You can experiment by compiling int a[5]=true;
and also int a[5]=a[3]=3;
and observing the results.
edit: I was wrong about the result of the assignment within the initialization list, that results in an integer that is the same as what was assigned.
This is a [language-lawyer] question, but this is not an answer that works with the standard, thus making it irrelevant. Plus there are also 2 much more in-depth answers available and your answer does not seem to add anything.
â Kami Kaze
Sep 14 at 8:19
1
"a[2]=1
evaluates to true and is implicitly cast to 1" is nonsense.a[2] = 1
evaluates to1
, there is no cast, and there is no assignment series. You claim thata[2]=1
is evaluated first, and then the expression in curly brackets is executed, which is alsoa[2]=1
. That makes no sense.
â melpomene
Sep 14 at 12:10
add a comment |Â
7 Answers
7
active
oldest
votes
7 Answers
7
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
85
down vote
accepted
TL;DR: I don't think the behavior of int a[5]=a[2]=1;
is well defined, at least in C99.
The funny part is that the only bit that makes sense to me is the part you're asking about: a[0]
is set to 1
because the assignment operator returns the value that was assigned. It's everything else that's unclear.
If the code had been int a[5] = [2] = 1
, everything would've been easy: That's a designated initializer setting a[2]
to 1
and everything else to 0
. But with a[2] = 1
we have a non-designated initializer containing an assignment expression, and we fall down a rabbit hole.
Here's what I've found so far:
a
must be a local variable.
6.7.8 Initialization
- All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.
a[2] = 1
is not a constant expression, soa
must have automatic storage.a
is in scope in its own initialization.
6.2.1 Scopes of identifiers
- Structure, union, and enumeration tags have scope that begins just after the appearance of
the tag in a type specifier that declares the tag. Each enumeration constant has scope that
begins just after the appearance of its defining enumerator in an enumerator list. Any
other identifier has scope that begins just after the completion of its declarator.
The declarator is
a[5]
, so variables are in scope in their own initialization.- Structure, union, and enumeration tags have scope that begins just after the appearance of
a
is alive in its own initialization.
6.2.4 Storage durations of objects
An object whose identifier is declared with no linkage and without the storage-class
specifierstatic
has automatic storage duration.For such an object that does not have a variable length array type, its lifetime extends
from entry into the block with which it is associated until execution of that block ends in
any way. (Entering an enclosed block or calling a function suspends, but does not end,
execution of the current block.) If the block is entered recursively, a new instance of the
object is created each time. The initial value of the object is indeterminate. If an
initialization is specified for the object, it is performed each time the declaration is
reached in the execution of the block; otherwise, the value becomes indeterminate each
time the declaration is reached.
There is a sequence point after
a[2]=1
.
6.8 Statements and blocks
- A full expression is an expression that is not part of another expression or of a declarator.
Each of the following is a full expression: an initializer; the expression in an expression
statement; the controlling expression of a selection statement (if
orswitch
); the
controlling expression of awhile
ordo
statement; each of the (optional) expressions of
afor
statement; the (optional) expression in areturn
statement. The end of a full
expression is a sequence point.
Note that e.g. in
int foo = 1, 2, 3
the1, 2, 3
part is a brace-enclosed list of initializers, each of which has a sequence point after it.- A full expression is an expression that is not part of another expression or of a declarator.
Initialization is performed in initializer list order.
6.7.8 Initialization
- Each brace-enclosed initializer list has an associated current object. When no
designations are present, subobjects of the current object are initialized in order according
to the type of the current object: array elements in increasing subscript order, structure members in declaration order, and the first named member of a union. [...]
Â
- The initialization shall occur in initializer list order, each initializer provided for a
particular subobject overriding any previously listed initializer for the same subobject; all
subobjects that are not initialized explicitly shall be initialized implicitly the same as
objects that have static storage duration.
- Each brace-enclosed initializer list has an associated current object. When no
However, initializer expressions are not necessarily evaluated in order.
6.7.8 Initialization
- The order in which any side effects occur among the initialization list expressions is
unspecified.
- The order in which any side effects occur among the initialization list expressions is
However, that still leaves some questions unanswered:
Are sequence points even relevant? The basic rule is:
6.5 Expressions
- Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression. Furthermore, the prior value
shall be read only to determine the value to be stored.
a[2] = 1
is an expression, but initialization is not.This is slightly contradicted by Annex J:
J.2 Undefined behavior
- Between two sequence points, an object is modified more than once, or is modified
and the prior value is read other than to determine the value to be stored (6.5).
Annex J says any modification counts, not just modifications by expressions. But given that annexes are non-normative, we can probably ignore that.
- Between the previous and next sequence point an object shall have its stored value
How are the subobject initializations sequenced with respect to initializer expressions? Are all initializers evaluated first (in some order), then the subobjects are initialized with the results (in initializer list order)? Or can they be interleaved?
I think int a[5] = a[2] = 1
is executed as follows:
- Storage for
a
is allocated when its containing block is entered. The contents are indeterminate at this point. - The (only) initializer is executed (
a[2] = 1
), followed by a sequence point. This stores1
ina[2]
and returns1
. - That
1
is used to initializea[0]
(the first initializer initializes the first subobject).
But here things get fuzzy because the remaining elements (a[1]
, a[2]
, a[3]
, a[4]
) are supposed to be initialized to 0
, but it's not clear when: Does it happen before a[2] = 1
is evaluated? If so, a[2] = 1
would "win" and overwrite a[2]
, but would that assignment have undefined behavior because there is no sequence point between the zero initialization and the assignment expression? Are sequence points even relevant (see above)? Or does zero initialization happen after all initializers are evaluated? If so, a[2]
should end up being 0
.
Because the C standard does not clearly define what happens here, I believe the behavior is undefined (by omission).
1
Instead of undefined I would argue that it's unspecified, which leave things open for interpretation by the implementations.
â Some programmer dude
Sep 13 at 8:24
1
"we fall into a rabbit hole" LOL! Never heard that for an UB or unspecified stuff.
â BÃÂþòøÃÂ
Sep 13 at 9:16
2
@Someprogrammerdude I don't think it can be unspecified ("behavior where this International Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance") because the standard doesn't really provide any possibilities among which to choose. It simply doesn't say what happens, which I believe falls under "Undefined behavior is [...] indicated in this International Standard [...] by the omission of any explicit definition of behavior."
â melpomene
Sep 13 at 15:52
2
@BÃÂþòøàIt's also a very nice description not only for undefined behaviour, but also for defined behaviour that needs a thread like this one to explain.
â gnasher729
Sep 13 at 22:40
1
@JohnBollinger The difference is that you cannot actually initialize thea[0]
subobject before evaluating its initializer, and evaluating any initializer includes a sequence point (because it's a "full expression"). Therefore I believe modifying the subobject we're initializing is fair game.
â melpomene
Sep 14 at 19:41
 |Â
show 10 more comments
up vote
85
down vote
accepted
TL;DR: I don't think the behavior of int a[5]=a[2]=1;
is well defined, at least in C99.
The funny part is that the only bit that makes sense to me is the part you're asking about: a[0]
is set to 1
because the assignment operator returns the value that was assigned. It's everything else that's unclear.
If the code had been int a[5] = [2] = 1
, everything would've been easy: That's a designated initializer setting a[2]
to 1
and everything else to 0
. But with a[2] = 1
we have a non-designated initializer containing an assignment expression, and we fall down a rabbit hole.
Here's what I've found so far:
a
must be a local variable.
6.7.8 Initialization
- All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.
a[2] = 1
is not a constant expression, soa
must have automatic storage.a
is in scope in its own initialization.
6.2.1 Scopes of identifiers
- Structure, union, and enumeration tags have scope that begins just after the appearance of
the tag in a type specifier that declares the tag. Each enumeration constant has scope that
begins just after the appearance of its defining enumerator in an enumerator list. Any
other identifier has scope that begins just after the completion of its declarator.
The declarator is
a[5]
, so variables are in scope in their own initialization.- Structure, union, and enumeration tags have scope that begins just after the appearance of
a
is alive in its own initialization.
6.2.4 Storage durations of objects
An object whose identifier is declared with no linkage and without the storage-class
specifierstatic
has automatic storage duration.For such an object that does not have a variable length array type, its lifetime extends
from entry into the block with which it is associated until execution of that block ends in
any way. (Entering an enclosed block or calling a function suspends, but does not end,
execution of the current block.) If the block is entered recursively, a new instance of the
object is created each time. The initial value of the object is indeterminate. If an
initialization is specified for the object, it is performed each time the declaration is
reached in the execution of the block; otherwise, the value becomes indeterminate each
time the declaration is reached.
There is a sequence point after
a[2]=1
.
6.8 Statements and blocks
- A full expression is an expression that is not part of another expression or of a declarator.
Each of the following is a full expression: an initializer; the expression in an expression
statement; the controlling expression of a selection statement (if
orswitch
); the
controlling expression of awhile
ordo
statement; each of the (optional) expressions of
afor
statement; the (optional) expression in areturn
statement. The end of a full
expression is a sequence point.
Note that e.g. in
int foo = 1, 2, 3
the1, 2, 3
part is a brace-enclosed list of initializers, each of which has a sequence point after it.- A full expression is an expression that is not part of another expression or of a declarator.
Initialization is performed in initializer list order.
6.7.8 Initialization
- Each brace-enclosed initializer list has an associated current object. When no
designations are present, subobjects of the current object are initialized in order according
to the type of the current object: array elements in increasing subscript order, structure members in declaration order, and the first named member of a union. [...]
Â
- The initialization shall occur in initializer list order, each initializer provided for a
particular subobject overriding any previously listed initializer for the same subobject; all
subobjects that are not initialized explicitly shall be initialized implicitly the same as
objects that have static storage duration.
- Each brace-enclosed initializer list has an associated current object. When no
However, initializer expressions are not necessarily evaluated in order.
6.7.8 Initialization
- The order in which any side effects occur among the initialization list expressions is
unspecified.
- The order in which any side effects occur among the initialization list expressions is
However, that still leaves some questions unanswered:
Are sequence points even relevant? The basic rule is:
6.5 Expressions
- Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression. Furthermore, the prior value
shall be read only to determine the value to be stored.
a[2] = 1
is an expression, but initialization is not.This is slightly contradicted by Annex J:
J.2 Undefined behavior
- Between two sequence points, an object is modified more than once, or is modified
and the prior value is read other than to determine the value to be stored (6.5).
Annex J says any modification counts, not just modifications by expressions. But given that annexes are non-normative, we can probably ignore that.
- Between the previous and next sequence point an object shall have its stored value
How are the subobject initializations sequenced with respect to initializer expressions? Are all initializers evaluated first (in some order), then the subobjects are initialized with the results (in initializer list order)? Or can they be interleaved?
I think int a[5] = a[2] = 1
is executed as follows:
- Storage for
a
is allocated when its containing block is entered. The contents are indeterminate at this point. - The (only) initializer is executed (
a[2] = 1
), followed by a sequence point. This stores1
ina[2]
and returns1
. - That
1
is used to initializea[0]
(the first initializer initializes the first subobject).
But here things get fuzzy because the remaining elements (a[1]
, a[2]
, a[3]
, a[4]
) are supposed to be initialized to 0
, but it's not clear when: Does it happen before a[2] = 1
is evaluated? If so, a[2] = 1
would "win" and overwrite a[2]
, but would that assignment have undefined behavior because there is no sequence point between the zero initialization and the assignment expression? Are sequence points even relevant (see above)? Or does zero initialization happen after all initializers are evaluated? If so, a[2]
should end up being 0
.
Because the C standard does not clearly define what happens here, I believe the behavior is undefined (by omission).
1
Instead of undefined I would argue that it's unspecified, which leave things open for interpretation by the implementations.
â Some programmer dude
Sep 13 at 8:24
1
"we fall into a rabbit hole" LOL! Never heard that for an UB or unspecified stuff.
â BÃÂþòøÃÂ
Sep 13 at 9:16
2
@Someprogrammerdude I don't think it can be unspecified ("behavior where this International Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance") because the standard doesn't really provide any possibilities among which to choose. It simply doesn't say what happens, which I believe falls under "Undefined behavior is [...] indicated in this International Standard [...] by the omission of any explicit definition of behavior."
â melpomene
Sep 13 at 15:52
2
@BÃÂþòøàIt's also a very nice description not only for undefined behaviour, but also for defined behaviour that needs a thread like this one to explain.
â gnasher729
Sep 13 at 22:40
1
@JohnBollinger The difference is that you cannot actually initialize thea[0]
subobject before evaluating its initializer, and evaluating any initializer includes a sequence point (because it's a "full expression"). Therefore I believe modifying the subobject we're initializing is fair game.
â melpomene
Sep 14 at 19:41
 |Â
show 10 more comments
up vote
85
down vote
accepted
up vote
85
down vote
accepted
TL;DR: I don't think the behavior of int a[5]=a[2]=1;
is well defined, at least in C99.
The funny part is that the only bit that makes sense to me is the part you're asking about: a[0]
is set to 1
because the assignment operator returns the value that was assigned. It's everything else that's unclear.
If the code had been int a[5] = [2] = 1
, everything would've been easy: That's a designated initializer setting a[2]
to 1
and everything else to 0
. But with a[2] = 1
we have a non-designated initializer containing an assignment expression, and we fall down a rabbit hole.
Here's what I've found so far:
a
must be a local variable.
6.7.8 Initialization
- All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.
a[2] = 1
is not a constant expression, soa
must have automatic storage.a
is in scope in its own initialization.
6.2.1 Scopes of identifiers
- Structure, union, and enumeration tags have scope that begins just after the appearance of
the tag in a type specifier that declares the tag. Each enumeration constant has scope that
begins just after the appearance of its defining enumerator in an enumerator list. Any
other identifier has scope that begins just after the completion of its declarator.
The declarator is
a[5]
, so variables are in scope in their own initialization.- Structure, union, and enumeration tags have scope that begins just after the appearance of
a
is alive in its own initialization.
6.2.4 Storage durations of objects
An object whose identifier is declared with no linkage and without the storage-class
specifierstatic
has automatic storage duration.For such an object that does not have a variable length array type, its lifetime extends
from entry into the block with which it is associated until execution of that block ends in
any way. (Entering an enclosed block or calling a function suspends, but does not end,
execution of the current block.) If the block is entered recursively, a new instance of the
object is created each time. The initial value of the object is indeterminate. If an
initialization is specified for the object, it is performed each time the declaration is
reached in the execution of the block; otherwise, the value becomes indeterminate each
time the declaration is reached.
There is a sequence point after
a[2]=1
.
6.8 Statements and blocks
- A full expression is an expression that is not part of another expression or of a declarator.
Each of the following is a full expression: an initializer; the expression in an expression
statement; the controlling expression of a selection statement (if
orswitch
); the
controlling expression of awhile
ordo
statement; each of the (optional) expressions of
afor
statement; the (optional) expression in areturn
statement. The end of a full
expression is a sequence point.
Note that e.g. in
int foo = 1, 2, 3
the1, 2, 3
part is a brace-enclosed list of initializers, each of which has a sequence point after it.- A full expression is an expression that is not part of another expression or of a declarator.
Initialization is performed in initializer list order.
6.7.8 Initialization
- Each brace-enclosed initializer list has an associated current object. When no
designations are present, subobjects of the current object are initialized in order according
to the type of the current object: array elements in increasing subscript order, structure members in declaration order, and the first named member of a union. [...]
Â
- The initialization shall occur in initializer list order, each initializer provided for a
particular subobject overriding any previously listed initializer for the same subobject; all
subobjects that are not initialized explicitly shall be initialized implicitly the same as
objects that have static storage duration.
- Each brace-enclosed initializer list has an associated current object. When no
However, initializer expressions are not necessarily evaluated in order.
6.7.8 Initialization
- The order in which any side effects occur among the initialization list expressions is
unspecified.
- The order in which any side effects occur among the initialization list expressions is
However, that still leaves some questions unanswered:
Are sequence points even relevant? The basic rule is:
6.5 Expressions
- Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression. Furthermore, the prior value
shall be read only to determine the value to be stored.
a[2] = 1
is an expression, but initialization is not.This is slightly contradicted by Annex J:
J.2 Undefined behavior
- Between two sequence points, an object is modified more than once, or is modified
and the prior value is read other than to determine the value to be stored (6.5).
Annex J says any modification counts, not just modifications by expressions. But given that annexes are non-normative, we can probably ignore that.
- Between the previous and next sequence point an object shall have its stored value
How are the subobject initializations sequenced with respect to initializer expressions? Are all initializers evaluated first (in some order), then the subobjects are initialized with the results (in initializer list order)? Or can they be interleaved?
I think int a[5] = a[2] = 1
is executed as follows:
- Storage for
a
is allocated when its containing block is entered. The contents are indeterminate at this point. - The (only) initializer is executed (
a[2] = 1
), followed by a sequence point. This stores1
ina[2]
and returns1
. - That
1
is used to initializea[0]
(the first initializer initializes the first subobject).
But here things get fuzzy because the remaining elements (a[1]
, a[2]
, a[3]
, a[4]
) are supposed to be initialized to 0
, but it's not clear when: Does it happen before a[2] = 1
is evaluated? If so, a[2] = 1
would "win" and overwrite a[2]
, but would that assignment have undefined behavior because there is no sequence point between the zero initialization and the assignment expression? Are sequence points even relevant (see above)? Or does zero initialization happen after all initializers are evaluated? If so, a[2]
should end up being 0
.
Because the C standard does not clearly define what happens here, I believe the behavior is undefined (by omission).
TL;DR: I don't think the behavior of int a[5]=a[2]=1;
is well defined, at least in C99.
The funny part is that the only bit that makes sense to me is the part you're asking about: a[0]
is set to 1
because the assignment operator returns the value that was assigned. It's everything else that's unclear.
If the code had been int a[5] = [2] = 1
, everything would've been easy: That's a designated initializer setting a[2]
to 1
and everything else to 0
. But with a[2] = 1
we have a non-designated initializer containing an assignment expression, and we fall down a rabbit hole.
Here's what I've found so far:
a
must be a local variable.
6.7.8 Initialization
- All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.
a[2] = 1
is not a constant expression, soa
must have automatic storage.a
is in scope in its own initialization.
6.2.1 Scopes of identifiers
- Structure, union, and enumeration tags have scope that begins just after the appearance of
the tag in a type specifier that declares the tag. Each enumeration constant has scope that
begins just after the appearance of its defining enumerator in an enumerator list. Any
other identifier has scope that begins just after the completion of its declarator.
The declarator is
a[5]
, so variables are in scope in their own initialization.- Structure, union, and enumeration tags have scope that begins just after the appearance of
a
is alive in its own initialization.
6.2.4 Storage durations of objects
An object whose identifier is declared with no linkage and without the storage-class
specifierstatic
has automatic storage duration.For such an object that does not have a variable length array type, its lifetime extends
from entry into the block with which it is associated until execution of that block ends in
any way. (Entering an enclosed block or calling a function suspends, but does not end,
execution of the current block.) If the block is entered recursively, a new instance of the
object is created each time. The initial value of the object is indeterminate. If an
initialization is specified for the object, it is performed each time the declaration is
reached in the execution of the block; otherwise, the value becomes indeterminate each
time the declaration is reached.
There is a sequence point after
a[2]=1
.
6.8 Statements and blocks
- A full expression is an expression that is not part of another expression or of a declarator.
Each of the following is a full expression: an initializer; the expression in an expression
statement; the controlling expression of a selection statement (if
orswitch
); the
controlling expression of awhile
ordo
statement; each of the (optional) expressions of
afor
statement; the (optional) expression in areturn
statement. The end of a full
expression is a sequence point.
Note that e.g. in
int foo = 1, 2, 3
the1, 2, 3
part is a brace-enclosed list of initializers, each of which has a sequence point after it.- A full expression is an expression that is not part of another expression or of a declarator.
Initialization is performed in initializer list order.
6.7.8 Initialization
- Each brace-enclosed initializer list has an associated current object. When no
designations are present, subobjects of the current object are initialized in order according
to the type of the current object: array elements in increasing subscript order, structure members in declaration order, and the first named member of a union. [...]
Â
- The initialization shall occur in initializer list order, each initializer provided for a
particular subobject overriding any previously listed initializer for the same subobject; all
subobjects that are not initialized explicitly shall be initialized implicitly the same as
objects that have static storage duration.
- Each brace-enclosed initializer list has an associated current object. When no
However, initializer expressions are not necessarily evaluated in order.
6.7.8 Initialization
- The order in which any side effects occur among the initialization list expressions is
unspecified.
- The order in which any side effects occur among the initialization list expressions is
However, that still leaves some questions unanswered:
Are sequence points even relevant? The basic rule is:
6.5 Expressions
- Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression. Furthermore, the prior value
shall be read only to determine the value to be stored.
a[2] = 1
is an expression, but initialization is not.This is slightly contradicted by Annex J:
J.2 Undefined behavior
- Between two sequence points, an object is modified more than once, or is modified
and the prior value is read other than to determine the value to be stored (6.5).
Annex J says any modification counts, not just modifications by expressions. But given that annexes are non-normative, we can probably ignore that.
- Between the previous and next sequence point an object shall have its stored value
How are the subobject initializations sequenced with respect to initializer expressions? Are all initializers evaluated first (in some order), then the subobjects are initialized with the results (in initializer list order)? Or can they be interleaved?
I think int a[5] = a[2] = 1
is executed as follows:
- Storage for
a
is allocated when its containing block is entered. The contents are indeterminate at this point. - The (only) initializer is executed (
a[2] = 1
), followed by a sequence point. This stores1
ina[2]
and returns1
. - That
1
is used to initializea[0]
(the first initializer initializes the first subobject).
But here things get fuzzy because the remaining elements (a[1]
, a[2]
, a[3]
, a[4]
) are supposed to be initialized to 0
, but it's not clear when: Does it happen before a[2] = 1
is evaluated? If so, a[2] = 1
would "win" and overwrite a[2]
, but would that assignment have undefined behavior because there is no sequence point between the zero initialization and the assignment expression? Are sequence points even relevant (see above)? Or does zero initialization happen after all initializers are evaluated? If so, a[2]
should end up being 0
.
Because the C standard does not clearly define what happens here, I believe the behavior is undefined (by omission).
edited Sep 13 at 15:56
answered Sep 13 at 8:03
melpomene
52.6k53782
52.6k53782
1
Instead of undefined I would argue that it's unspecified, which leave things open for interpretation by the implementations.
â Some programmer dude
Sep 13 at 8:24
1
"we fall into a rabbit hole" LOL! Never heard that for an UB or unspecified stuff.
â BÃÂþòøÃÂ
Sep 13 at 9:16
2
@Someprogrammerdude I don't think it can be unspecified ("behavior where this International Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance") because the standard doesn't really provide any possibilities among which to choose. It simply doesn't say what happens, which I believe falls under "Undefined behavior is [...] indicated in this International Standard [...] by the omission of any explicit definition of behavior."
â melpomene
Sep 13 at 15:52
2
@BÃÂþòøàIt's also a very nice description not only for undefined behaviour, but also for defined behaviour that needs a thread like this one to explain.
â gnasher729
Sep 13 at 22:40
1
@JohnBollinger The difference is that you cannot actually initialize thea[0]
subobject before evaluating its initializer, and evaluating any initializer includes a sequence point (because it's a "full expression"). Therefore I believe modifying the subobject we're initializing is fair game.
â melpomene
Sep 14 at 19:41
 |Â
show 10 more comments
1
Instead of undefined I would argue that it's unspecified, which leave things open for interpretation by the implementations.
â Some programmer dude
Sep 13 at 8:24
1
"we fall into a rabbit hole" LOL! Never heard that for an UB or unspecified stuff.
â BÃÂþòøÃÂ
Sep 13 at 9:16
2
@Someprogrammerdude I don't think it can be unspecified ("behavior where this International Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance") because the standard doesn't really provide any possibilities among which to choose. It simply doesn't say what happens, which I believe falls under "Undefined behavior is [...] indicated in this International Standard [...] by the omission of any explicit definition of behavior."
â melpomene
Sep 13 at 15:52
2
@BÃÂþòøàIt's also a very nice description not only for undefined behaviour, but also for defined behaviour that needs a thread like this one to explain.
â gnasher729
Sep 13 at 22:40
1
@JohnBollinger The difference is that you cannot actually initialize thea[0]
subobject before evaluating its initializer, and evaluating any initializer includes a sequence point (because it's a "full expression"). Therefore I believe modifying the subobject we're initializing is fair game.
â melpomene
Sep 14 at 19:41
1
1
Instead of undefined I would argue that it's unspecified, which leave things open for interpretation by the implementations.
â Some programmer dude
Sep 13 at 8:24
Instead of undefined I would argue that it's unspecified, which leave things open for interpretation by the implementations.
â Some programmer dude
Sep 13 at 8:24
1
1
"we fall into a rabbit hole" LOL! Never heard that for an UB or unspecified stuff.
â BÃÂþòøÃÂ
Sep 13 at 9:16
"we fall into a rabbit hole" LOL! Never heard that for an UB or unspecified stuff.
â BÃÂþòøÃÂ
Sep 13 at 9:16
2
2
@Someprogrammerdude I don't think it can be unspecified ("behavior where this International Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance") because the standard doesn't really provide any possibilities among which to choose. It simply doesn't say what happens, which I believe falls under "Undefined behavior is [...] indicated in this International Standard [...] by the omission of any explicit definition of behavior."
â melpomene
Sep 13 at 15:52
@Someprogrammerdude I don't think it can be unspecified ("behavior where this International Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance") because the standard doesn't really provide any possibilities among which to choose. It simply doesn't say what happens, which I believe falls under "Undefined behavior is [...] indicated in this International Standard [...] by the omission of any explicit definition of behavior."
â melpomene
Sep 13 at 15:52
2
2
@BÃÂþòøàIt's also a very nice description not only for undefined behaviour, but also for defined behaviour that needs a thread like this one to explain.
â gnasher729
Sep 13 at 22:40
@BÃÂþòøàIt's also a very nice description not only for undefined behaviour, but also for defined behaviour that needs a thread like this one to explain.
â gnasher729
Sep 13 at 22:40
1
1
@JohnBollinger The difference is that you cannot actually initialize the
a[0]
subobject before evaluating its initializer, and evaluating any initializer includes a sequence point (because it's a "full expression"). Therefore I believe modifying the subobject we're initializing is fair game.â melpomene
Sep 14 at 19:41
@JohnBollinger The difference is that you cannot actually initialize the
a[0]
subobject before evaluating its initializer, and evaluating any initializer includes a sequence point (because it's a "full expression"). Therefore I believe modifying the subobject we're initializing is fair game.â melpomene
Sep 14 at 19:41
 |Â
show 10 more comments
up vote
21
down vote
I don't understand, why does
a[0]
print1
instead of0
?
Presumably a[2]=1
initializes a[2]
first, and the result of the expression is used to initialize a[0]
.
From N2176 (C17 draft):
6.7.9 Initialization
- The evaluations of the initialization list expressions are indeterminately sequenced with respect to
one another and thus the order in which any side effects occur is unspecified. 154)
So it would seem that output 1 0 0 0 0
would also have been possible.
Conclusion: Don't write initializers that modifies the initialized variable on the fly.
1
That part does not apply: There is only one initializer expression here, so it doesn't need to be sequenced with anything.
â melpomene
Sep 13 at 7:43
@melpomene There is the...
expression which initializesa[2]
to0
, anda[2]=1
sub-expression which initializesa[2]
to1
.
â user694733
Sep 13 at 7:47
1
...
is a braced initializer list. It is not an expression.
â melpomene
Sep 13 at 7:49
@melpomene Ok, you may be right there. But I would still argue there are still 2 competing side-effects so that paragraph stands.
â user694733
Sep 13 at 8:03
@melpomene there are two things to be sequenced: the first initializer, and the setting of other elements to 0
â M.M
Sep 13 at 9:01
 |Â
show 1 more comment
up vote
21
down vote
I don't understand, why does
a[0]
print1
instead of0
?
Presumably a[2]=1
initializes a[2]
first, and the result of the expression is used to initialize a[0]
.
From N2176 (C17 draft):
6.7.9 Initialization
- The evaluations of the initialization list expressions are indeterminately sequenced with respect to
one another and thus the order in which any side effects occur is unspecified. 154)
So it would seem that output 1 0 0 0 0
would also have been possible.
Conclusion: Don't write initializers that modifies the initialized variable on the fly.
1
That part does not apply: There is only one initializer expression here, so it doesn't need to be sequenced with anything.
â melpomene
Sep 13 at 7:43
@melpomene There is the...
expression which initializesa[2]
to0
, anda[2]=1
sub-expression which initializesa[2]
to1
.
â user694733
Sep 13 at 7:47
1
...
is a braced initializer list. It is not an expression.
â melpomene
Sep 13 at 7:49
@melpomene Ok, you may be right there. But I would still argue there are still 2 competing side-effects so that paragraph stands.
â user694733
Sep 13 at 8:03
@melpomene there are two things to be sequenced: the first initializer, and the setting of other elements to 0
â M.M
Sep 13 at 9:01
 |Â
show 1 more comment
up vote
21
down vote
up vote
21
down vote
I don't understand, why does
a[0]
print1
instead of0
?
Presumably a[2]=1
initializes a[2]
first, and the result of the expression is used to initialize a[0]
.
From N2176 (C17 draft):
6.7.9 Initialization
- The evaluations of the initialization list expressions are indeterminately sequenced with respect to
one another and thus the order in which any side effects occur is unspecified. 154)
So it would seem that output 1 0 0 0 0
would also have been possible.
Conclusion: Don't write initializers that modifies the initialized variable on the fly.
I don't understand, why does
a[0]
print1
instead of0
?
Presumably a[2]=1
initializes a[2]
first, and the result of the expression is used to initialize a[0]
.
From N2176 (C17 draft):
6.7.9 Initialization
- The evaluations of the initialization list expressions are indeterminately sequenced with respect to
one another and thus the order in which any side effects occur is unspecified. 154)
So it would seem that output 1 0 0 0 0
would also have been possible.
Conclusion: Don't write initializers that modifies the initialized variable on the fly.
edited Sep 13 at 8:17
answered Sep 13 at 7:28
user694733
10.6k12749
10.6k12749
1
That part does not apply: There is only one initializer expression here, so it doesn't need to be sequenced with anything.
â melpomene
Sep 13 at 7:43
@melpomene There is the...
expression which initializesa[2]
to0
, anda[2]=1
sub-expression which initializesa[2]
to1
.
â user694733
Sep 13 at 7:47
1
...
is a braced initializer list. It is not an expression.
â melpomene
Sep 13 at 7:49
@melpomene Ok, you may be right there. But I would still argue there are still 2 competing side-effects so that paragraph stands.
â user694733
Sep 13 at 8:03
@melpomene there are two things to be sequenced: the first initializer, and the setting of other elements to 0
â M.M
Sep 13 at 9:01
 |Â
show 1 more comment
1
That part does not apply: There is only one initializer expression here, so it doesn't need to be sequenced with anything.
â melpomene
Sep 13 at 7:43
@melpomene There is the...
expression which initializesa[2]
to0
, anda[2]=1
sub-expression which initializesa[2]
to1
.
â user694733
Sep 13 at 7:47
1
...
is a braced initializer list. It is not an expression.
â melpomene
Sep 13 at 7:49
@melpomene Ok, you may be right there. But I would still argue there are still 2 competing side-effects so that paragraph stands.
â user694733
Sep 13 at 8:03
@melpomene there are two things to be sequenced: the first initializer, and the setting of other elements to 0
â M.M
Sep 13 at 9:01
1
1
That part does not apply: There is only one initializer expression here, so it doesn't need to be sequenced with anything.
â melpomene
Sep 13 at 7:43
That part does not apply: There is only one initializer expression here, so it doesn't need to be sequenced with anything.
â melpomene
Sep 13 at 7:43
@melpomene There is the
...
expression which initializes a[2]
to 0
, and a[2]=1
sub-expression which initializes a[2]
to 1
.â user694733
Sep 13 at 7:47
@melpomene There is the
...
expression which initializes a[2]
to 0
, and a[2]=1
sub-expression which initializes a[2]
to 1
.â user694733
Sep 13 at 7:47
1
1
...
is a braced initializer list. It is not an expression.â melpomene
Sep 13 at 7:49
...
is a braced initializer list. It is not an expression.â melpomene
Sep 13 at 7:49
@melpomene Ok, you may be right there. But I would still argue there are still 2 competing side-effects so that paragraph stands.
â user694733
Sep 13 at 8:03
@melpomene Ok, you may be right there. But I would still argue there are still 2 competing side-effects so that paragraph stands.
â user694733
Sep 13 at 8:03
@melpomene there are two things to be sequenced: the first initializer, and the setting of other elements to 0
â M.M
Sep 13 at 9:01
@melpomene there are two things to be sequenced: the first initializer, and the setting of other elements to 0
â M.M
Sep 13 at 9:01
 |Â
show 1 more comment
up vote
5
down vote
I think the C11 standard covers this behaviour and says that the result
is unspecified, and I don't think C18 made any relevant changes in
this area.
The standard language is not easy to parse.
The relevant section of the standard is
ç6.7.9 Initialization.
The syntax is documented as:
initializer:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂassignment-expression
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂinitializer-list
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂinitializer-list ,
initializer-list:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignation
opt
ÃÂ initializer
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂinitializer-list , designation
opt
ÃÂ initializer
designation:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignator-list =
designator-list:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignator
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignator-list designator
designator:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ[ constant-expression ]
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ. identifier
Note that one of the terms is assignment-expression, and since a[2] = 1
is indubitably an assignment expression, it is allowed inside
initializers for arrays with non-static duration:
ç4 All the expressions in an initializer for an object that has
static or thread storage duration shall be constant expressions or
string literals.
One of the key paragraphs is:
ç19 The initialization shall occur in initializer list order, each
initializer provided for a particular subobject overriding any
previously listed initializer for the same subobject;151)
all subobjects that are not initialized explicitly shall be
initialized implicitly the same as objects that have static storage
duration.
151) Any initializer for the subobject which is overridden
and so not used to initialize that subobject might not be evaluated at
all.
And another key paragraph is:
ç23 The evaluations of the initialization list expressions are
indeterminately sequenced with respect to one another and thus the
order in which any side effects occur is unspecified.152)
152) In particular, the evaluation order need not be the
same as the order of subobject initialization.
I'm fairly sure that paragraph ç23 indicates that the notation in the
question:
int a[5] = a[2] = 1 ;
leads to unspecified behaviour.
The assignment to a[2]
is a side-effect, and the evaluation order of the
expressions are indeterminately sequenced with respect to one another.
Consequently, I don't think there is a way to appeal to the standard and
claim that a particular compiler is handling this correctly or incorrectly.
add a comment |Â
up vote
5
down vote
I think the C11 standard covers this behaviour and says that the result
is unspecified, and I don't think C18 made any relevant changes in
this area.
The standard language is not easy to parse.
The relevant section of the standard is
ç6.7.9 Initialization.
The syntax is documented as:
initializer:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂassignment-expression
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂinitializer-list
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂinitializer-list ,
initializer-list:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignation
opt
ÃÂ initializer
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂinitializer-list , designation
opt
ÃÂ initializer
designation:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignator-list =
designator-list:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignator
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignator-list designator
designator:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ[ constant-expression ]
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ. identifier
Note that one of the terms is assignment-expression, and since a[2] = 1
is indubitably an assignment expression, it is allowed inside
initializers for arrays with non-static duration:
ç4 All the expressions in an initializer for an object that has
static or thread storage duration shall be constant expressions or
string literals.
One of the key paragraphs is:
ç19 The initialization shall occur in initializer list order, each
initializer provided for a particular subobject overriding any
previously listed initializer for the same subobject;151)
all subobjects that are not initialized explicitly shall be
initialized implicitly the same as objects that have static storage
duration.
151) Any initializer for the subobject which is overridden
and so not used to initialize that subobject might not be evaluated at
all.
And another key paragraph is:
ç23 The evaluations of the initialization list expressions are
indeterminately sequenced with respect to one another and thus the
order in which any side effects occur is unspecified.152)
152) In particular, the evaluation order need not be the
same as the order of subobject initialization.
I'm fairly sure that paragraph ç23 indicates that the notation in the
question:
int a[5] = a[2] = 1 ;
leads to unspecified behaviour.
The assignment to a[2]
is a side-effect, and the evaluation order of the
expressions are indeterminately sequenced with respect to one another.
Consequently, I don't think there is a way to appeal to the standard and
claim that a particular compiler is handling this correctly or incorrectly.
add a comment |Â
up vote
5
down vote
up vote
5
down vote
I think the C11 standard covers this behaviour and says that the result
is unspecified, and I don't think C18 made any relevant changes in
this area.
The standard language is not easy to parse.
The relevant section of the standard is
ç6.7.9 Initialization.
The syntax is documented as:
initializer:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂassignment-expression
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂinitializer-list
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂinitializer-list ,
initializer-list:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignation
opt
ÃÂ initializer
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂinitializer-list , designation
opt
ÃÂ initializer
designation:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignator-list =
designator-list:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignator
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignator-list designator
designator:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ[ constant-expression ]
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ. identifier
Note that one of the terms is assignment-expression, and since a[2] = 1
is indubitably an assignment expression, it is allowed inside
initializers for arrays with non-static duration:
ç4 All the expressions in an initializer for an object that has
static or thread storage duration shall be constant expressions or
string literals.
One of the key paragraphs is:
ç19 The initialization shall occur in initializer list order, each
initializer provided for a particular subobject overriding any
previously listed initializer for the same subobject;151)
all subobjects that are not initialized explicitly shall be
initialized implicitly the same as objects that have static storage
duration.
151) Any initializer for the subobject which is overridden
and so not used to initialize that subobject might not be evaluated at
all.
And another key paragraph is:
ç23 The evaluations of the initialization list expressions are
indeterminately sequenced with respect to one another and thus the
order in which any side effects occur is unspecified.152)
152) In particular, the evaluation order need not be the
same as the order of subobject initialization.
I'm fairly sure that paragraph ç23 indicates that the notation in the
question:
int a[5] = a[2] = 1 ;
leads to unspecified behaviour.
The assignment to a[2]
is a side-effect, and the evaluation order of the
expressions are indeterminately sequenced with respect to one another.
Consequently, I don't think there is a way to appeal to the standard and
claim that a particular compiler is handling this correctly or incorrectly.
I think the C11 standard covers this behaviour and says that the result
is unspecified, and I don't think C18 made any relevant changes in
this area.
The standard language is not easy to parse.
The relevant section of the standard is
ç6.7.9 Initialization.
The syntax is documented as:
initializer:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂassignment-expression
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂinitializer-list
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂinitializer-list ,
initializer-list:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignation
opt
ÃÂ initializer
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂinitializer-list , designation
opt
ÃÂ initializer
designation:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignator-list =
designator-list:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignator
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂdesignator-list designator
designator:
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ[ constant-expression ]
ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ. identifier
Note that one of the terms is assignment-expression, and since a[2] = 1
is indubitably an assignment expression, it is allowed inside
initializers for arrays with non-static duration:
ç4 All the expressions in an initializer for an object that has
static or thread storage duration shall be constant expressions or
string literals.
One of the key paragraphs is:
ç19 The initialization shall occur in initializer list order, each
initializer provided for a particular subobject overriding any
previously listed initializer for the same subobject;151)
all subobjects that are not initialized explicitly shall be
initialized implicitly the same as objects that have static storage
duration.
151) Any initializer for the subobject which is overridden
and so not used to initialize that subobject might not be evaluated at
all.
And another key paragraph is:
ç23 The evaluations of the initialization list expressions are
indeterminately sequenced with respect to one another and thus the
order in which any side effects occur is unspecified.152)
152) In particular, the evaluation order need not be the
same as the order of subobject initialization.
I'm fairly sure that paragraph ç23 indicates that the notation in the
question:
int a[5] = a[2] = 1 ;
leads to unspecified behaviour.
The assignment to a[2]
is a side-effect, and the evaluation order of the
expressions are indeterminately sequenced with respect to one another.
Consequently, I don't think there is a way to appeal to the standard and
claim that a particular compiler is handling this correctly or incorrectly.
edited Sep 23 at 13:57
answered Sep 16 at 6:48
Jonathan Leffler
547k856491001
547k856491001
add a comment |Â
add a comment |Â
up vote
3
down vote
My Understanding is a[2]=1
returns value 1 so code becomes
int a[5]=a[2]=1 --> int a[5]=1
int a[5]=1
assign value for a[0]=1
Hence it print 1 for a[0]
For example
char str[10]=âÂÂHâÂÂ,âÂÂaâÂÂ,âÂÂiâÂÂ;
char str[0] = âÂÂHâÂÂ;
char str[1] = âÂÂaâÂÂ;
char str[2] = âÂÂi;
1
This is a [language-lawyer] question, but this is not an answer that works with the standard, thus making it irrelevant. Plus there are also 2 much more in-depth answers available and your answer does not seem to add anything.
â Kami Kaze
Sep 14 at 8:20
I have a doubt.Is the concept I posted wrong?Could you clarify me with this?
â Karthika
Sep 14 at 9:56
You just speculate for reasons, while there is a very good answer already given with relevant parts of the standard. Just saying how it could happen is not what the the question is about. It is about what the standard says should happen.
â Kami Kaze
Sep 14 at 10:00
But the person who posted above question asked the reason and why does it happen? So only i dropped this answer.But concept is correct.Right?
â Karthika
Sep 14 at 10:23
OP asked "Is it undefined behaviour?". Your answer doesn't say.
â melpomene
Sep 14 at 12:12
 |Â
show 1 more comment
up vote
3
down vote
My Understanding is a[2]=1
returns value 1 so code becomes
int a[5]=a[2]=1 --> int a[5]=1
int a[5]=1
assign value for a[0]=1
Hence it print 1 for a[0]
For example
char str[10]=âÂÂHâÂÂ,âÂÂaâÂÂ,âÂÂiâÂÂ;
char str[0] = âÂÂHâÂÂ;
char str[1] = âÂÂaâÂÂ;
char str[2] = âÂÂi;
1
This is a [language-lawyer] question, but this is not an answer that works with the standard, thus making it irrelevant. Plus there are also 2 much more in-depth answers available and your answer does not seem to add anything.
â Kami Kaze
Sep 14 at 8:20
I have a doubt.Is the concept I posted wrong?Could you clarify me with this?
â Karthika
Sep 14 at 9:56
You just speculate for reasons, while there is a very good answer already given with relevant parts of the standard. Just saying how it could happen is not what the the question is about. It is about what the standard says should happen.
â Kami Kaze
Sep 14 at 10:00
But the person who posted above question asked the reason and why does it happen? So only i dropped this answer.But concept is correct.Right?
â Karthika
Sep 14 at 10:23
OP asked "Is it undefined behaviour?". Your answer doesn't say.
â melpomene
Sep 14 at 12:12
 |Â
show 1 more comment
up vote
3
down vote
up vote
3
down vote
My Understanding is a[2]=1
returns value 1 so code becomes
int a[5]=a[2]=1 --> int a[5]=1
int a[5]=1
assign value for a[0]=1
Hence it print 1 for a[0]
For example
char str[10]=âÂÂHâÂÂ,âÂÂaâÂÂ,âÂÂiâÂÂ;
char str[0] = âÂÂHâÂÂ;
char str[1] = âÂÂaâÂÂ;
char str[2] = âÂÂi;
My Understanding is a[2]=1
returns value 1 so code becomes
int a[5]=a[2]=1 --> int a[5]=1
int a[5]=1
assign value for a[0]=1
Hence it print 1 for a[0]
For example
char str[10]=âÂÂHâÂÂ,âÂÂaâÂÂ,âÂÂiâÂÂ;
char str[0] = âÂÂHâÂÂ;
char str[1] = âÂÂaâÂÂ;
char str[2] = âÂÂi;
answered Sep 13 at 9:43
Karthika
786
786
1
This is a [language-lawyer] question, but this is not an answer that works with the standard, thus making it irrelevant. Plus there are also 2 much more in-depth answers available and your answer does not seem to add anything.
â Kami Kaze
Sep 14 at 8:20
I have a doubt.Is the concept I posted wrong?Could you clarify me with this?
â Karthika
Sep 14 at 9:56
You just speculate for reasons, while there is a very good answer already given with relevant parts of the standard. Just saying how it could happen is not what the the question is about. It is about what the standard says should happen.
â Kami Kaze
Sep 14 at 10:00
But the person who posted above question asked the reason and why does it happen? So only i dropped this answer.But concept is correct.Right?
â Karthika
Sep 14 at 10:23
OP asked "Is it undefined behaviour?". Your answer doesn't say.
â melpomene
Sep 14 at 12:12
 |Â
show 1 more comment
1
This is a [language-lawyer] question, but this is not an answer that works with the standard, thus making it irrelevant. Plus there are also 2 much more in-depth answers available and your answer does not seem to add anything.
â Kami Kaze
Sep 14 at 8:20
I have a doubt.Is the concept I posted wrong?Could you clarify me with this?
â Karthika
Sep 14 at 9:56
You just speculate for reasons, while there is a very good answer already given with relevant parts of the standard. Just saying how it could happen is not what the the question is about. It is about what the standard says should happen.
â Kami Kaze
Sep 14 at 10:00
But the person who posted above question asked the reason and why does it happen? So only i dropped this answer.But concept is correct.Right?
â Karthika
Sep 14 at 10:23
OP asked "Is it undefined behaviour?". Your answer doesn't say.
â melpomene
Sep 14 at 12:12
1
1
This is a [language-lawyer] question, but this is not an answer that works with the standard, thus making it irrelevant. Plus there are also 2 much more in-depth answers available and your answer does not seem to add anything.
â Kami Kaze
Sep 14 at 8:20
This is a [language-lawyer] question, but this is not an answer that works with the standard, thus making it irrelevant. Plus there are also 2 much more in-depth answers available and your answer does not seem to add anything.
â Kami Kaze
Sep 14 at 8:20
I have a doubt.Is the concept I posted wrong?Could you clarify me with this?
â Karthika
Sep 14 at 9:56
I have a doubt.Is the concept I posted wrong?Could you clarify me with this?
â Karthika
Sep 14 at 9:56
You just speculate for reasons, while there is a very good answer already given with relevant parts of the standard. Just saying how it could happen is not what the the question is about. It is about what the standard says should happen.
â Kami Kaze
Sep 14 at 10:00
You just speculate for reasons, while there is a very good answer already given with relevant parts of the standard. Just saying how it could happen is not what the the question is about. It is about what the standard says should happen.
â Kami Kaze
Sep 14 at 10:00
But the person who posted above question asked the reason and why does it happen? So only i dropped this answer.But concept is correct.Right?
â Karthika
Sep 14 at 10:23
But the person who posted above question asked the reason and why does it happen? So only i dropped this answer.But concept is correct.Right?
â Karthika
Sep 14 at 10:23
OP asked "Is it undefined behaviour?". Your answer doesn't say.
â melpomene
Sep 14 at 12:12
OP asked "Is it undefined behaviour?". Your answer doesn't say.
â melpomene
Sep 14 at 12:12
 |Â
show 1 more comment
up vote
1
down vote
I try to give a short and simple answer for the puzzle: int a[5] = a[2] = 1 ;
- First
a[2] = 1
is set. That means the array says:0 0 1 0 0
- But behold, given that you did it in the
1
) and sets that toa[0]
. It is as ifint a[5] = a[2] ;
would remain, where we already gota[2] = 1
. The resulting array is now:1 0 1 0 0
Another example: int a[6] = a[3] = 1, a[4] = 2, a[5] = 3 ;
- Even though the order is somewhat arbitrary, assuming it goes from left to right, it would go in these 6 steps:
0 0 0 1 0 0
1 0 0 1 0 0
1 0 0 1 2 0
1 2 0 1 2 0
1 2 0 1 2 3
1 2 3 1 2 3
1
A = B = C = 5
is not a declaration (or initialization). It's a normal expression that parses asA = (B = (C = 5))
because the=
operator is right associative. That doesn't really help with explaining how initialization works. The array actually starts existing when the block it is defined in is entered, which can be long before the actual definition is executed.
â melpomene
Sep 13 at 15:48
1
"It goes from left to right, each starting with the internal declaration" is incorrect. The C standard explicitly says "The order in which any side effects occur among the initialization list expressions is unspecified."
â melpomene
Sep 14 at 12:14
1
"You test the code from my example sufficient times and see if the results are consistent." That's not how it works. You don't seem to understand what undefined behavior is. Everything in C has undefined behavior by default; it's just that some parts have behavior that is defined by the standard. To prove that something has defined behavior, you must cite the standard and show where it defines what should happen. In the absence of such a definition, the behavior is undefined.
â melpomene
Sep 14 at 14:49
1
The assertion in point (1) is an enormous leap over the key question here: does the implicit initialization of element a[2] to 0 occur before the side effect of thea[2] = 1
initializer expression is applied? The observed result is as if it was, but the standard does not appear to specify that that should be the case. That is the center of the controversy, and this answer completely overlooks it.
â John Bollinger
Sep 14 at 15:02
1
"Undefined behavior" is a technical term with a narrow meaning. It doesn't mean "behavior we're not really sure about". The key insight here is that no test, with no compiler, can ever show a particular program is or is not well-behaved according to the standard, because if a program has undefined behavior, the compiler is allowed to do anything -- including working in a perfectly predictable and reasonable manner. It's not simply a quality of implementation issue where the compiler writers document things -- that's unspecified or implementation-defined behavior.
â Jeroen Mostert
Sep 14 at 16:04
 |Â
show 9 more comments
up vote
1
down vote
I try to give a short and simple answer for the puzzle: int a[5] = a[2] = 1 ;
- First
a[2] = 1
is set. That means the array says:0 0 1 0 0
- But behold, given that you did it in the
1
) and sets that toa[0]
. It is as ifint a[5] = a[2] ;
would remain, where we already gota[2] = 1
. The resulting array is now:1 0 1 0 0
Another example: int a[6] = a[3] = 1, a[4] = 2, a[5] = 3 ;
- Even though the order is somewhat arbitrary, assuming it goes from left to right, it would go in these 6 steps:
0 0 0 1 0 0
1 0 0 1 0 0
1 0 0 1 2 0
1 2 0 1 2 0
1 2 0 1 2 3
1 2 3 1 2 3
1
A = B = C = 5
is not a declaration (or initialization). It's a normal expression that parses asA = (B = (C = 5))
because the=
operator is right associative. That doesn't really help with explaining how initialization works. The array actually starts existing when the block it is defined in is entered, which can be long before the actual definition is executed.
â melpomene
Sep 13 at 15:48
1
"It goes from left to right, each starting with the internal declaration" is incorrect. The C standard explicitly says "The order in which any side effects occur among the initialization list expressions is unspecified."
â melpomene
Sep 14 at 12:14
1
"You test the code from my example sufficient times and see if the results are consistent." That's not how it works. You don't seem to understand what undefined behavior is. Everything in C has undefined behavior by default; it's just that some parts have behavior that is defined by the standard. To prove that something has defined behavior, you must cite the standard and show where it defines what should happen. In the absence of such a definition, the behavior is undefined.
â melpomene
Sep 14 at 14:49
1
The assertion in point (1) is an enormous leap over the key question here: does the implicit initialization of element a[2] to 0 occur before the side effect of thea[2] = 1
initializer expression is applied? The observed result is as if it was, but the standard does not appear to specify that that should be the case. That is the center of the controversy, and this answer completely overlooks it.
â John Bollinger
Sep 14 at 15:02
1
"Undefined behavior" is a technical term with a narrow meaning. It doesn't mean "behavior we're not really sure about". The key insight here is that no test, with no compiler, can ever show a particular program is or is not well-behaved according to the standard, because if a program has undefined behavior, the compiler is allowed to do anything -- including working in a perfectly predictable and reasonable manner. It's not simply a quality of implementation issue where the compiler writers document things -- that's unspecified or implementation-defined behavior.
â Jeroen Mostert
Sep 14 at 16:04
 |Â
show 9 more comments
up vote
1
down vote
up vote
1
down vote
I try to give a short and simple answer for the puzzle: int a[5] = a[2] = 1 ;
- First
a[2] = 1
is set. That means the array says:0 0 1 0 0
- But behold, given that you did it in the
1
) and sets that toa[0]
. It is as ifint a[5] = a[2] ;
would remain, where we already gota[2] = 1
. The resulting array is now:1 0 1 0 0
Another example: int a[6] = a[3] = 1, a[4] = 2, a[5] = 3 ;
- Even though the order is somewhat arbitrary, assuming it goes from left to right, it would go in these 6 steps:
0 0 0 1 0 0
1 0 0 1 0 0
1 0 0 1 2 0
1 2 0 1 2 0
1 2 0 1 2 3
1 2 3 1 2 3
I try to give a short and simple answer for the puzzle: int a[5] = a[2] = 1 ;
- First
a[2] = 1
is set. That means the array says:0 0 1 0 0
- But behold, given that you did it in the
1
) and sets that toa[0]
. It is as ifint a[5] = a[2] ;
would remain, where we already gota[2] = 1
. The resulting array is now:1 0 1 0 0
Another example: int a[6] = a[3] = 1, a[4] = 2, a[5] = 3 ;
- Even though the order is somewhat arbitrary, assuming it goes from left to right, it would go in these 6 steps:
0 0 0 1 0 0
1 0 0 1 0 0
1 0 0 1 2 0
1 2 0 1 2 0
1 2 0 1 2 3
1 2 3 1 2 3
edited Sep 14 at 13:58
answered Sep 13 at 11:58
Battle
31717
31717
1
A = B = C = 5
is not a declaration (or initialization). It's a normal expression that parses asA = (B = (C = 5))
because the=
operator is right associative. That doesn't really help with explaining how initialization works. The array actually starts existing when the block it is defined in is entered, which can be long before the actual definition is executed.
â melpomene
Sep 13 at 15:48
1
"It goes from left to right, each starting with the internal declaration" is incorrect. The C standard explicitly says "The order in which any side effects occur among the initialization list expressions is unspecified."
â melpomene
Sep 14 at 12:14
1
"You test the code from my example sufficient times and see if the results are consistent." That's not how it works. You don't seem to understand what undefined behavior is. Everything in C has undefined behavior by default; it's just that some parts have behavior that is defined by the standard. To prove that something has defined behavior, you must cite the standard and show where it defines what should happen. In the absence of such a definition, the behavior is undefined.
â melpomene
Sep 14 at 14:49
1
The assertion in point (1) is an enormous leap over the key question here: does the implicit initialization of element a[2] to 0 occur before the side effect of thea[2] = 1
initializer expression is applied? The observed result is as if it was, but the standard does not appear to specify that that should be the case. That is the center of the controversy, and this answer completely overlooks it.
â John Bollinger
Sep 14 at 15:02
1
"Undefined behavior" is a technical term with a narrow meaning. It doesn't mean "behavior we're not really sure about". The key insight here is that no test, with no compiler, can ever show a particular program is or is not well-behaved according to the standard, because if a program has undefined behavior, the compiler is allowed to do anything -- including working in a perfectly predictable and reasonable manner. It's not simply a quality of implementation issue where the compiler writers document things -- that's unspecified or implementation-defined behavior.
â Jeroen Mostert
Sep 14 at 16:04
 |Â
show 9 more comments
1
A = B = C = 5
is not a declaration (or initialization). It's a normal expression that parses asA = (B = (C = 5))
because the=
operator is right associative. That doesn't really help with explaining how initialization works. The array actually starts existing when the block it is defined in is entered, which can be long before the actual definition is executed.
â melpomene
Sep 13 at 15:48
1
"It goes from left to right, each starting with the internal declaration" is incorrect. The C standard explicitly says "The order in which any side effects occur among the initialization list expressions is unspecified."
â melpomene
Sep 14 at 12:14
1
"You test the code from my example sufficient times and see if the results are consistent." That's not how it works. You don't seem to understand what undefined behavior is. Everything in C has undefined behavior by default; it's just that some parts have behavior that is defined by the standard. To prove that something has defined behavior, you must cite the standard and show where it defines what should happen. In the absence of such a definition, the behavior is undefined.
â melpomene
Sep 14 at 14:49
1
The assertion in point (1) is an enormous leap over the key question here: does the implicit initialization of element a[2] to 0 occur before the side effect of thea[2] = 1
initializer expression is applied? The observed result is as if it was, but the standard does not appear to specify that that should be the case. That is the center of the controversy, and this answer completely overlooks it.
â John Bollinger
Sep 14 at 15:02
1
"Undefined behavior" is a technical term with a narrow meaning. It doesn't mean "behavior we're not really sure about". The key insight here is that no test, with no compiler, can ever show a particular program is or is not well-behaved according to the standard, because if a program has undefined behavior, the compiler is allowed to do anything -- including working in a perfectly predictable and reasonable manner. It's not simply a quality of implementation issue where the compiler writers document things -- that's unspecified or implementation-defined behavior.
â Jeroen Mostert
Sep 14 at 16:04
1
1
A = B = C = 5
is not a declaration (or initialization). It's a normal expression that parses as A = (B = (C = 5))
because the =
operator is right associative. That doesn't really help with explaining how initialization works. The array actually starts existing when the block it is defined in is entered, which can be long before the actual definition is executed.â melpomene
Sep 13 at 15:48
A = B = C = 5
is not a declaration (or initialization). It's a normal expression that parses as A = (B = (C = 5))
because the =
operator is right associative. That doesn't really help with explaining how initialization works. The array actually starts existing when the block it is defined in is entered, which can be long before the actual definition is executed.â melpomene
Sep 13 at 15:48
1
1
"It goes from left to right, each starting with the internal declaration" is incorrect. The C standard explicitly says "The order in which any side effects occur among the initialization list expressions is unspecified."
â melpomene
Sep 14 at 12:14
"It goes from left to right, each starting with the internal declaration" is incorrect. The C standard explicitly says "The order in which any side effects occur among the initialization list expressions is unspecified."
â melpomene
Sep 14 at 12:14
1
1
"You test the code from my example sufficient times and see if the results are consistent." That's not how it works. You don't seem to understand what undefined behavior is. Everything in C has undefined behavior by default; it's just that some parts have behavior that is defined by the standard. To prove that something has defined behavior, you must cite the standard and show where it defines what should happen. In the absence of such a definition, the behavior is undefined.
â melpomene
Sep 14 at 14:49
"You test the code from my example sufficient times and see if the results are consistent." That's not how it works. You don't seem to understand what undefined behavior is. Everything in C has undefined behavior by default; it's just that some parts have behavior that is defined by the standard. To prove that something has defined behavior, you must cite the standard and show where it defines what should happen. In the absence of such a definition, the behavior is undefined.
â melpomene
Sep 14 at 14:49
1
1
The assertion in point (1) is an enormous leap over the key question here: does the implicit initialization of element a[2] to 0 occur before the side effect of the
a[2] = 1
initializer expression is applied? The observed result is as if it was, but the standard does not appear to specify that that should be the case. That is the center of the controversy, and this answer completely overlooks it.â John Bollinger
Sep 14 at 15:02
The assertion in point (1) is an enormous leap over the key question here: does the implicit initialization of element a[2] to 0 occur before the side effect of the
a[2] = 1
initializer expression is applied? The observed result is as if it was, but the standard does not appear to specify that that should be the case. That is the center of the controversy, and this answer completely overlooks it.â John Bollinger
Sep 14 at 15:02
1
1
"Undefined behavior" is a technical term with a narrow meaning. It doesn't mean "behavior we're not really sure about". The key insight here is that no test, with no compiler, can ever show a particular program is or is not well-behaved according to the standard, because if a program has undefined behavior, the compiler is allowed to do anything -- including working in a perfectly predictable and reasonable manner. It's not simply a quality of implementation issue where the compiler writers document things -- that's unspecified or implementation-defined behavior.
â Jeroen Mostert
Sep 14 at 16:04
"Undefined behavior" is a technical term with a narrow meaning. It doesn't mean "behavior we're not really sure about". The key insight here is that no test, with no compiler, can ever show a particular program is or is not well-behaved according to the standard, because if a program has undefined behavior, the compiler is allowed to do anything -- including working in a perfectly predictable and reasonable manner. It's not simply a quality of implementation issue where the compiler writers document things -- that's unspecified or implementation-defined behavior.
â Jeroen Mostert
Sep 14 at 16:04
 |Â
show 9 more comments
up vote
0
down vote
The assignment a[2]= 1
is an expression that has the value 1
, and you essentially wrote int a[5]= 1 ;
(with the side effect that a[2]
is assigned 1
as well).
add a comment |Â
up vote
0
down vote
The assignment a[2]= 1
is an expression that has the value 1
, and you essentially wrote int a[5]= 1 ;
(with the side effect that a[2]
is assigned 1
as well).
add a comment |Â
up vote
0
down vote
up vote
0
down vote
The assignment a[2]= 1
is an expression that has the value 1
, and you essentially wrote int a[5]= 1 ;
(with the side effect that a[2]
is assigned 1
as well).
The assignment a[2]= 1
is an expression that has the value 1
, and you essentially wrote int a[5]= 1 ;
(with the side effect that a[2]
is assigned 1
as well).
answered Sep 19 at 7:05
Yves Daoust
35.4k62557
35.4k62557
add a comment |Â
add a comment |Â
up vote
-3
down vote
Order of operations.
First, the assignment occurs and the assignment is evaluated as this:
int a[5] = 1
, which yields the following:
1, 0, 0, 0, 0
. We get 1
because a[2]=1
evaluates to true and is implicitly cast to 1 in the assignment series.
Second, the expression within the curly brackets is executed, which results in actually assigning 1 to the array at index 2.
You can experiment by compiling int a[5]=true;
and also int a[5]=a[3]=3;
and observing the results.
edit: I was wrong about the result of the assignment within the initialization list, that results in an integer that is the same as what was assigned.
This is a [language-lawyer] question, but this is not an answer that works with the standard, thus making it irrelevant. Plus there are also 2 much more in-depth answers available and your answer does not seem to add anything.
â Kami Kaze
Sep 14 at 8:19
1
"a[2]=1
evaluates to true and is implicitly cast to 1" is nonsense.a[2] = 1
evaluates to1
, there is no cast, and there is no assignment series. You claim thata[2]=1
is evaluated first, and then the expression in curly brackets is executed, which is alsoa[2]=1
. That makes no sense.
â melpomene
Sep 14 at 12:10
add a comment |Â
up vote
-3
down vote
Order of operations.
First, the assignment occurs and the assignment is evaluated as this:
int a[5] = 1
, which yields the following:
1, 0, 0, 0, 0
. We get 1
because a[2]=1
evaluates to true and is implicitly cast to 1 in the assignment series.
Second, the expression within the curly brackets is executed, which results in actually assigning 1 to the array at index 2.
You can experiment by compiling int a[5]=true;
and also int a[5]=a[3]=3;
and observing the results.
edit: I was wrong about the result of the assignment within the initialization list, that results in an integer that is the same as what was assigned.
This is a [language-lawyer] question, but this is not an answer that works with the standard, thus making it irrelevant. Plus there are also 2 much more in-depth answers available and your answer does not seem to add anything.
â Kami Kaze
Sep 14 at 8:19
1
"a[2]=1
evaluates to true and is implicitly cast to 1" is nonsense.a[2] = 1
evaluates to1
, there is no cast, and there is no assignment series. You claim thata[2]=1
is evaluated first, and then the expression in curly brackets is executed, which is alsoa[2]=1
. That makes no sense.
â melpomene
Sep 14 at 12:10
add a comment |Â
up vote
-3
down vote
up vote
-3
down vote
Order of operations.
First, the assignment occurs and the assignment is evaluated as this:
int a[5] = 1
, which yields the following:
1, 0, 0, 0, 0
. We get 1
because a[2]=1
evaluates to true and is implicitly cast to 1 in the assignment series.
Second, the expression within the curly brackets is executed, which results in actually assigning 1 to the array at index 2.
You can experiment by compiling int a[5]=true;
and also int a[5]=a[3]=3;
and observing the results.
edit: I was wrong about the result of the assignment within the initialization list, that results in an integer that is the same as what was assigned.
Order of operations.
First, the assignment occurs and the assignment is evaluated as this:
int a[5] = 1
, which yields the following:
1, 0, 0, 0, 0
. We get 1
because a[2]=1
evaluates to true and is implicitly cast to 1 in the assignment series.
Second, the expression within the curly brackets is executed, which results in actually assigning 1 to the array at index 2.
You can experiment by compiling int a[5]=true;
and also int a[5]=a[3]=3;
and observing the results.
edit: I was wrong about the result of the assignment within the initialization list, that results in an integer that is the same as what was assigned.
edited Sep 14 at 14:40
answered Sep 13 at 23:01
Brandon Mantzey
11512
11512
This is a [language-lawyer] question, but this is not an answer that works with the standard, thus making it irrelevant. Plus there are also 2 much more in-depth answers available and your answer does not seem to add anything.
â Kami Kaze
Sep 14 at 8:19
1
"a[2]=1
evaluates to true and is implicitly cast to 1" is nonsense.a[2] = 1
evaluates to1
, there is no cast, and there is no assignment series. You claim thata[2]=1
is evaluated first, and then the expression in curly brackets is executed, which is alsoa[2]=1
. That makes no sense.
â melpomene
Sep 14 at 12:10
add a comment |Â
This is a [language-lawyer] question, but this is not an answer that works with the standard, thus making it irrelevant. Plus there are also 2 much more in-depth answers available and your answer does not seem to add anything.
â Kami Kaze
Sep 14 at 8:19
1
"a[2]=1
evaluates to true and is implicitly cast to 1" is nonsense.a[2] = 1
evaluates to1
, there is no cast, and there is no assignment series. You claim thata[2]=1
is evaluated first, and then the expression in curly brackets is executed, which is alsoa[2]=1
. That makes no sense.
â melpomene
Sep 14 at 12:10
This is a [language-lawyer] question, but this is not an answer that works with the standard, thus making it irrelevant. Plus there are also 2 much more in-depth answers available and your answer does not seem to add anything.
â Kami Kaze
Sep 14 at 8:19
This is a [language-lawyer] question, but this is not an answer that works with the standard, thus making it irrelevant. Plus there are also 2 much more in-depth answers available and your answer does not seem to add anything.
â Kami Kaze
Sep 14 at 8:19
1
1
"
a[2]=1
evaluates to true and is implicitly cast to 1" is nonsense. a[2] = 1
evaluates to 1
, there is no cast, and there is no assignment series. You claim that a[2]=1
is evaluated first, and then the expression in curly brackets is executed, which is also a[2]=1
. That makes no sense.â melpomene
Sep 14 at 12:10
"
a[2]=1
evaluates to true and is implicitly cast to 1" is nonsense. a[2] = 1
evaluates to 1
, there is no cast, and there is no assignment series. You claim that a[2]=1
is evaluated first, and then the expression in curly brackets is executed, which is also a[2]=1
. That makes no sense.â melpomene
Sep 14 at 12:10
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52307474%2fconfusion-about-array-initialization-in-c%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
31
The expression
a[2]=1
evaluates to1
.â tkausl
Sep 13 at 6:01
14
A very deep question. I wonder if the interviewer knows the answer themselves. I don't. Indeed ostensibly the value of the expression
a[2] = 1
is1
, but I'm not sure if you are are allowed to take the result of a designated initialiser expression as the value of the first element. The fact you've added the lawyer tag means I think we need an answer citing the standard.â Bathsheba
Sep 13 at 6:59
15
Well if that's their favourite question, you may well have dodged a bullet. Personally I prefer a written programming exercise (with access to a compiler and debugger) to be taken over a few hours rather than "ace" style questions such as the above. I could conject an answer, but I don't think it would have any real factual basis.
â Bathsheba
Sep 13 at 7:04
1
@Bathsheba I would do the opposite, as the answer here now answers both questions.
â Kami Kaze
Sep 13 at 7:36
1
@Bathsheba would be the best. Still I would give the credit for the question to OP, as he came up with the topic. But this is not for me to decide just what I feel would be "the right thing".
â Kami Kaze
Sep 13 at 7:39