Connecting Tech Pros Worldwide Forums | Help | Site Map

c size 0 question

sinbad
Guest
 
Posts: n/a
#1: Nov 21 '08
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
~

Joachim Schmitz
Guest
 
Posts: n/a
#2: Nov 21 '08

re: c size 0 question


sinbad wrote:
Quote:
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

Nate Eldredge
Guest
 
Posts: n/a
#3: Nov 21 '08

re: c size 0 question


sinbad <sinbad.sinbad@gmail.comwrites:
Quote:
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....ro-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.
James Kuyper
Guest
 
Posts: n/a
#4: Nov 21 '08

re: c size 0 question


Nate Eldredge wrote:
....
Quote:
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.
James Kuyper
Guest
 
Posts: n/a
#5: Nov 21 '08

re: c size 0 question


sinbad wrote:
Quote:
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.
Quote:
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);
Nick Keighley
Guest
 
Posts: n/a
#6: Nov 21 '08

re: c size 0 question


On 21 Nov, 08:13, Nate Eldredge <n...@vulcan.lanwrote:

<snip>
Quote:
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

--
Nick Keighley

Keith Thompson
Guest
 
Posts: n/a
#7: Nov 21 '08

re: c size 0 question


Nate Eldredge <nate@vulcan.lanwrites:
[...]
Quote:
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".
Quote:
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.
[...]

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Keith Thompson
Guest
 
Posts: n/a
#8: Nov 21 '08

re: c size 0 question


Nick Keighley <nick_keighley_nospam@hotmail.comwrites:
Quote:
On 21 Nov, 08:13, Nate Eldredge <n...@vulcan.lanwrote:
<snip>
>
Quote:
>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
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....84baf9899c90a6
http://preview.tinyurl.com/6h76rs
starting at the 10th article.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Keith Thompson
Guest
 
Posts: n/a
#9: Nov 21 '08

re: c size 0 question


James Kuyper <jameskuyper@verizon.netwrites:
[...]
Quote:
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);

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
s0suk3@gmail.com
Guest
 
Posts: n/a
#10: Nov 21 '08

re: c size 0 question


On Nov 21, 11:01*am, Keith Thompson <kst-u@mib.orgwrote:
Quote:
Nick Keighley <nick_keighley_nospam@hotmail.comwrites:
Quote:
On 21 Nov, 08:13, Nate Eldredge <n...@vulcan.lanwrote:
<snip>
>
Quote:
Quote:
Also, the correctness of `int main()' is controversial. *You should
really use `int main(void)' which is unambiguously correct
>
Quote:
I'm not sure if "controversial" is the right word.
>
Quote:
* *int main()
>
Quote:
in a function definition is correct and unambiguous.
>
Quote:
* *int main (void)
>
Quote:
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.
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

CBFalconer
Guest
 
Posts: n/a
#11: Nov 22 '08

re: c size 0 question


James Kuyper wrote:
Quote:
sinbad wrote:
>
Quote:
>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.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Keith Thompson
Guest
 
Posts: n/a
#12: Nov 22 '08

re: c size 0 question


CBFalconer <cbfalconer@yahoo.comwrites:
Quote:
James Kuyper wrote:
Quote:
>sinbad wrote:
>>
Quote:
>>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).

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Closed Thread