I am porting code from ew and gcc to keil uvision arm compiler (Arm compiler 5.06 update 1 build 61).
Both ew and gcc allow me to the following:
struct header { uint32_t chksum; uint8_t id; uint8_t size; /* This many bytes follow immediately */ uint8_t payload[]; /* Allows for easy access to the payload of variable size packets */ } struct datapacket { struct header header; uint64_t timestamp; uint8_t data[]; }
Is it possible to something similar with the arm compiler? I have enabled the C99 option which allows for empty array declaration but it does not seem to accept that the header has the empty array member payload[].
Thank you guys,
As I stated in the first message: this is allowed both in ew (Embedded workbench) and GCC. It is handy and helpful when dealing with data "on the wire". The idea being that the transport layer only has to know about the header structure and has easy access to the payload through the payload array, which is is variable sized. The application layer has to generate it's data array and prepend the header and then only pass a pointer to the header to the transport layer. Somehting like:
struct header { uint32_t chksum; uint8_t id; uint8_t size; /* This many bytes follow immediately */ uint8_t payload[]; /* Allows for easy access to the payload of variable size packets */ }; struct datapacket { struct header header; <<< ERROR HERE ! uint64_t timestamp; uint8_t data[2]; }; extern void transport_calcchecksum( struct header * hdr ); extern void transport_ship( struct header * hdr ); void shipdata( void ) { extern uint64_t now; /* Global time */ extern uint8_t const dataid; /* packet id of data packets */ struct datapacket mydata = { {0, dataid, sizeof( mydata ) }, now, { 1, 2} }; transport_calcshecksum( &mydata.header ); transport_ship( &mydata.header ); }
Something similar goes when receiving data on the wire, i.e. the transport layer only knows about the struct header with its variable sized payload.
I am also aware that there are other ways to do this but this is the way the code is and I have to keep it compilable with both EW and GCC.
I did not expect this to be supported since I have not found any reference to any "hidden" switch/option on the compiler but I thought I would ask before I would start rewriting into something that works on all compilers.
Hamis: It is possible in the same way as the empty arrays are allowed at the end of structures. The empty array at the end is just an easy reference to the data that follows and has zero size. Please look at GCC and EW which allow this kind of notation.
Please look at GCC and EW which allow this kind of notation.
That is truly horrible.
I've just tried a few experiments with GCC and these structures. It appears to accept it (which did surprise me), but after that it does what I would expect of it, and that's not very useful!
I created an instance of one, set the timestamp field and then filled in the header with three bytes of 'payload' and the timestamp field got chomped.
Nope, I'll definitely stick to the KISS principle and avoid this type of thing as much as possible.
I can understand why this arrangement might be useful. I would have to refer back to standards to see whether it is strictly legitimate though.
would have to refer back to standards to see whether it is strictly legitimate though.
It quite strictly is not. C99 forbids VLAs in nested structs.