Hi, I'm using your keil IDE for stm32 programming.To improve the readability and safty of my code, I always like to use enum type. Sometimes I need to transfer data from the mcu to my pc, and in some wireless app, the number of bytes that can be transfered is fixed. I want to use struct and enum for the transfered data, so I need to strictly defined the sizeof my user-defined enum type. That is, I want to specify the underlying type of the enum type. But this is not available in the iso 2003 standard. I've tested that the default underlying type has the smallest sizeof(enum_type_name) that can represent all the enumerator values defined in the enumeration. But you know, things Without Any Warranty is not good. So I wrote this e-mail to suggest that mdk C++ compiler should support the new c++ standard.
last, for the explicitness of what I mean: I need the define an enum type like this, enum Direction: char{ /* underlying type is char, so sizeof(Direction) is 1 */ LEFT, RIGHT }; this code is valid when i wrote it in visual studio, but it cannot be compiled use mdk.
you can refer to “7.2 Enumeration declarations” of the doc ISO/IEC 14882 - Information technology — Programming languages — C++
sincerely, Pony279 from china.
But that doesn't solve the issues with padding in structures.
It really is way (!) better to write an import/export function where you pack/unpack your data into binary buffers for transfer. Then you can move the data between whatever architectures you want without getting hurt by the individual compilers.
Google, "Serialisation" (or "Serialization").
eg, see: en.wikipedia.org/.../Serialization
www.keil.com/.../search.asp
your are right, I never thought about padding in structures before,
function is more generic, while I thought structure could make my code more readable and easy to use,
the "__attribute__((packed))" can be use to turn off padding with gcc compiler, but this is not a generic way,
maybe I should write class and member function to pack/unpack my data into binary buffers for transfer.
thanks.
to Andrew Neil,
Thanks. It is a good way to solve the problem of padding in struct.
----------------------------------------------------------------------
from en.wikipedia.org/.../Serialization:
"In computer science, in the context of data storage and transmission, serialization is the process of converting a data structure or object state into a format that can be stored (for example, in a file or memory buffer, or transmitted across a network connection link) and "resurrected" later in the same or another computer environment."
"C and C++ do not provide direct support for serialization. It is however possible to write your own serialization functions, since both languages support writing binary data."
Padding is not the problem!
"__attribute__((packed)) can be use to turn off padding with gcc compiler, but this is not a generic way"
When compilers insert padding, they do it for good reasons. Turning it off is liable to cause problems...
Padding should only be removed during transfers or when you need to store a long array and really do need to save the bytes of RAM.
Removal of padding requires much more from the code (potentially making code much larger) while also slowing down the code because of multiple memory accesses to glue together low and high part of data that spans alignment borders.
Thanks, I see,
from c-faq.com/.../padding.html : " If you're worried about wasted space, you can minimize the effects of padding by ordering the members of a structure based on their base types, from largest to smallest. "
So I wonder whether correctly ordering the members of a structure avoids sturcture padding completely.
"So I wonder whether correctly ordering the members of a structure avoids sturcture padding completely."
Only in some situations.
If you have 3 byte variables and then a 32-bit variable, then a compiler for a normal 32-bit processor will insert a pad byte to get the 32-bit variable to start at offset 4. If you have that 32-bit integer first, then the struct will still get a pad byte last, to make sure that the full struct is n*4 byte large in case you use it in an array.
Starting with all large variable types and going to smaller types tends to minimize the amount of pad - but is not enough to guarantee that no pad is needed. And different architectures have different rules for how much padding is needed because of differences in cost for unaligned access.
I wonder how you could possibly justify starting that sentence with "So", indicating it was some kind of conclusion of the one you quoted. It's not; and by a quite a margin.
First of all, "correctly" has no place in that sentence. There's neither a correct, nor an incorrect ordering to be found here. All orderings are equally correct, period.
As to "avoiding [...] padding completely": do you really believe the C FAQ would have said "minimize" if what they actually meant was "avoid completely"?
some cpus dont have the bug like t 51 and t x86. theres a patch for the bug. use #pragma pack. its good.
"some cpus dont have the bug like t 51 and t x86. theres a patch for the bug. use #pragma pack. its good."
Trolls in the thread.
"Trolls in the thread."
yea. push of broeker.
The need for padding have nothing with "bug" to do - neither for compiler nor processors.
The old 8088 processor didn't need padding because it had an 8-bit memory interface so always had to read data a byte at a time. The 8086 had a 16-bit memory interface. The x86 then continued with 32-bit, 64-bit, ... memory interfaces and added internal caches with cache-lines where the processor core receives maybe 8, 16 or even 32 bytes (not bits) from the cache.
So unaligned data that spans two external memory words or spans two cache lines will result in a significant slowdown of the processor.
Many processors don't even have a memory controller that supports multiple memory accesses to retrieve and glue together unaligned data, forcing the processor to generate code that performs multiple memory reads followed by logical shifts/oring to combine the data. And even more extra instructions when writing back unaligned ata, since the low memory word has to be read in and be partly modified and saved, then the high memory word has to be read in and partly modified before written back.
So while a 8051 chip don't need padding, it don't need padding because the compiler must always generate code to perform many memory reads/writes when working with larger data types. Not to mention the amount of instructions that is needed for performing larger add/sub/mul/div/shift/... with integers wider than 8 bits.
But even when there are no padding involved, raw structs are still very problematic to transfer - different architectures have different byte orders for data types larger than a single byte. And an architecture needn't even have two-complement binary storage format for integers, not to mention the binary storage format for floating point, pointers etc.
Serialization code that packs/unpacks the data is really the only route to remove the influence of compiler or target architecture when moving data between different architectures. And in most situations, the cost (code size, execution time, ...) are very low compared to the advantages of having a documented intermediate format that isn't coupled to compiler or processor.
So when you use the term "bug" here, you are either a troll or making statements you don't understand the meaning of.
or both.