Domanda

Let's say I have this struct

typedef struct foo {
  int a;
  char b;
  char *c;
} foo;

and I want to create an initialized instance of the struct

foo bar = { .a = 7 .b = 'x' .c = "hello" };

However, what if I mess up and forget to initialize one of the elements of the structure I am initializing ... for example ...

foo bar = { .a = 7, .c = "hello" };

... I just forgot to initialize element "b" --- a mistake that is simple to detect in the example I gave, but in the case of more complex structs, especially under-development ones, this is definitely plausible.

Is there any flag that I could pass to that would cause it to generate a warning if I do a screw-up like this?

È stato utile?

Soluzione

Using the "old school" ISO C way of initializing structs (when not compiling with -std=c99), gcc should give you a warning by default. Other than that, the gcc flag you need to set is -Wmissing-field-initializers, which is enabled by default AFAIK Which is NOT enabled by default, but part of -Wextra, as Michael Burr stated in his comment, provided you use the following syntax:

int main ( void )
{
    foo bar = {123, "foobar"};//failed to init char b member
    foo zar = {123, '\a'};//omitted c initialization 
    return 0;
}

This should issue the following warning:

warning: initialization makes integer from pointer without a cast [enabled by default]
  foo bar = { 123, "foobar"};
warning: missing initializer for field ‘c’ of ‘foo’ [-Wmissing-field-initializers]
  foo zar = { 123, 'a'};

The major downside to this is, of course, that it makes your code harder to read, and maintain... not an insignificant down-side IMO...

If you can, and if the overhead isn't too bad, I'd simply write a function. Especially considering you have a char * member field, which may require heap-allocated memory:

foo * init_foo(foo *str, int a, char b, char *c)
{
    if (c == NULL) return NULL;// no char pointer passed
    if (str == NULL) str = malloc(sizeof *str);//function allocates struct, too
    str->a = a;
    str->b = b;
    str->c = calloc(strlen(c) + 1, sizeof *(str->c));//allocate char pointer
    strcpy(str->c, c);
    return str;
}
//optionally include custom free function:
void free_foo ( foo **f)
{
    if ((*f)->c != NULL) free((*f)->c);
    free(*f)
    *f = NULL;//init pointer to NULL
}

That'd be the safest way to go... call this function like so:

foo *new_foo = init_foo( NULL, 123, '\a', "string");//allocate new struct, set all members
//free like so:
free_foo(&new_foo);//pass pointer to pointer
foo stack_foo;
init_foo(&stack_foo, 123, '\a', "string");//initialize given struct
//only free .c member
free(stack_foo.c);
stack_foo.c = NULL;

At any rate, while developing, always compile using -Wall and, to be safe --pedantic, too...

Altri suggerimenti

  1. You have to pass "-W" option to gcc.
  2. User bar.a instead of .a in your code.

you can see the following warning message if you compile code with "gcc -W test.c" command

test.c:11: warning: missing initializer
test.c:11: warning: (near initialization for âbar.câ)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top