Wednesday, April 27, 2022

[FIXED] Why do I get warning: braces around scalar initializer?

Issue

I have this code:

typedef char **Runlevel[];
Runlevel runlevel_default = {
    { "/usr/bin/test", NULL },
};

And if I try to compile it, I get warnings like:

  • warning: braces around scalar initializer
  • warning: initialization of ‘char **’ from incompatible pointer type ‘char *’
  • warning: excess elements in scalar initializer

However, when I write it like this:

char *args[] = { "/usr/bin/test", NULL };

Runlevel runlevel_default = {
    args
};

I don't get any warnings. What's the problem?

EDIT: My target is to make an array of runlevels. Like in comment of @Paul Ogilvie, I removed nested brackets, but now when I am making something like this:

Runlevel runlevel_default[] = {
    { "/usr/bin/test", NULL }
};

I am getting another error: error: array type has incomplete element type ‘Runlevel’ {aka ‘char **[]’}

What can be a problem now?


Solution

Your typedef char **Runlevel[]; statement isn't defining what you appear to want; with that statement, RunLevel is not a 2-D array of char* pointers but a 1-D array of char** elements. Thus, not only does your subsequent initialization of the runlevel_default variable have too many sets of braces, but the individual elements (string literals and the NULL token) are of the wrong type (they are 'valid' char* values but not char**).

So, what you maybe looking for is something like typedef char *Runlevel[][]; – but this is not valid, because only one dimension of a multi-dimensional array can have an unspecified size, to be determined by the compiler when such an array type is declared/initialized.

So, assuming each sub-element of your array will be two (and only two) char* pointers (possibly to string literals), then you need to specify that 2 as the last (innermost) dimension:

typedef char* Runlevel[][2];

Runlevel runlevel_default = {
    { "/usr/bin/test", NULL },
    { "/usr/bin/test2", NULL },
    { "/usr/bin/test3", NULL },
};

Using this syntax, the value of the 'empty' dimension in the typedef will be determined by the compiler according to how many brace-enclosed pairs of char* values you include in the (also brace-enclosed) initialization list; in the above code, the runlevel_default variable will be as if declared char* runlevel_default[3][2]. However, you could also declare a different variable of Runlevel type, with a different 'outer' dimension, like so:

Runlevel runlevel_different = {
    { "/usr/bin/test", NULL },
    { "/usr/bin/test2", NULL },
    { "/usr/bin/test3", NULL },
    { "/usr/bin/test4", NULL },
    { "/usr/bin/test5", NULL }, // This time, we have 5 as the outer dimension
};


Answered By - Adrian Mole
Answer Checked By - David Marino (PHPFixing Volunteer)

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.