[LLVMdev] MS C++ gives error C2371 on this code while (obviously)gcc compiles it fine

Jay Freeman (saurik)
Thu, 02 Oct 2008 19:01:45 -0000

Those rules only apply to if and switch statements. (Yes, this is insane,
but true.) The entire section you are quoting from, 6.4, is titled
"Selection statements [stmt.select]", which specifically covers these
two
cases. A for is an iteration statement, not a selection statement.

So, if you read 6.5.3p1 (which is actually about for statements) it states
that a for loop is rewritten as a while loop where names defined by the
for-init-statement are declared in the declaration space of the condition of
the while statement. Then, if you read 6.5.1p2 it states:

<quote>
-2- When the condition of a while statement is a declaration, the scope of
the variable that is declared extends from its point of declaration
(basic.scope.pdecl) to the end of the while statement. A while statement of
the form

while (T t = x) statement

is equivalent to
label:
{                               //  start of condition scope
    T t = x;
    if (t) {
	statement
	goto label;
    }
}                               //  end of condition scope
</quote>

Unlike the case of the for statement, there are no subsequent rules that
redefine where this declaration is scoped. This rewrite means that the rules
you cite in 6.4 simply do not apply: for loops don't cause conditions in
selection statements, and therefore should not be scoped in that manner.
They almost are, but the rules for while statements actually force the
declaration outside of the condition of the if statement.

You are correct, though, that gcc should be emitting an error in the case of
the if statement. Naughty gcc.

-J

--------------------------------------------------
From: "Argiris Kirtzidis" <akyrtzi at gmail.com>
Sent: Thursday, October 02, 2008 11:33 AM
To: "LLVM Developers Mailing List" <llvmdev at cs.uiuc.edu>
Subject: Re: [LLVMdev] MS C++ gives error C2371 on this code
while(obviously)gcccompiles it fine

> Jay Freeman (saurik) wrote:
>> gcc is correct. According to the ISO specification, the
>> for-init-statement
>> is supposed to inject any variable names into the same declarative
scope
>> as
>> the condition of an equivalent restructuring of the loop in the form of
a
>> while statement, which in turn fronts the declaration to an extra scope
>> that
>> surrounds the /entire/ loop construct. VC++ seems to be scoping the
>> variables as if they were /inside/ of the loop and not creating this
>> extra
>> scope. Frowny. -J
>>
>
> Actually, gcc is wrong and VC++ got it right.
> From the C++ standard, 6.4p3:
>
>> A name introduced by a declaration in a condition (either introduced
>> by the type-specifier-seq or the declarator of the
>> condition) is in scope from its point of declaration until the end of
>> the substatements controlled by the condition. If the
>> name is re-declared in the outermost block of a substatement
>> controlled by the condition, the declaration that re-declares
>> the name is ill-formed.
>
> Which gives us:
>
> while (int x=0) {
>    int x=0;   // error: redeclaration, clashes with condition
> }
>
> Both gcc and VC++ emit a compilation error for the above.
>
> Then the standard says this, 6.5.3p1:
>
>> names declared in the for-init-statement are in the same
>> declarative-region as those declared in the condition
>
> So names inside the 'for' loop clash with both the condition and
the
> for-init-statement:
>
> for (int x=0;;) {
>    int x=0;   // error: redeclaration, clashes with for-init-statement
> }
>
> but gcc, incorrectly, does not emit a compilation error.
>
> And while we are on the subject, gcc is also wrong on this one:
>
> if (int x=0) {
>    int x=0;   // error: redeclaration, but gcc does not emit any errors.
> }
>
>
> -Argiris
>
>> --------------------------------------------------
>> From: "Yanko" <yhdezalvarez at gmail.com>
>> Sent: Thursday, October 02, 2008 8:12 AM
>> To: <llvmdev at cs.uiuc.edu>
>> Subject: [LLVMdev] MS C++ gives error C2371 on this code while
>> (obviously)gcc compiles it fine
>>
>> ...
>>
>>> makes the code compilable by MS C++. But as a curiosity (and I
really
>>> don't know the answer because I can barely read C++): Which
compiler
>>> got it right?
>>>
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>
>>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>