c size 0 question

S

sinbad

chip_init.c

1 #include <stdio.h>
2 struct a {
3 char buf[0];
4 }b;
5 struct c {
6 char buf[1];
7 }d;
8
9 int main ()
10 {
11 printf("%u %u\n", sizeof(b), sizeof(d));
12 printf("%u %u", sizeof(struct a), sizeof(struct c));
13 return 0;
14 }

the output is
0 1
0 1

can someone explain why sizeof(b) and sizeof(struct a) is zero,
if there is no memory allocated how can i use this variable
and why gcc allows this.

thanks
~
 
J

Joachim Schmitz

sinbad said:
chip_init.c

1 #include <stdio.h>
2 struct a {
3 char buf[0];
4 }b;
5 struct c {
6 char buf[1];
7 }d;
8
9 int main ()
10 {
11 printf("%u %u\n", sizeof(b), sizeof(d));
12 printf("%u %u", sizeof(struct a), sizeof(struct c));
13 return 0;
14 }

the output is
0 1
0 1

can someone explain why sizeof(b) and sizeof(struct a) is zero,
if there is no memory allocated how can i use this variable
and why gcc allows this.

Most propbably because you didn't incoke gcc in a (mostly) conforming mode
(-ansi or -std=c99 plus -pedantic)

Bye, Jojo
 
N

Nate Eldredge

sinbad said:
chip_init.c

1 #include <stdio.h>
2 struct a {
3 char buf[0];
4 }b;
5 struct c {
6 char buf[1];
7 }d;
8
9 int main ()
10 {
11 printf("%u %u\n", sizeof(b), sizeof(d));
12 printf("%u %u", sizeof(struct a), sizeof(struct c));
13 return 0;
14 }

the output is
0 1
0 1

can someone explain why sizeof(b) and sizeof(struct a) is zero,
if there is no memory allocated how can i use this variable
and why gcc allows this.

It's a GCC extension, not part of standard C. You can read about it in
the GCC manual at
http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Zero-Length.html . That
page also has an explanation of C99 flexible array members, which are
similar and standard.

Note that your program has a bug; the "%u" format specifier for printf()
expects you to pass an unsigned int, but sizeof(b) has type size_t,
which might be different. You should ideally use the C99-standard "%z"
format specifier if your library supports it. Otherwise, cast sizeof(b)
to unsigned int, and hope that it fits.

Also, the correctness of `int main()' is controversial. You should
really use `int main(void)' which is unambiguously correct.
 
J

James Kuyper

Nate Eldredge wrote:
....
Note that your program has a bug; the "%u" format specifier for printf()
expects you to pass an unsigned int, but sizeof(b) has type size_t,
which might be different. You should ideally use the C99-standard "%z"
format specifier if your library supports it. Otherwise, cast sizeof(b)
to unsigned int, and hope that it fits.

It's safer to use unsigned long; that's more likely to fit.
 
J

James Kuyper

sinbad said:
chip_init.c

1 #include <stdio.h>
2 struct a {
3 char buf[0];

It's a constraint violation to declare an array with a length of 0. gcc
allows this as an extension, but it's entirely up to gcc to determine
how it can be used.
4 }b;
5 struct c {
6 char buf[1];
7 }d;
8
9 int main ()
10 {
11 printf("%u %u\n", sizeof(b), sizeof(d));

The "%u" specifier expects an unsigned int argument; the result of the
sizeof operator is size_t, which is unsigned, but might be an unsigned
type larger than unsigned int (it could also be smaller, though that's a
lot less likely, and not a problem in this context).

In C90, you should write
printf("%lu %lu\n",
(unsigned long)sizeof b, (unsigned long)sizeof d);

In C99, you should write
printf("%z %z\n", sizeof b, sizeof d);
 
N

Nick Keighley

Also, the correctness of `int main()' is controversial.  You should
really use `int main(void)' which is unambiguously correct

I'm not sure if "controversial" is the right word.

int main()

in a function definition is correct and unambiguous.

int main (void)

is more of a style thing
 
K

Keith Thompson

Nate Eldredge said:
Note that your program has a bug; the "%u" format specifier for printf()
expects you to pass an unsigned int, but sizeof(b) has type size_t,
which might be different. You should ideally use the C99-standard "%z"
format specifier if your library supports it.

You mean "%zu".
Otherwise, cast sizeof(b)
to unsigned int, and hope that it fits.

Even better, cast to unsigned long and use "%lu" -- though unsigned
int is fine if you're sure the size doesn't exceed 32767.
[...]
 
K

Keith Thompson

Nick Keighley said:
I'm not sure if "controversial" is the right word.

int main()

in a function definition is correct and unambiguous.

int main (void)

is more of a style thing

It is controversial; we've discussed it here at considerable length a
couple of times. In case you missed it, the argument is that
int main() { /* ... */ }
is not "equivalent" to
int main(void) { /* ... */ }
because the latter causes a call main(42) to be a constraint
violation.

See, for example,
http://groups.google.com/group/comp...67fc7/ff84baf9899c90a6?tvc=1#ff84baf9899c90a6
http://preview.tinyurl.com/6h76rs
starting at the 10th article.
 
K

Keith Thompson

James Kuyper said:
The "%u" specifier expects an unsigned int argument; the result of the
sizeof operator is size_t, which is unsigned, but might be an unsigned
type larger than unsigned int (it could also be smaller, though that's
a lot less likely, and not a problem in this context).

In C90, you should write
printf("%lu %lu\n",
(unsigned long)sizeof b, (unsigned long)sizeof d);

In C99, you should write
printf("%z %z\n", sizeof b, sizeof d);

printf("%zu %zu\n", sizeof b, sizeof d);
 
S

s0suk3

It is controversial; we've discussed it here at considerable length a
couple of times.  In case you missed it, the argument is that
    int main() { /* ... */ }
is not "equivalent" to
    int main(void) { /* ... */ }
because the latter causes a call main(42) to be a constraint
violation.

Why? In the link to the first thread you posted below, Richard
Heathfield posted a quote from C89 about this. In 6.7.5.3 from C99,
the quote is:

"14 An identifier list declares only the identifiers of the parameters
of the function. An empty list in a function declarator that is part
of a definition of that function specifies that the
function has no parameters. The empty list in a function declarator
that is not part of a
definition of that function specifies that no information about the
number or types of the
parameters is supplied.126)"

So if the function declarator is part of the definition of the
function (as was the case for main() in the OP's code), then calling
main(42) *is* a constraint violation, isn't it?

Sebastian
 
C

CBFalconer

James said:
sinbad said:
chip_init.c

1 #include <stdio.h>
2 struct a {
3 char buf[0];

It's a constraint violation to declare an array with a length of
0. gcc allows this as an extension, but it's entirely up to gcc
to determine how it can be used.

You can define the last element of a struct as a zero sized array,
in C99 only. This allows special games to set the buf (above) to
an appropriate size on malloc of an instance of that struct.

Other possibilities are off-topic extensions.
 
K

Keith Thompson

CBFalconer said:
James said:
sinbad said:
chip_init.c

1 #include <stdio.h>
2 struct a {
3 char buf[0];

It's a constraint violation to declare an array with a length of
0. gcc allows this as an extension, but it's entirely up to gcc
to determine how it can be used.

You can define the last element of a struct as a zero sized array,
in C99 only. This allows special games to set the buf (above) to
an appropriate size on malloc of an instance of that struct.
[...]

No, C99's flexible array member syntax doesn't use "[0]"; it uses
"[]".

So this:

struct a {
size_t len;
char buf[1];
};

is likely to be a C90-style struct hack (whose legality has been
questioned); and this:

struct b {
size_t len;
char buf[0];
};

is a constraint violation in either C90 or C99, and is likely to be
dependent on a gcc extension; and this:

struct c {
size_t len;
char buf[];
};

is a struct containing a C99 flexible array member, intended to
replace the struct hack.

See also question 2.6 in the comp.lang.c FAQ, <http://c-faq.com/>
(which unfortunately doesn't mention the phrase "struct hack" except
in its URL).
 
H

Harald van Dijk

Keith said:
CBFalconer said:
James Kuyper wrote:
sinbad wrote:

chip_init.c

1 #include <stdio.h>
2 struct a {
3 char buf[0];

It's a constraint violation to declare an array with a length of 0.

You can define the last element of a struct as a zero sized array, in
C99 only.

No, C99's flexible array member syntax doesn't use "[0]"; it uses "[]".

Well caught. So it's just a syntax error.

No, it's not a syntax error, it's a constraint violation, as James Kuyper
already wrote in the text you quoted.
 
C

CBFalconer

Harald said:
CBFalconer said:
Keith said:
James Kuyper wrote:
sinbad wrote:

chip_init.c

1 #include <stdio.h>
2 struct a {
3 char buf[0];

It's a constraint violation to declare an array with a length
of 0.

You can define the last element of a struct as a zero sized
array, in C99 only.

No, C99's flexible array member syntax doesn't use "[0]"; it
uses "[]".

Well caught. So it's just a syntax error.

No, it's not a syntax error, it's a constraint violation, as
James Kuyper already wrote in the text you quoted.

Please try to ignore my misuse of the 'accurate' error titles.
 
K

Keith Thompson

CBFalconer said:
Harald said:
CBFalconer said:
Keith Thompson wrote:
James Kuyper wrote: [...]
It's a constraint violation to declare an array with a length
of 0.

You can define the last element of a struct as a zero sized
array, in C99 only.

No, C99's flexible array member syntax doesn't use "[0]"; it
uses "[]".

Well caught. So it's just a syntax error.

No, it's not a syntax error, it's a constraint violation, as
James Kuyper already wrote in the text you quoted.

Please try to ignore my misuse of the 'accurate' error titles.

Um, why? You made a mistake (an honest one I'm sure) why shouldn't it
be pointed out?
 
C

CBFalconer

Keith said:
CBFalconer said:
Harald said:
CBFalconer wrote:
Keith Thompson wrote:
James Kuyper wrote: [...]
It's a constraint violation to declare an array with a length
of 0.

You can define the last element of a struct as a zero sized
array, in C99 only.

No, C99's flexible array member syntax doesn't use "[0]"; it
uses "[]".

Well caught. So it's just a syntax error.

No, it's not a syntax error, it's a constraint violation, as
James Kuyper already wrote in the text you quoted.

Please try to ignore my misuse of the 'accurate' error titles.

Um, why? You made a mistake (an honest one I'm sure) why shouldn't
it be pointed out?

A point, a veritable point. :)
 

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

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,591
Members
45,103
Latest member
VinaykumarnNevatia
Top