[csw-maintainers] need help with C++ cmopile problem

James Lee james at opencsw.org
Sun Jun 13 16:38:58 CEST 2010


On 13/06/10, 13:34:07, Ben Walton <bwalton at opencsw.org> wrote regarding Re:
[csw-maintainers] need help with C++ cmopile problem:

> > typedef struct fooo{
> > int filler;
> > int *testing;
> > } foostruct;

> This was my first thought too, but I hesitated to send it as I wasn't
> sure about it[1].  The C compiler would most likely turn 'int
> testing[]' into 'int *testing' I think since defining a struct of
> unknown (variable) size wouldn't be useful.  But, 'int *' can be
> different than 'int []' as the array wouldn't require a de-reference
> to access to the contents.  Will Phil need to look at how the
> structure is used to ensure it's treated as 'int *' even though
> originally declared as 'int []' ?

It does handle a pointer but it difference where the pointer is
stored.  So yes your are right, it does depend how it's used,
as written the the structure is no use and can only be used to
point to another piece of memory.  "foostruct foo" isn't useful;
"foostruct foo *" is how to use.

The way to get CC to accept the array is to allocate 1 unit of
storage:

typedef struct foo {
    int length;
    int array[1];
}  foostruct;

This will work and just wastes 4 bytes.  "int array[0];" is a
variation I've often seen, which is accepted by gcc but not cc.



#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int length;
    int array[1];
} foo_t;

typedef struct {
    int length;
    int *array;
} bar_t;


void load(int length, int* data)
{
    for (int i = 0; i < length; i++) {
        data[i] = i;
    }
}

void dump(int length, int* data)
{
    for (int i = 0; i < length; i++) {
        printf(" %i", data[i]);
    }
    printf("\n");
}


int main(int argc, char* argv[])
{
    int size = 9;               // variable

    foo_t * foo;
    bar_t bar;

    printf("%i\n", sizeof (foo_t));
    foo = (foo_t *) malloc(sizeof(foo_t) + size * sizeof (int));
    foo->length = size;
    for (int i = 0; i < size; i++) {
        foo->array[i] = i;
    }
    load(foo->length, foo->array);
    dump(foo->length, foo->array);


    printf("%i\n", sizeof (bar_t));
    bar.length = size;
#ifdef __cplusplus
    bar.array = new int[size];
#else
    bar.array = malloc(size * sizeof (int));
#endif
    for (int i = 0; i < size; i++) {
        bar.array[i] = i;
    }
    load(bar.length, bar.array);
    dump(bar.length, bar.array);
}


I expect adding a 1 unit dimension is the easiest modification to
existing software but if I was writing from the start I'd use
pointers.  Consider:

typedef struct {
    int length;
    int height;
    int X[];      // won't compile
    int Y[];
} foo_t;



James.


More information about the maintainers mailing list