Compiler warning on struct initialization...

D

Daniel Rudy

Hello Group.

Please consider the following code:

/* this table is used in the wipedevice routine */
static const struct wipe_t
{
uchar wte[3]; /* wipe table entry */
} wipetable[] = {
{0x00, 0x00, 0x00},
{0x92, 0x29, 0x24},
{0x6D, 0xB6, 0xDB},
{0xFF, 0xFF, 0xFF},
{0x92, 0x29, 0x24},
{0x6D, 0xB6, 0xDB},
{0xAA, 0xAA, 0xAA},
{0x92, 0x29, 0x24},
{0x6D, 0xB6, 0xDB},
{0x55, 0x55, 0x55},
{0x92, 0x29, 0x24},
{0x6D, 0xB6, 0xDB},
{0x00, 0x00, 0x00}
};


When I compile the module, I'm getting the following error:

fs_dev.c:83: warning: missing braces around initializer
fs_dev.c:83: warning: (near initialization for `wipetable[0].wte')

uchar is defined as follows:

#define uchar unsigned char


This code appears before the table above, and there is no problem:

/* this table is used to help determine the CHS if the
device does not have or support CHS */
static const struct chs_xla_t
{
uint32 count;
uint16 cyl;
uint16 head;
uint16 sect;
uint16 block;
} chs_xla[] = {
{ 13668, 201, 4, 17, 68}, /* 7MB */
{ 20502, 201, 6, 17, 102}, /* 10MB */
{ 32436, 318, 6, 17, 102}, /* 16MB */
{ 41820, 615, 4, 17, 68}, /* 21MB */
{ 57222, 306, 11, 17, 187}, /* 28MB */
{ 62832, 462, 8, 17, 136}, /* 31MB */
{ 64000, 250, 16, 16, 256}, /* 32MB */
{ 80000, 400, 8, 25, 200}, /* 40MB */
{ 128000, 250, 16, 32, 512}, /* 64MB */
{ 256000, 250, 32, 32, 1024}, /* 128MB */
{ 512000, 250, 64, 32, 2048}, /* 256MB */
{ 1024000, 500, 64, 32, 2048}, /* 512MB */
{ 2048000, 500, 128, 32, 4096}, /* 1GB */
{ 4096000, 1000, 128, 32, 4096}, /* 2GB */
{ 8192000, 1024, 200, 40, 8000}, /* 4GB */
{16384000, 1024, 256, 63, 16128}, /* 8GB */
{16515072, 1024, 256, 63, 16128} /* Absolute Maximum for CHS */
};

Any ideas as to what the compiler is complaining about? I'm using gcc
on FreeBSD. The command line is as follows:

gcc -W -Wall -Wshadow -Wpointer-arith -Wcast-align -Wstrict-prototypes
-Wnested-externs -Wwrite-strings -Wfloat-equal -Winline -Wtrigraphs
-ansi -std=c89 -pedantic -ggdb3 -c -o fs_dev.o fs_dev.c


--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fsck more fsck yes spray umount sleep
 
M

Mohan

Hello Group.

Please consider the following code:

/* this table is used in the wipedevice routine */
static const struct wipe_t
{
uchar wte[3]; /* wipe table entry */
} wipetable[] = {
{0x00, 0x00, 0x00},
{0x92, 0x29, 0x24},
{0x6D, 0xB6, 0xDB},
{0xFF, 0xFF, 0xFF},
{0x92, 0x29, 0x24},
{0x6D, 0xB6, 0xDB},
{0xAA, 0xAA, 0xAA},
{0x92, 0x29, 0x24},
{0x6D, 0xB6, 0xDB},
{0x55, 0x55, 0x55},
{0x92, 0x29, 0x24},
{0x6D, 0xB6, 0xDB},
{0x00, 0x00, 0x00}
};

When I compile the module, I'm getting the following error:

fs_dev.c:83: warning: missing braces around initializer
fs_dev.c:83: warning: (near initialization for `wipetable[0].wte')

An extra set of braces required in the above initialization.
Because the structure has an array member.

wipetable[] = {
{ {0x00, 0x00, 0x00} },
...
};

Mohan
 
M

mark_bluemel

Hello Group.

Please consider the following code:

/* this table is used in the wipedevice routine */
static const struct wipe_t
{
uchar wte[3]; /* wipe table entry */
} wipetable[] = {
{0x00, 0x00, 0x00}, ....
};

This is a somewhat special case of a struct - with only one element.
When I compile the module, I'm getting the following error:

fs_dev.c:83: warning: missing braces around initializer
fs_dev.c:83: warning: (near initialization for `wipetable[0].wte')

In the line "{0x00, 0x00, 0x00}," the braces wrap the initialization
of the array.
In the context of the larger array of structs, each struct initializer
should also be braced.

When I used "{ {0x00, 0x00, 0x00} }," for the first line of the
initialization, I found that
the error moved on one line, confirming (or at least reinforcing) my
understanding of the issue.

[Over to the language lawyers to correct me]
 
A

Army1987

On Fri, 13 Jul 2007 09:59:07 +0000, Daniel Rudy wrote:
[snip]
Any ideas as to what the compiler is complaining about? I'm using gcc
on FreeBSD. The command line is as follows:

gcc -W -Wall -Wshadow -Wpointer-arith -Wcast-align -Wstrict-prototypes
-Wnested-externs -Wwrite-strings -Wfloat-equal -Winline -Wtrigraphs
-ansi -std=c89 -pedantic -ggdb3 -c -o fs_dev.o fs_dev.c
^^ ^^
Aren't those two synonymous?
 
D

Daniel Rudy

At about the time of 7/13/2007 3:28 AM, (e-mail address removed) stated
the following:
Hello Group.

Please consider the following code:

/* this table is used in the wipedevice routine */
static const struct wipe_t
{
uchar wte[3]; /* wipe table entry */
} wipetable[] = {
{0x00, 0x00, 0x00}, ...
};

This is a somewhat special case of a struct - with only one element.
When I compile the module, I'm getting the following error:

fs_dev.c:83: warning: missing braces around initializer
fs_dev.c:83: warning: (near initialization for `wipetable[0].wte')

In the line "{0x00, 0x00, 0x00}," the braces wrap the initialization
of the array.
In the context of the larger array of structs, each struct initializer
should also be braced.

That explains it, and corrects it. Thanks.
When I used "{ {0x00, 0x00, 0x00} }," for the first line of the
initialization, I found that
the error moved on one line, confirming (or at least reinforcing) my
understanding of the issue.

[Over to the language lawyers to correct me]


--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fsck more fsck yes spray umount sleep
 
C

Chris Torek

[some rearrangement and vertical compression applied]
#define uchar unsigned char
static const struct wipe_t {
uchar wte[3]; /* wipe table entry */
} wipetable[] = {

So, "wipetable" has type "array ? of struct ...", where the
question-mark (representing an unknown-as-yet size) will be
filled in by the number of elements initialized.

The struct has type "struct wipe_t", and contains one member,
"wte". This memeber has type "array 3 of unsigned char".

The final opening brace above begins the initializer for the
outermost array, i.e., "wipetable" itself.
{0x00, 0x00, 0x00},

This line has an open brace, a list of values, and a close brace.

The open brace can be applied to the "next available aggregate".
Aggregate types include both arrays and structures, and the next
available one is "struct wipe_t".

That uses up the open brace, so that we just have the three values.
The thing to be initialized at this point is an array, which is
an aggregate, and logically "ought to" have an open brace.
{0x92, 0x29, 0x24},
{0x6D, 0xB6, 0xDB},
{0xFF, 0xFF, 0xFF},
{0x92, 0x29, 0x24},
[etc]

These go on to initialize wipetable[1], wipetable[2], and so on;
all of them have the same set of "missing" braces.
When I compile the module, I'm getting the following error:

fs_dev.c:83: warning: missing braces around initializer
fs_dev.c:83: warning: (near initialization for `wipetable[0].wte')

which is what gcc produces when you have a partially-bracketed
initializer (as in this case), and you ask for the warning about
partially-bracketed initializers ("-Wmissing-braces", in at least
some versions, and implied by "-Wall").
This code appears before the table above, and there is no problem:

/* this table is used to help determine the CHS if the
device does not have or support CHS */
static const struct chs_xla_t
{
uint32 count;
uint16 cyl;
uint16 head;
uint16 sect;
uint16 block;
} chs_xla[] = {

Here chs_xla has type "array ? of struct chs_xla_t". As before,
the question-mark will be filled in by the initializer. The struct
type has five elements, each an ordinary integer (assuming "the
usual" typedefs for uint32 and uint16 anyway).
{ 13668, 201, 4, 17, 68}, /* 7MB */

The open brace indicates the next available aggregate, i.e.,
the struct making up chs_xla[0]. Now we are down to the list
of values. The next "thing to be initialized" is an ordinary
integer, which does not require a brace, so chs_xla[0].count
is to be set to 13668. This leaves the 201 for chs_xla[0].cyl,
and so forth.

If any members of "struct chs_xla_t" had been aggregates themselves,
you would need more braces (at least, to remove the warning). For
instance:

struct foo {
int a;
int b[2];
int c;
} foo[] = {
{ 1, { 2, 3 }, 4 },
{ 9, { 8, 7 }, 6 },
};

would be fully-bracketed.

Nothing requires initializers in C to be fully-bracketed, although
it is probably usually a good idea anyway.
 
K

Keith Thompson

Mohan said:
Please consider the following code:

/* this table is used in the wipedevice routine */
static const struct wipe_t
{
uchar wte[3]; /* wipe table entry */
} wipetable[] = {
{0x00, 0x00, 0x00},
{0x92, 0x29, 0x24},
{0x6D, 0xB6, 0xDB},
{0xFF, 0xFF, 0xFF},
{0x92, 0x29, 0x24},
{0x6D, 0xB6, 0xDB},
{0xAA, 0xAA, 0xAA},
{0x92, 0x29, 0x24},
{0x6D, 0xB6, 0xDB},
{0x55, 0x55, 0x55},
{0x92, 0x29, 0x24},
{0x6D, 0xB6, 0xDB},
{0x00, 0x00, 0x00}
};

When I compile the module, I'm getting the following error:

fs_dev.c:83: warning: missing braces around initializer
fs_dev.c:83: warning: (near initialization for `wipetable[0].wte')

An extra set of braces required in the above initialization.
Because the structure has an array member.

wipetable[] = {
{ {0x00, 0x00, 0x00} },
...
};

The extra braces are a good idea, but they're not actually required.
The language rules about braces in initializers are fairly lax. For
example, this:

int arr[2][2][2] = { 1, 2, 3, 4, 5, 6, 7, 8 };

is legal, even though this:

int arr[2][2][2] = { { {1, 2}, {3, 4} },
{ {5, 6}, {7, 8} } };

is clearer. The compiler is merely warning about the "missing" braces
(appropriately, IMHO); there's no constraint violation or syntax
error.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,233
Latest member
AlyssaCrai

Latest Threads

Top