Bug 20184 - assignment error in inline function
Summary: assignment error in inline function
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.3.4
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-02-24 10:13 UTC by Dirk Clemens
Modified: 2005-07-23 22:49 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dirk Clemens 2005-02-24 10:13:37 UTC
// Postet by dirk@cle-mens.de
// Compiler Error found:
//	gcc (GCC) 3.3.4 (pre 3.3.5 20040809)
//	under SuSE Linux kernel 2.6.8-24.10-default (i386)
//
// If this littel programm is compiled with the option -O2
// the assignment in the inline function data::data() is wrong.
// If I remove the 'inline' the result is correct.
//
// Compiled with: g++ -Wall error.cpp
//		-> OK, printout = 00000000:00000000
//
// Compiled with: g++ -Wall -O2 error.cpp
//		-> ERROR, printout = 00000000:bffff408
//
// Compiled with: g++ -Wall -O2 error.cpp,, but without 'inline'
//		-> OK, printout = 00000000:00000000
//

#include <stdlib.h>
#include <stdio.h>

typedef unsigned int uint32;
typedef unsigned long long uint64;

class data
{
 public:
    uint32 lo;
    uint32 hi;

    data ( uint32 num );
};

inline data::data ( uint32 num ) { *(uint64*)this = num; }


int main()
{
    printf("sizeof(uint32)=%d\n",sizeof(uint32));
    printf("sizeof(uint64)=%d\n",sizeof(uint64));
    printf("sizeof(data)  =%d\n",  sizeof(data));

    uint32 tab[] = { 0,0,0,0,0 };
    uint32 *p = tab;

    data D = data(*p++);
    printf("%08x:%08x\n",D.hi,D.lo);
}
Comment 1 Falk Hueffner 2005-02-24 10:21:27 UTC
You are accessing an object of type "class data" via a pointer to uint64, which
is not allowed in C++. So this is invalid.
Comment 2 Dirk Clemens 2005-02-24 10:35:15 UTC
The cast is, perhaps, illegal. But after the cast there is an assignment from
uint32 to uin64. And that assignment does not work.
Comment 3 Dirk Clemens 2005-02-24 10:38:38 UTC
The reinterpret_cast solves the problem with this old code.

inline data::data ( uint32 num ) { *reinterpret_cast<uint64*>(this) = num; }
Comment 4 Falk Hueffner 2005-02-24 10:57:58 UTC
(In reply to comment #2)
> The cast is, perhaps, illegal.

No, the cast is fine. The access is bad.

> But after the cast there is an assignment from
> uint32 to uin64. And that assignment does not work.

Since this has undefined behaviour, it cannot possibly "not work".
Comment 5 Falk Hueffner 2005-02-24 10:58:57 UTC
(In reply to comment #3)
> The reinterpret_cast solves the problem with this old code.
> 
> inline data::data ( uint32 num ) { *reinterpret_cast<uint64*>(this) = num; }

That is pure luck; the code is still invalid.