1

I am attempting to use a macro to initialize all the array parameters of a structure array where one of the parameters is an array.

My struct is

typedef struct
{
  int size_parts;
  int *parts;
  int width;
  int length;
} parts_struct;

And my macro is defined as

#define SET_ARRAY_INPUT(_width, _length, ...) {width:_width, length:_length, parts:{__VA_ARGS__}, size_parts:(sizeof((int[]){__VA_ARGS__})/sizeof(int))}

My array is initialized as

static parts_struct parts[] = {
   SET_ARRAY_INPUT(2, 3, 9354, 39458, 3294),
   SET_ARRAY_INPUT(4, 2, 9354, 3294)
}

However this is always failing and I keep getting error "error: braces around scalar initializer for type". Any help would be greatly appreciated.

6
  • 3
    This isn't valid C. Rather looks like some icky macro used by a C++ constructor. Please don't write code like this regardless of language used... Now what you actually want (in C) is probably a compound literal. Commented Apr 19, 2018 at 15:45
  • A guess - mayby use double brackets around the MACRO SET_ARRAY - ie SET_ARRAY(( 2,3,4,5 )), Commented Apr 19, 2018 at 15:49
  • Do you have advice on how to get a similar behavior ? Commented Apr 19, 2018 at 15:49
  • Are you sure you didn't want designated initializers? Like Lundin already mentioned, this looks more like JavaScript than C. Commented Apr 19, 2018 at 17:54
  • 1
    @Groo: It's a GCC extension syntax that GCC documents as obsolete since GCC 2.5 (meaning it was obsolete by mid-1994, possibly as early as late-1993). See my answer for links to supporting evidence. I only found it out today when trying to work out how the macro in the question could work at all. Commented Apr 19, 2018 at 18:20

2 Answers 2

1

In standard C (C99 or C11), designated initializers in a structure are preceded by a . and use = instead of :. You might manage to get something like this to work:

#define SET_ARRAY_INPUT(_width, _length, ...) \
    { .width = (_width), .length = (_length), \
      .parts = (int []){__VA_ARGS__}, \
      .size_parts = (sizeof((int[]){__VA_ARGS__})/sizeof(int))}

Note that the GCC manual page on Designated Initializers states:

Another syntax that has the same meaning, obsolete since GCC 2.5, is fieldname:, as shown here:

struct point p = { y: yvalue, x: xvalue };

Thus the alternative definition shown below does work (to my considerable surprise) but it is a GCC extension that has officially been obsolete for a very long time (the GCC releases page says GCC 2.5.0 was released in 1993-10-22; GCC 2.5.8 was released 1994-01-24; GCC 2.6.0 was released 1994-07-14) — and should not be used in new or refurbished code:

#define SET_ARRAY_INPUT(_width, _length, ...) \
    { width: (_width), length: (_length), \
      parts: (int []){__VA_ARGS__}, \
      size_parts: (sizeof((int[]){__VA_ARGS__})/sizeof(int))}
Sign up to request clarification or add additional context in comments.

3 Comments

It is telling me " error: expected primary-expression before '.' token"
The .parts is a pointer, not an array, so the initializer needs a compound literal. The amended answer compiles.
parts_struct p = SET_ARRAY_INPUT(2, 3, 9354, 39458, 3294); works well for me.
0

In your macro, you're trying to initialize a pointer like an array:

parts:{__VA_ARGS__}

You need to add the compound literal syntax to this:

parts:(int []){__VA_ARGS__}

4 Comments

Seems to have done something. Now I cam getting an error "unimplemented: non-trivial designated initializers not supported".
@user1936582 It compiles and runs for me. What compiler/version are you using?
Go it to work thank you! Had moved some stuff while testing and forgot to put it back to normal.
Note that the 'designated initializer' notation used in the question is a GCC extension that has been obsolete since 'GCC 2.5' (see my answer for links), meaning since not later than 1994-07-14 (when 2.6.0 was released).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.