Binary serialization of variable length data and zero length arrays, is it safe?

Go To StackoverFlow.com

3

I did some research but cannot find a definite approval or disapproval.

What I want is, a fixed size structure + variable length part, so that serialization can be expressed in simple and less error prone way.

struct serialized_data
{
    int len;
    int type;
    char variable_length_text[0];
};

And then:

serialize_data buff = (serialize_data*)malloc(sizeof(serialize_data)+5);
buff->len=5;
buff->type=1;
memcpy(buff->variable_length_text, "abcd", 5);

Unfortunately I can't find if MSVC, GCC, CLang etc., are ok with it.

Maybe there is a better way to achieve the same?

I really don't want those ugly casts all around:

memcpy((char*)(((char*)buffer)+sizeof(serialize_data)), "abcd", 5);
2012-04-04 21:34
by Coder
That should be char variable_length_text[1];, but yes, there is surely a better way to achieve the same - ildjarn 2012-04-04 21:37
Pick a language. Are you interested in C++ or C - Robᵩ 2012-04-04 21:40
You will probably find this article useful. Doesn't answer the portability question but does give some insight into this pattern http://blogs.msdn.com/b/oldnewthing/archive/2004/08/26/220873.asp - JaredPar 2012-04-04 21:40
@ildjarn shouldn't the 0 length array be legal as of C99 - JaredPar 2012-04-04 21:41
@JaredPar : Yes, but this is tagged c++ as well - ildjarn 2012-04-04 21:42
No, char variable_length_text[1]; reserves 1 byte of memory inside structure, [0] does not - Coder 2012-04-04 21:42
@ildjarn oh, so C++ doesn't allow for 0 length arrays? Sorry, not very up to date on the C++ spec - JaredPar 2012-04-04 21:43
It's a C++ project, but I need to use POD data - Coder 2012-04-04 21:43
@JaredPar: Zero-length arrays are not permitted in C99. You're thinking of flexible array members, defined without a length like char member[];. They must occur as the last member in a struct, and they're only permitted in C99. Not all compilers (notable MSVC) are C99-compliant, so it's more portable to use a 1-length array, although that complicates size calculations - Adam Rosenfield 2012-04-04 21:43
The 0 should be rejected (or, at least, warned about in any standard-compliant mode of compilation). Use a 1 instead of the 0 and you're dealing with the 'struct hack' (search term). C99 has 'flexible array members' which would work here - Jonathan Leffler 2012-04-04 21:53


2

This program is using a zero length array. This is not C but a GNU extension.

http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

A common idiom in C89, called the struct hack, was to use:

struct serialized_data
{
    int len;
    int type;
    char variable_length_text[1];
}; 

Unfortunately its common use as a flexible array is not strictly conforming.

C99 comes with something similar to perform the same task: a feature called the flexible array member. Here is an example right from the Standard (C99, 6.7.2.1p17)

struct s { int n; double d[]; };
int m = 12;  // some value
struct s *p = malloc(sizeof (struct s) + sizeof (double [m]));
2012-04-04 21:50
by ouah
Can I use C99 way and be safe that it will work on MSVC7/8/9, GCC and Clang - Coder 2012-04-04 22:06
C99 is supported by gcc and clang but not by MSVC. The struct hack although not strictly conforming is pretty common and should be considered for C89 compilers - ouah 2012-04-04 22:09
Ads