tags:

views:

97

answers:

3

Hello,

gcc 4.4.4 c89

I will be adding to this list. So I am looking to NULL terminate it. However, I am getting a warning: "Initialization makes integer from pointer without a cast"

Why does the it mention integer when I haven't used in that structure?

I was thinking in this case arrays and pointers where the same?

 struct company_prof
    {
        char name[32];
        size_t age;
        char position[32];
    } employee[] = {
        { "Job Bloggs",  23, "software engineer"    },
        { "Lisa Low" ,   34, "Telecomms Technician" },
        { "simon smith", 38, "personal assistist"   },
        { NULL         , -1, NULL                   }
    };

Many thanks for any suggestions,

+6  A: 

In this case, you're statically allocating the space for the strings in the structure. The space for the strings aren't really a separate entity from the structure, it's just a block of space with in it. So you can't assign a pointer to those fields because they can't refer to anything else -- they're just convenient names for referring to the beginning of those chunks within the structure.

The reason you get the bit about the conversion is that characters (e.g., name[0]) are small integers, and it's trying to stuff the NULL pointer into the first character of each string. That first character is too small to hold a pointer, so it's giving you a warning about that.

You probably want to use "\0" instead of NULL here. That's an empty string or null string which is a bit different from a null pointer.

Edit: An alternative that you might consider for getting the size of the list is not using a sentinel value, but defining a constant that calculates it from the sizes in bytes. A typical construction for that looks like:

static const int num_employees = sizeof(employee) / sizeof(employee[0]);
Boojum
`""` is also an empty string, and probably more idiomatic.
caf
+2  A: 

You're using char[32] as your struct members. You can't convert from NULL to a char[N]. So whats happening is that NULL is being treated as zero. The warning is coming from the compiler deciding to convert the NULL to a 0. As the initialisation of the char[N] is occuring inside an array initialising it to 0 is valid, it just sets all the values to zero. e.g.

struct wrapper { char i[2] } w = { 0 }

will set the internal i to {0,0}

This means your memory layout looks like this.

|==============name============||--||==========position===========|
0123456789012345678901234567890101230123456789012345678901245678901
Job.Bloggs0000000000000000000000(23)software.engineer00000000000000 // first
...                                                                 // rest
00000000000000000000000000000000(-1)0000000000000000000000000000000 // sentinel

This may or may not be what you want .. but it does mean that looping over thises values will not be what you may expect: In particular this will not work:

p = employee;
while( p.name != NULL )
{
  printf("%s", p.name);
  ++p;
};

It will just run off printing garbage from memory and eventually segfault.

You might try something like this instead

p = employee;
while( p.name[0] != 0 )
{
  printf("%s", p.name);
  ++p;
};

But that wont work for names like "\0foo" (Which you might consider invalid anyway...)

Michael Anderson
+5  A: 

You are attempting to initialize a character array with NULL. This does not make any sense. For example, you will get the same warning from

char a[100] = { NULL };

and it makes no sense in exactly the same way.

The "integer" that is mentioned in the diagnostic message is the first element of the character array. char is an integer type in C and when you write

char a[100] = { NULL };

it is an attempt to initialize 0-th element of the array a with NULL. On your platform, NULL is declared as something with pointer type, which is why the diagnostic message is saying that you are attempting to make an integer (a[0]) from a pointer (NULL) without a cast.

An even simpler example might look as follows

char c = NULL;

and it will earn you the same diagnostic message for the very same reasons.

May I ask why you are attempting to initialize a char with NULL? What was your intent?

If you don't intend to write into the name and position arrays after initialization, maybe you should use pointers instead of arrays as in

struct company_prof
    {
        const char *name;
        size_t age;
        const char *position;
    } employee[] = {
        { "Job Bloggs",  23, "software engineer"    },
        { "Lisa Low" ,   34, "Telecomms Technician" },
        { "simon smith", 38, "personal assistist"   },
        { NULL         , -1, NULL                   }
    };

Formally, in this case NULL makes perfect sense. But not in case of array.

But less formally the purpose of that { NULL, -1, NULL } record at the end of the array is not clear to me though. Is is a terminating element of some kind? Why don't you just use the exact size of the array instead of creating a terminating element?

AndreyT
Thanks for the precise explanation. The list will grow large everyday. Maybe added more than 20 each day. Just seemed to be easy to write them in, rather counting how many I have each day. Thanks.
robUK
@robUK: You don't need to count it manually. Just use `sizeof employee / sizeof *employee` to get the current array size. It was already mentioned in other replies.
AndreyT