Jump to content

  • Log In with Google      Sign In   
  • Create Account

#ActualMatias Goldberg

Posted 01 January 2013 - 01:18 PM

I'm with Bregma's interpretation.
• an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union)
My understanding, it is saying that if Bar is derived from Foo, you can cast Foo to Bar and still access it correctly. Also the clause seems to allow for unions & typedefs.
• the dynamic type of the object
My interpretation here it is saying that it could be defined behavior because they're both of the same type (Commands::Type). However like Bregma said, this clause does not apply because you went into undefined behavior land when casting Foo into Command.

Implementation wise (so far all systems I know) will work as expected because the compiler can see you casted Foo into Command. However, compile some code with -fstrict-aliasing where the compiler can't see in it's scope you did that, and you'll run into trouble, for example this:
void test( Command *cmd, Foo *foo )
{
    cmd->id = 1;
    print( foo->id );
}

//Meanwhile in another compilation unit...
int main( /* ...args.. */ )
{
    Foo foo;
    foo->id = 3;
    foo->value = 0;
    test( reinterpret_cast<Command*>(foo), foo );
    return 0;
}

Note that MSVC is too relaxed on aliasing, so you're gonna need to test it into some other compiler which follows aliasing rules more strictly (like GCC with -fstrict-aliasing)

#1Matias Goldberg

Posted 01 January 2013 - 01:16 PM

I'm with Bregma's interpretation.
• an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union)
My understanding, it is saying that if Bar is derived from Foo, you can cast Foo to Bar and still access it correctly. Also the clause seems to allow for unions.
• the dynamic type of the object
My interpretation here it is saying that it could be defined behavior because they're both of the same type (Commands::Type). However like Bregma said, this clause does not apply because you went into undefined behavior land when casting Foo into Command.

Implementation wise (so far all systems I know) will work as expected because the compiler can see you casted Foo into Command. However, compile some code with -fstrict-aliasing where the compiler can't see in it's scope you did that, and you'll run into trouble, for example this:
void test( Command *cmd, Foo *foo )
{
    cmd->id = 1;
    print( foo->id );
}

//Meanwhile in another compilation unit...
int main( /* ...args.. */ )
{
    Foo foo;
    foo->id = 3;
    foo->value = 0;
    test( reinterpret_cast<Command*>(foo), foo );
    return 0;
}

Note that MSVC is too relaxed on aliasing, so you're gonna need to test it into some other compiler which follows aliasing rules more strictly (like GCC with -fstrict-aliasing)

PARTNERS