Bug or undefined behaviour?

Bug or undefined behaviour?


In integrating a third party C library into our product, I came across a fragment of code where inside a function, a struct is defined that includes a variable length array, the length of which depends on a parameter of that function. Incrementing a pointer s to such a struct works differently depending on whether you write ++s or s += 1 on the one hand, or s = s + 1 on the other hand. The code is similar to the following:

#include <stdio.h>
typedef struct {
    int   ndim;
    void  *firstmember, *lastmember;
} Container;
#define N_MEMBERS 5
#define TYPEDEFMEMBER(t)       
    typedef struct {            
        int    n;               
        double data[t->ndim];   
    } Member
void init(Container *t) {
    Member *first, *last;
    first = malloc(N_MEMBERS * sizeof(Member));
    last  = first + N_MEMBERS - 1;
    t->firstmember = first;
    t->lastmember  = last;
void process(Container *t) {
    Member *s, *first, *last;
    first = t->firstmember;
    last  = t->lastmember;
    printf("t->ndim = %d, with ++s:n", t->ndim);
    for (s = first; s <= last; ++s) {
        printf("s: %pn", s);
    printf("t->ndim = %d, with s += 1:n", t->ndim);
    for (s = first; s <= last; s += 1) {
        printf("s: %pn", s);
    printf("t->ndim = %d, with s = s + 1:n", t->ndim);
    for (s = first; s <= last; s = s + 1) {
        printf("s: %pn", s);
void destroy(Container *t) {
    t->firstmember = 0;
    t->lastmember  = 0;
int main(void) {
    Container container;
    Container *containerp = &container;
    container.ndim = 1;
    container.ndim = 3;
    return 0;

On linux on x86_64, both ++s and s += 1 increase s by 8 independent of the value of t->ndim, whereas s = s + 1 increases s by sizeof(Member) == 8 + t->ndim * 8. Clearly the latter is intended. This was compiled icc Version Build 20121010 by the way, without any further options - just icc foo.c && ./a.out.

I'm not entirely sure this code is legal; but I feel that either icc should refuse to compile it, or be consistent between the ways of incrementing s.


Erik Postma

4 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Not sure if I can edit my original post - I notice that the line continuation characters in the macro definition of TYPEDEFMEMBER do not show up. There should be a backslash at the end of four lines there - the definition ends with the line "} Member". Similarly but less crucially, there should be backslashes in the printf format strings. Sorry for the confusion.


What result do you get with the gcc compiler?

The compiler you are using is a bit old.  The latest one that you could try is icc Build 20130313.


Hi Mark,

Thanks for your response. gcc does the intended thing: it increases s by sizeof(Member) for each of the methods of increasing s.

Indeed, I have found out since yesterday that this is an undocumented (mis?)feature of gcc specifically; clang, for example, describes it at http://clang.llvm.org/docs/UsersManual.html#intentionally-unsupported-gc... as:

clang does not support the gcc extension that allows variable-length arrays in structures. This is for a few reasons: one, it is tricky to implement, two, the extension is completely undocumented, and three, the extension appears to be rarely used.

I guess this means that the obvious solution for you guys is to just refuse to compile it (which wouldn't solve the issue for me, but that's life I guess).


Leave a Comment

Please sign in to add a comment. Not a member? Join today