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

View: New views
11 Messages — Rating Filter:   Alert me  

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

by Yanko Hernández Álvarez :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Taken from tools/llvmc2/CompilationGraph.cpp:
...
    for (typename C::const_iterator B = EdgesContainer.begin(),
           E = EdgesContainer.end(); B != E; ++B) {
      const Edge* E = B->getPtr();
...

MS C++ compiler (VS 2008) gives:
...
CompilationGraph.cpp
..\..\..\llvm\tools\llvmc2\CompilationGraph.cpp(58) : error C2371:
'E' : redefinition; different basic types
        ..\..\..\llvm\tools\llvmc2\CompilationGraph.cpp(57) : see
declaration of 'E'
...

While GCC compiles it fine. (I'm assuming it does, 'cause almost
everyone here uses gcc)

Changing the code to
...
    for (typename C::const_iterator B = EdgesContainer.begin(),
           End = EdgesContainer.end(); B != End; ++B) {
      const Edge* E = B->getPtr();
...
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@...         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

Re: MS C++ gives error C2371 on this code while (obviously)gcc compiles it fine

by Jay Freeman (saurik) :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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

--------------------------------------------------
From: "Yanko" <yhdezalvarez@...>
Sent: Thursday, October 02, 2008 8:12 AM
To: <llvmdev@...>
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@...         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

Re: MS C++ gives error C2371 on this code while (obviously)gcc compiles it fine

by OvermindDL1 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Oct 2, 2008 at 11:34 AM, Jay Freeman (saurik) <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
This can be changed in the project settings for a VC++ project.  I think it was called something like "Enforce for loop conformance" or so...
This is something I always change though.

_______________________________________________
LLVM Developers mailing list
LLVMdev@...         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

Re: MS C++ gives error C2371 on this code while (obviously)gcc compiles it fine

by Sherief N. Farouk :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> This can be changed in the project settings for a VC++ project. 
> I think it was called something like "Enforce for loop conformance" or
so...
> This is something I always change though.

Nope. The for loop conformance option fixes a VC++6 "feature" where
identifiers declared in the for loop initialization are visible after the
for loop's body.
VC6:
for(int i = 0; i < 5; ++i)
{
    ...
}
std::cout << i; //Prints "5"

This is illegal in ISO C++, and by default in VC8 and beyond (maybe earlier,
but I moved from 6 to 8). The VC++ option enable VC6-like behavior for
legacy code. What Jay pointed out is Yet Another For Scope FUBAR.

To the VC team's credit, though, "inline any suitable" is pure awesome.

- Sherief


_______________________________________________
LLVM Developers mailing list
LLVMdev@...         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

Re: MS C++ gives error C2371 on this code while (obviously)gcc compiles it fine

by Argiris Kirtzidis :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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@...>
> Sent: Thursday, October 02, 2008 8:12 AM
> To: <llvmdev@...>
> 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@...         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>  
_______________________________________________
LLVM Developers mailing list
LLVMdev@...         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

Re: MS C++ gives error C2371 on this code while (obviously)gcc compiles it fine

by OvermindDL1 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Ah, interesting, have not ran across that before (as I always strive to never use the same name as any scope previously), but rather interesting that GCC gets it wrong while VC++ gets it right, kind of a switch.

And yes, that switch I mentioned is for VC6 style in VC7.1 (what I use), you have to switch it to make it conformant, nice to hear VC8 does it correctly by default now.

On Thu, Oct 2, 2008 at 12:33 PM, Argiris Kirtzidis <akyrtzi@...> wrote:
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@...>
> Sent: Thursday, October 02, 2008 8:12 AM
> To: <llvmdev@...>
> 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@...         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>
_______________________________________________
LLVM Developers mailing list
LLVMdev@...         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev


_______________________________________________
LLVM Developers mailing list
LLVMdev@...         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

Re: MS C++ gives error C2371 on this code while (obviously)gcc compiles it fine

by Jay Freeman (saurik) :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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@...>
Sent: Thursday, October 02, 2008 11:33 AM
To: "LLVM Developers Mailing List" <llvmdev@...>
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@...>
>> Sent: Thursday, October 02, 2008 8:12 AM
>> To: <llvmdev@...>
>> 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@...         http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>
>>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev@...         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
_______________________________________________
LLVM Developers mailing list
LLVMdev@...         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

Re: MS C++ gives error C2371 on this code while (obviously)gcc compiles it fine

by Argiris Kirtzidis :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Jay Freeman (saurik) wrote:
> 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.
>  

See 6.4p2: "The rules for conditions apply both to selection-statements
and to the for and while statements"

> 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.
>  

Again, see the 6.4p2 reference. 'while' statements should also follow
this rule:

> 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.

gcc correctly scopes the declaration inside the while statement:

while (int x=0) {
   int x=0;   // error: redeclaration.
}


-Argiris

> You are correct, though, that gcc should be emitting an error in the case of
> the if statement. Naughty gcc.
>
> -J
>  
_______________________________________________
LLVM Developers mailing list
LLVMdev@...         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

Re: MS C++ gives error C2371 on this code while (obviously)gcc compiles it fine

by Jay Freeman (saurik) :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Fair enough, you win this round. ;P (Which actually makes me happy as that
makes things a lot more consistent and sensible.) -J

--------------------------------------------------
From: "Argiris Kirtzidis" <akyrtzi@...>
Sent: Thursday, October 02, 2008 12:32 PM
To: "LLVM Developers Mailing List" <llvmdev@...>
Subject: Re: [LLVMdev] MS C++ gives error C2371 on this code while(obviously)gcccompiles it fine

...
> See 6.4p2: "The rules for conditions apply both to selection-statements
> and to the for and while statements"
...
> -Argiris

_______________________________________________
LLVM Developers mailing list
LLVMdev@...         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

Re: MS C++ gives error C2371 on this code while (obviously)gcc compiles it fine

by Mike Stump :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Oct 2, 2008, at 11:52 AM, OvermindDL1 wrote:
> 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.
> }

I filed http://gcc.gnu.org/PR37728 for this.
_______________________________________________
LLVM Developers mailing list
LLVMdev@...         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

Re: MS C++ gives error C2371 on this code while (obviously)gcc compiles it fine

by Argiris Kirtzidis :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

BTW, here is the relevant bug report:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=2288

> *Opened:* 2001-03-14

Hmm.. that doesn't look good :-)

-Argiris


Jay Freeman (saurik) wrote:

> Fair enough, you win this round. ;P (Which actually makes me happy as that
> makes things a lot more consistent and sensible.) -J
>
> --------------------------------------------------
> From: "Argiris Kirtzidis" <akyrtzi@...>
> Sent: Thursday, October 02, 2008 12:32 PM
> To: "LLVM Developers Mailing List" <llvmdev@...>
> Subject: Re: [LLVMdev] MS C++ gives error C2371 on this code while(obviously)gcccompiles it fine
>
> ...
>  
>> See 6.4p2: "The rules for conditions apply both to selection-statements
>> and to the for and while statements"
>>    
> ...
>  
>> -Argiris
>>    
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev@...         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>  
_______________________________________________
LLVM Developers mailing list
LLVMdev@...         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
LightInTheBox - Buy quality products at wholesale price!