Capricorn
Capricorn

Reputation: 761

Macro for a structure

I have a structure

typedef struct lzma_next_coder_s lzma_next_coder;

struct lzma_next_coder_s {
lzma_coder *coder;
lzma_vli id;
uintptr_t init;
lzma_code_function code;
lzma_end_function end;
lzma_check (*get_check)(const lzma_coder *coder);
lzma_ret (*memconfig)(lzma_coder *coder, uint64_t *memusage,
        uint64_t *old_memlimit, uint64_t new_memlimit);
lzma_ret (*update)(lzma_coder *coder, lzma_allocator *allocator,
        const lzma_filter *filters,
        const lzma_filter *reversed_filters);
};

Following is the macro:

#define LZMA_NEXT_CODER_INIT \
(lzma_next_coder){ \
    .coder = NULL, \
    .init = (uintptr_t)(NULL), \
    .id = LZMA_VLI_UNKNOWN, \
    .code = NULL, \
    .end = NULL, \
    .get_check = NULL, \
    .memconfig = NULL, \
    .update = NULL, \
}

This is the call

lzma_next_coder *next;

next = LZMA_NEXT_CODER_INIT; line 210.

Main aim is to initialize the next structure with NULL.

But I am getting error C2059: syntax error : '{' and error C2143: syntax error : missing ';' before '{' at line 210

I am using Visual studio 2010 to compile. I guess VS doesn't recognize .coder=NULL style syntax. I also wrote a function(instead of the macro) in which I initialize the structure members with NULL like this.

lzma_next_coder make_null_lzma()
{
lzma_next_coder temp;
temp.coder = NULL;
    //other members
    return temp;
}
next = make_null_lzma();

The errors go away now but I am getting run-time crash. Am I doing it correctly? Is next really getting initialized with NULL? Or have I messed it up?

Thanks

Upvotes: 1

Views: 1268

Answers (2)

Lindydancer
Lindydancer

Reputation: 26164

The basic problem is that LZMA_NEXT_CODER_INIT is used to initialize a structure, whereas next is a pointer to a structure. To initialize it to NULL simply do:

next = NULL

In addition, Visual C++ wouldn't support this kind of initialization anyway, as it was introduced in C99, which isn't supported by Visual Studio. To get around this limitation you can replace the macro with a C90-style initialization:

#define LZMA_NEXT_CODER_INIT \
{ \
    NULL, \
    LZMA_VLI_UNKNOWN, \
    (uintptr_t)(NULL), \
    NULL, \
    NULL, \
    NULL, \
    NULL, \
    NULL, \
}

Note that in the fields have been rearranged to match the order of the struct.

EDIT: This only works when initializing a structure. If you want to assign to an already existing structure, you can create a temporary and assign it to the old struct. For example:

{
  tmp lzma_next_coder_s tmp = LZMA_NEXT_CODER_INIT;
  old = tmp;
}

Upvotes: 2

Jonathan Leffler
Jonathan Leffler

Reputation: 755094

The error messages are formatted as if they come from MSVC. MSVC does not support C99; the constructs you are using are in C99 and not C89 which is all MSVC supports.

You'll either need to find a C99 compiler (which suggests using a GCC compiler such as Cygwin or MinGW) or forego the convenience of the compound literal and designated initializers.

The function version should work fine. You could check that you've initialized everything by printing out the initialized structure. I'm assuming that there is some other code between the function definition and its use in the assignment to temp.

Upvotes: 4

Related Questions