Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hiding name of int variable in c++

Out of curiosity, I've tried this code, resulting from an interview question[*]

int main(int argc, char *argv[])
{
    int a = 1234;
    printf("Outer: %d\n", a);
    {
        int a(a);
        printf("Inner: %d\n", a);
    }
}

When compiled on Linux (both g++ 4.6.3 and clang++ 3.0) it outputs:

Outer: 1234
Inner: -1217375632

However on Windows (VS2010) it prints:

Outer: 1234
Inner: 1234

The rationale would be that, until the copy-constructor of the second 'a' variable has finished, the first 'a' variable is still accessible. However I'm not sure if this is standard behaviour, or just a(nother) Microsoft quirk.

Any idea?

[*] The actual question was:

How you'd initialise a variable within a scope with the value of an identically named variable in the containing scope without using a temporary or global variable?

{
    // Not at global scope here
    int a = 1234;
    {
        int a;
        // how do you set this a to the value of the containing scope a ?
    }
}
like image 802
rippeltippel Avatar asked May 23 '12 16:05

rippeltippel


1 Answers

How you'd initialise a variable within a scope with the value of an identically named variable in the containing scope without using a temporary or global variable?

Unless the outer scope can be explicitly named you cannot do this. You can explicitly name the global scope, namespace scopes, and class scopes, but not function or block statement scopes.


C++11 [basic.scope.pdecl 3.3.2 p1 states:

The point of declaration for a name is immediately after its complete declarator (Clause 8) and before its initializer (if any), except as noted below. [ Example:

int x = 12;
{ int x = x; }

Here the second x is initialized with its own (indeterminate) value. —end example ]

MSVC correctly implements this example, however it does not correctly implement this when the initializer uses parentheses instead of assignment syntax. There's a bug filed about this on microsoft connect.

Here's an example program with incorrect behavior in VS as a result of this bug.

#include <iostream>

int foo(char) { return 0; }
int foo(int) { return 1; } 

int main()
{
    char x = 'a';
    {
        int x = foo(static_cast<decltype(x)>(0));
        std::cout << "'=' initialization has correct behavior? " << (x?"Yes":"No") << ".\n";
    }
    {
        int x(foo(static_cast<decltype(x)>(0)));
        std::cout << "'()' initialization has correct behavior? " << (x?"Yes":"No") << ".\n";
    }
}

C++ includes the following note.

[ Note: Operations involving indeterminate values may cause undefined behavior. —end note ]

However, this note indicates that operations may cause undefined behavior, not that they necessarily do. The above linked bug report includes an acknowledgement from Microsoft that this is a bug and not that the program triggers undefined behavior.

Edit: And now I've changed the example so that the object with indeterminate value is only 'used' in an unevaluated context, and I believe that this absolutely rules out the possibility of undefined behavior on any platform, while still demonstrating the bug in Visual Studio.

like image 57
bames53 Avatar answered Oct 13 '22 01:10

bames53