[Bug c++/32016] sizeof(class) always a multiple of 4 on 32 bit machine
--- Comment #8 from bliss1940-bbs at yahoo dot com 2007-05-22 01:16 --- (In reply to comment #7) > On arm-elf structures are padded/aligned to a 4-byte boundary. This is a > "feature" of the ABI. The microsoft compiler obviously conforms to a different > ABI, which is why you get different results. Both are "correct". Thanks everyone for your time and trouble. I will go with the packed attribute. > Any code that relies on a particular structure layout or size is inherently > unportable. > EABI based targets (eg. arm-eabi) use a more conventional ABI. Unfortunately so. I think that structures with only chars would be portable if only compilers didn't pad the end of them. In fact my message classes are portable between Microsoft on the PC and GNU on the ARM except for the sizeof() thing. Defining inter-computer messages as classes with functions to manipulate the data inside is so very handy that I will continue to do it and will use the __attribute__((packed)) whenever necessary. Thanks again, Steve -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32016
[Bug c++/32016] sizeof(class) always a multiple of 4 on 32 bit machine
--- Comment #5 from bliss1940-bbs at yahoo dot com 2007-05-21 23:48 --- (In reply to comment #3) > Try: > struct a33 > { > struct Char1 a1; > struct Char1 a2; > }; > And see what size/offset the structs are at. Again this is an ABI issue Simply saying it's an ABI issue doesn't make it so. Please explain. MicrosoftGNU sizeof(a33)28 offsetof(a1) 00 offsetof(a2) 14 So what's the point? What would you expect? -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32016
[Bug c++/32016] sizeof(class) always a multiple of 4 on 32 bit machine
--- Comment #4 from bliss1940-bbs at yahoo dot com 2007-05-21 23:22 --- (In reply to comment #3) I'm using arm-elf. Thanks for the __attribute__((packed)). That does indeed remove the hole at the end. I think we should agree to disagree. You say it's an ABI issue but that seems impossible. All data members are chars and so can be at any address. If you are thinking of accessing whole structures at once, to copy for instance, then aligning on four byte addresses and accessing 4 bytes at a time could be efficient. But that's a compiler thing. Here's another way to look at it. The hole at the end can't affect the placement of the members in the struct. But it can affect the placement of the next struct in the array. So if you wanted to copy the structs 4 bytes at a time, putting them on 4 byte addresses would be a good idea. But accessing the data members can't be an alignment or ABI issue because the data members are chars and are accessed one byte at a time. In my second example, I used shorts. But here the alignment needs to be a multiple of 2 bytes. The only requirement for an address of a multiple of 4, is for using 4 byte operands. That's under the control of the compiler. Maybe we should just put this thing to bed. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32016
[Bug c++/32016] sizeof(class) always a multiple of 4 on 32 bit machine
--- Comment #2 from bliss1940-bbs at yahoo dot com 2007-05-21 22:18 --- (In reply to comment #1) I don't think I said GCC was in error, but just different. Maybe we can come to an agreement here, or maybe not. Let's see. I certainly would expect the ARM7 would prefer that 4 byte operands (ints, in this case) would be on addresses that are a multiple of 4, 2 byte operands (shorts) would want to be at addresses that are a multiple of two, and 1 byte operands (chars) have no alignment requirement so could go anywhere. I would expect to see that somewhere in the ABI. I would also expect to see that in the ABI for the Intel Pentium. I would not expect to see anything in the ABI concerning structs as the hardware knows nothing about them. They are the figment of the imagination of the compiler and programmer. So I would expect the Microsoft compiler targeting the PC and the GNU compiler targeting the ARM7 would align shorts and ints accordingly. Indeed, that's what I see when I examine the code. By the way, there is a good explanation of this on Wikipedia: It mentions that compilers usually arrange structs so the primitive objects they contain are at appropriate addresses. It explains why it's more efficient for the hardware, and it also explains how the GNU and Microsoft compilers do it when targeting the PC. So far, so good. http://en.wikipedia.org/wiki/Data_structure_alignment But the GNU compiler does something else. It makes the size of all structs a multiple of 4. I can think of one reason to do this. GNU compiled code can copy any struct by accessing memory 4 bytes at a time. That is, it can consider every struct to be composed of ints, and they will all be aligned correctly. If this is a good enough reason to make all structs a multiple of 4, then so be it. But it's confusing to mention the ABI, because the ABI has nothing to do with such things. And it's confusing to mention data alignment because it's an artificial requirement due to the way GNU copies structs. It has nothing to do with the struct data members as seen by the programmer. Here are some examples of structs compiled by Microsoft for the PC, and also compiled by GNU for the ARM7 (Analog Devices ADuC7024). These are the only compilers I currently have. Microsoft GNU struct Char1 { sizeof() == 1sizeof() == 4 char char1; }; struct Char2 { sizeof() == 2sizeof() == 4 char char1; char char2; }; struct Char3 { sizeof() == 3sizeof() == 4 char char1; char char2; char char3; }; struct Char4 { sizeof() == 4sizeof() == 4 char char1; char char2; char char3; char char4; }; struct Char5 { sizeof() == 5sizeof() == 8 char char1; char char2; char char3; char char4; char char5; }; Note that the above structs only have chars so by definition they are aligned correctly. But Microsoft's structs are only as large as necessary, GNU's are padded to a multiple of 4 bytes. This has nothing to do with the alignment of the data members as they have no particular alignment requirement. But as mentioned before, GNU can copy any struct accessing memory 4 bytes at a time. There is no other reason I can think of to pad these structs to a multiple of 4 bytes. Here are some structs that contain shorts (2 byte) to show what data alignment means to me, to the wiki, to the hardware, and I think also to most people. Microsoft GNU class Short1 { char char1; sizeof() == 4sizeof() == 4 short short1; }; class Short2 {sizeof() == 6sizeof() == 8 char char1; short short1; short short2; }; Here a hole is inserted after the char. This is required to align the 2 byte short on the appropriate address. Both Microsoft and GNU agree, as do most everyone. This is an ABI issue. But notice the second class, Short2. I added a second short which will automatically have the correct alignment because it immediately follows another short. It doesn't require padding to be aligned correctly. Everyone agrees on this. But the Microsoft compiler gives the size as 6. As always, the GNU compiler adds two pad bytes to make the struct have a size which is a multiple of 4. But the struct doesn't require this. Neither would a following struct in an array of structs, as long as the compiler didn't try accessing these structs as if they contained ints. The only alignment requirement obvious to the programmer is that the shorts be on addresses that are a multiple
[Bug c++/32016] New: sizeof(class) always a multiple of 4 on 32 bit machine
GCC seems to have a "feature" where it always pads the end of classes (or structs) to make the class size as reported by sizeof() be a multiple of 4 bytes when targeting a 32 bit machine. This isn't a data alignment issue as the problematic classes contain nothing but chars. It seems to be simply arbitrary with no practical use except to provide pitfalls for programmers. It makes the code non-portable if sizeof() is used and thus makes it cumbersome to define and manipulate inter-computer messages. I've always believed I could define a class or struct that would have the size I wanted with no holes if I took data alignment into consideration. That seems to be the case with other compilers, and is the case with GCC when targeting an 8 bit machine, but alas, it doesn't work on the ARM7. I can work around this by making my messages have a size that is a multiple of 4, but it doesn't seem this should be necessary. Hopefully I'll never have to use a 64 bit machine. Just to make myself clear, this isn't a data alignment thing. There are no holes between data members. All data members are chars. The hole is at the end, and the only reason for the hole that I can figure is to make sizeof() less useful. -- Summary: sizeof(class) always a multiple of 4 on 32 bit machine Product: gcc Version: 4.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: bliss1940-bbs at yahoo dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32016
[Bug target/17705] Testing a bool using true doesn't work
--- Additional Comments From bliss1940-bbs at yahoo dot com 2004-09-29 03:21 --- (In reply to comment #1) > Could attach the preprocessed source? I have discovered that the problem was in my code. The compiler is okay. Please cancel this bug report. Steve Bliss -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17705