By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,988 Members | 1,017 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,988 IT Pros & Developers. It's quick & easy.

Size of Void

P: n/a
Hi,

Why sizeof operator when applied on void returns one when compiled
with gcc compiler ??. When i tried it on VC++ compiler, it gives an
error. But another version of the VC++ compiler on my friend's machine
gives it as zero. Have anyone tried this ? I believe it should give an
error because i think there is nothing called void.

Regards,
arun..

Apr 24 '06 #1
Share this Question
Share on Google+
14 Replies


P: n/a
"arun" <ar****************@gmail.com> wrote:
Why sizeof operator when applied on void returns one when compiled
with gcc compiler ??.


Because someone on the ganuck team thought that this would be a good
idea. Whatever made this person think that is one of the great mysteries
of the universe, which will be revealed when Deep Thought II finishes
calculating.

Richard
Apr 24 '06 #2

P: n/a
Richard Bos wrote:
"arun" <ar****************@gmail.com> wrote:
Why sizeof operator when applied on void returns one when compiled
with gcc compiler ??.


Because someone on the ganuck team thought that this would be a good
idea. Whatever made this person think that is one of the great mysteries
of the universe, which will be revealed when Deep Thought II finishes
calculating.


Instead of assuming there is no reason for this, you could check the
documentation, where you would find that sizeof(void) is defined in
"GNU C" because this allows certain extra operations on pointers to
void. Given that gcc complains about this when called with -pedantic,
and -pedantic is documented as a required option to get gcc to try to
conform to any standard, what is your problem with it?

Apr 24 '06 #3

P: n/a
"=?utf-8?B?SGFyYWxkIHZhbiBExLNr?=" <tr*****@gmail.com> wrote:
Richard Bos wrote:
"arun" <ar****************@gmail.com> wrote:
Why sizeof operator when applied on void returns one when compiled
with gcc compiler ??.
Because someone on the ganuck team thought that this would be a good
idea. Whatever made this person think that is one of the great mysteries
of the universe, which will be revealed when Deep Thought II finishes
calculating.


Instead of assuming there is no reason for this, you could check the
documentation, where you would find that sizeof(void) is defined in
"GNU C" because this allows certain extra operations on pointers to
void.


Well, yeah, that much was obvious. If sizeof(void) isn't forced to be 1,
you can't do arithmetic on void *s. But whoever thought that arithmetic
on void *s was a good idea?
Given that gcc complains about this when called with -pedantic,
and -pedantic is documented as a required option to get gcc to try to
conform to any standard, what is your problem with it?


None, as long as people don't ask for reasons for Ganuck-specific
features in this ISO C newsgroup.

Richard
Apr 24 '06 #4

P: n/a
Richard Bos wrote:
"=?utf-8?B?SGFyYWxkIHZhbiBExLNr?=" <tr*****@gmail.com> wrote:
Given that gcc complains about this when called with -pedantic,
and -pedantic is documented as a required option to get gcc to try to
conform to any standard, what is your problem with it?
None, as long as people don't ask for reasons for Ganuck-specific
features in this ISO C newsgroup.

From arun's original post:

"But another version of the VC++ compiler on my friend's machine gives
it as zero."
sizeof(void) is allowed in more compilers than only GNU's, and
additionally, it's not always linked to arithmetic on void * (unless
with that VC++ compiler for any valid void *p and integer i, p+i==p).

Also from the original post:
"I believe it should give an error because i think there is nothing
called void."
Asking whether something is valid C is a problem now in this newsgroup?
I'll admit that particular question is not explicit, but that's how I
read it.

A simple answer without insults would be one that states sizeof(void)
is not allowed in standard C, and therefore if accepted by any compiler
may give any result for any reason.

Apr 24 '06 #5

P: n/a
Richard Bos wrote:
[... sizeof(void)==1 in gcc ...]
Well, yeah, that much was obvious. If sizeof(void) isn't forced to be 1,
you can't do arithmetic on void *s.
Hmm... On my system, sizeof(int) is 4, and I can do arithmetic on int*'s
all over the place. You can have sizeof(void) be 37 if you wanted, and
arithmetic would still "work" on void*'s.
But whoever thought that arithmetic on void *s was a good idea?


I guess it allows "easy" access to void* buffers? Perhaps:

void foo(void *buffer)
{
int i;
float f;
char *pt;

i = *(int *)buffer;
buffer += sizeof(i);
f = *(float *)buffer;
buffer += sizeof(f);
pt = *(char **)buffer;
buffer += sizeof(pt);

...etc...
}

(Yes, I know this is very dependent on alignment restrictions.)

Of course, given that you need to cast each assignment anyway, why not
just use "unsigned char *" instead?

[...]

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Apr 24 '06 #6

P: n/a

"Richard Bos" <rl*@hoekstra-uitgeverij.nl> wrote in message
news:44****************@news.xs4all.nl...
"=?utf-8?B?SGFyYWxkIHZhbiBExLNr?=" <tr*****@gmail.com> wrote:
Richard Bos wrote:
"arun" <ar****************@gmail.com> wrote:

> Why sizeof operator when applied on void returns one when compiled > with gcc compiler ??.

Because someone on the ganuck team thought that this would be a good
idea. Whatever made this person think that is one of the great mysteries of the universe, which will be revealed when Deep Thought II finishes
calculating.
Instead of assuming there is no reason for this, you could check the
documentation, where you would find that sizeof(void) is defined in
"GNU C" because this allows certain extra operations on pointers to
void.


Well, yeah, that much was obvious. If sizeof(void) isn't forced to be 1,
you can't do arithmetic on void *s.


Really? As I see it, since sizeof(void) and pointer arithmetic are
undefined by the C standards, the compiler is free to return zero (or as
Brody said 37, or McIntyre would say 42) for sizeof(void) and still do
pointer arithmetic by any offset of the compiler implementors choice.
But whoever thought that arithmetic
on void *s was a good idea?


People who have to implement a real world compiler using the host
environment's assembly language. If you look at the list of GCC extensions,
at least a third are due to or for assembly language.
Rod Pemberton
Apr 24 '06 #7

P: n/a
On Mon, 24 Apr 2006 18:37:39 -0400, "Rod Pemberton"
<do*********@sorry.bitbuck.cmm> wrote in comp.lang.c:

"Richard Bos" <rl*@hoekstra-uitgeverij.nl> wrote in message
news:44****************@news.xs4all.nl...
"=?utf-8?B?SGFyYWxkIHZhbiBExLNr?=" <tr*****@gmail.com> wrote:
Richard Bos wrote:
> "arun" <ar****************@gmail.com> wrote:
>
> > Why sizeof operator when applied on void returns one when compiled > > with gcc compiler ??.
>
> Because someone on the ganuck team thought that this would be a good
> idea. Whatever made this person think that is one of the great mysteries > of the universe, which will be revealed when Deep Thought II finishes
> calculating.

Instead of assuming there is no reason for this, you could check the
documentation, where you would find that sizeof(void) is defined in
"GNU C" because this allows certain extra operations on pointers to
void.
Well, yeah, that much was obvious. If sizeof(void) isn't forced to be 1,
you can't do arithmetic on void *s.


Really? As I see it, since sizeof(void) and pointer arithmetic are
undefined by the C standards, the compiler is free to return zero (or as
Brody said 37, or McIntyre would say 42) for sizeof(void) and still do
pointer arithmetic by any offset of the compiler implementors choice.


There's a little more to it. The C standard defines void as an
incomplete type that cannot be completed, and it is a constraint
violation to apply the sizeof operator to an incomplete type.

So while the implementer is entitled to do whatever he/she likes,
since the behavior is undefined, the standard requires a diagnostic.
But whoever thought that arithmetic
on void *s was a good idea?


People who have to implement a real world compiler using the host
environment's assembly language. If you look at the list of GCC extensions,
at least a third are due to or for assembly language.


Which assembly language? x86, PowerPC, MIPS, ARM, etc.?

Give me a break. Attempting to apply sizeof to an incomplete type and
attempting to perform pointer arithmetic on an incomplete type are
errors that completely diagnosable at compile time, hence making them
constraint violations.

This particular extension has more to do with not breaking the code of
lazy and/or ignorant and/or sloppy programmers, than it does with the
assembly language. That statement makes no sense at all.
Rod Pemberton


--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Apr 25 '06 #8

P: n/a
On Mon, 24 Apr 2006 18:37:39 -0400, in comp.lang.c , "Rod Pemberton"
<do*********@sorry.bitbuck.cmm> wrote:
Brody said 37, or McIntyre would say 42)


Fame at last.

However FTR, it was the late and much lamented Douglas Adams who said
that.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Apr 25 '06 #9

P: n/a
Jack Klein wrote:

There's a little more to it. The C standard defines void as an
incomplete type that cannot be completed, and it is a constraint
violation to apply the sizeof operator to an incomplete type.

So while the implementer is entitled to do whatever he/she likes,
since the behavior is undefined, the standard requires a diagnostic.


The diagnostic is required because of the constraint violation.

In general, undefined behaviour does not require a diagnostic.
Also, constraint violations may not result in UB, but they still
do require a diagnostic. See C99 5.1.1.3.

Apr 26 '06 #10

P: n/a
"Old Wolf" <ol*****@inspire.net.nz> writes:
Jack Klein wrote:

There's a little more to it. The C standard defines void as an
incomplete type that cannot be completed, and it is a constraint
violation to apply the sizeof operator to an incomplete type.

So while the implementer is entitled to do whatever he/she likes,
since the behavior is undefined, the standard requires a diagnostic.


The diagnostic is required because of the constraint violation.

In general, undefined behaviour does not require a diagnostic.
Also, constraint violations may not result in UB, but they still
do require a diagnostic. See C99 5.1.1.3.


For some reason, I'm thinking that a constraint violation *does* cause
undefined behavior (if the program is successfully translated after
the required diagnostic), but I can't find a specific reference.

In most cases, the behavior would be undefined by omission.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Apr 26 '06 #11

P: n/a
Keith Thompson wrote:
"Old Wolf" <ol*****@inspire.net.nz> writes:
Jack Klein wrote:

There's a little more to it. The C standard defines void as an
incomplete type that cannot be completed, and it is a constraint
violation to apply the sizeof operator to an incomplete type.

So while the implementer is entitled to do whatever he/she likes,
since the behavior is undefined, the standard requires a diagnostic.
The diagnostic is required because of the constraint violation.

In general, undefined behaviour does not require a diagnostic.
Also, constraint violations may not result in UB, but they still
do require a diagnostic. See C99 5.1.1.3.


For some reason, I'm thinking that a constraint violation *does* cause
undefined behavior (if the program is successfully translated after
the required diagnostic), but I can't find a specific reference.


Mike Wahler had some comments on this...

http://groups.google.com/group/comp....4422af243a43ce
In most cases, the behavior would be undefined by omission.


This violates a constraint on some implementations, but that
notwithstanding,
it appears to have well defined semantics on any conforming C99
implementation. [Assuming no typos...]

#include <stdio.h>
#include <stdint.h>

int main(void)
{
int a;

#ifdef INTPTR_MAX
void *p = &a;
intptr_t i = p; /* constraint violation */
int *q = (void *) i;
#else
int *q = &a;
#endif

*q = 42;
printf("%d\n", a);
}

--
Peter

Apr 26 '06 #12

P: n/a
"Peter Nilsson" <ai***@acay.com.au> writes:
Keith Thompson wrote:
"Old Wolf" <ol*****@inspire.net.nz> writes: [...]
> In general, undefined behaviour does not require a diagnostic.
> Also, constraint violations may not result in UB, but they still
> do require a diagnostic. See C99 5.1.1.3.


For some reason, I'm thinking that a constraint violation *does* cause
undefined behavior (if the program is successfully translated after
the required diagnostic), but I can't find a specific reference.


Mike Wahler had some comments on this...

http://groups.google.com/group/comp....4422af243a43ce
In most cases, the behavior would be undefined by omission.


This violates a constraint on some implementations, but that
notwithstanding,
it appears to have well defined semantics on any conforming C99
implementation. [Assuming no typos...]

#include <stdio.h>
#include <stdint.h>

int main(void)
{
int a;

#ifdef INTPTR_MAX
void *p = &a;
intptr_t i = p; /* constraint violation */
int *q = (void *) i;
#else
int *q = &a;
#endif

*q = 42;
printf("%d\n", a);
}


The marked line is a constraint violation because it uses a pointer
value to initialize an integer object without a cast. For an
initializer of a scalar object, "the same type constraints and
conversions as for simple assignment apply" (C99 6.7.8p11); attempting
to assign a pointer value to an integer object violates the
constraints for simple assignment (C99 6.5.16.1).

A compiler is free to continue processing the translation unit after
issuing a diagnostic for this constraint violation. But you seem to
be assuming that the behavior of
intptr_t i = p;
will be to convert p from void* to intptr_t and assign the result to i.
I see nothing in the standard that supports this assumption.

Unless I'm missing something, the standard doesn't define the behavior
of this construct.

If there's a case where the standard says something is a constraint
violation, but nevertheless defines its behavior if the compiler
chooses to accept it after issuing a diagnostic, I'd be interested in
seeing it.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Apr 26 '06 #13

P: n/a
Keith Thompson wrote:
"Peter Nilsson" <ai***@acay.com.au> writes:
Keith Thompson wrote:
For some reason, I'm thinking that a constraint violation *does* cause
undefined behavior (if the program is successfully translated after
the required diagnostic), but I can't find a specific reference.


Mike Wahler had some comments on this...

http://groups.google.com/group/comp....4422af243a43ce
In most cases, the behavior would be undefined by omission.


This violates a constraint on some implementations, but that
notwithstanding, it appears to have well defined semantics on
any conforming C99 implementation. [Assuming no typos...]

#include <stdio.h>
#include <stdint.h>

int main(void)
{
int a;

#ifdef INTPTR_MAX
void *p = &a;
intptr_t i = p; /* constraint violation */
int *q = (void *) i;
#else
int *q = &a;
#endif

*q = 42;
printf("%d\n", a);
}


... A compiler is free to continue processing the translation unit after
issuing a diagnostic for this constraint violation. But you seem to
be assuming that the behavior of
intptr_t i = p;
will be to convert p from void* to intptr_t and assign the result to i.
I see nothing in the standard that supports this assumption.


6.5.16 gives the semantics of assignment.
6.5.16.1p2 says the conversion of p to an intptr_t is implicit in the
assignment.
6.3.2.3p6 says the conversion is allowed, albeit with caveats.
7.18.1.4p1 says the conversion is, in fact, well defined.

Thus, apart from the constraint violation, it's similar to...

unsigned char c = -1L;

An implicit conversion is present and well defined.

--
Peter

Apr 27 '06 #14

P: n/a
"Peter Nilsson" <ai***@acay.com.au> writes:
Keith Thompson wrote:
"Peter Nilsson" <ai***@acay.com.au> writes:
> Keith Thompson wrote:
>> For some reason, I'm thinking that a constraint violation *does* cause
>> undefined behavior (if the program is successfully translated after
>> the required diagnostic), but I can't find a specific reference.
>
> Mike Wahler had some comments on this...
>
> http://groups.google.com/group/comp....4422af243a43ce
>
>> In most cases, the behavior would be undefined by omission.
>
> This violates a constraint on some implementations, but that
> notwithstanding, it appears to have well defined semantics on
> any conforming C99 implementation. [Assuming no typos...]
>
> #include <stdio.h>
> #include <stdint.h>
>
> int main(void)
> {
> int a;
>
> #ifdef INTPTR_MAX
> void *p = &a;
> intptr_t i = p; /* constraint violation */
> int *q = (void *) i;
> #else
> int *q = &a;
> #endif
>
> *q = 42;
> printf("%d\n", a);
> }


... A compiler is free to continue processing the translation unit after
issuing a diagnostic for this constraint violation. But you seem to
be assuming that the behavior of
intptr_t i = p;
will be to convert p from void* to intptr_t and assign the result to i.
I see nothing in the standard that supports this assumption.


6.5.16 gives the semantics of assignment.
6.5.16.1p2 says the conversion of p to an intptr_t is implicit in the
assignment.
6.3.2.3p6 says the conversion is allowed, albeit with caveats.
7.18.1.4p1 says the conversion is, in fact, well defined.

Thus, apart from the constraint violation, it's similar to...

unsigned char c = -1L;

An implicit conversion is present and well defined.


Interesting.

6.5.16.1p1 lists the constraints on the types of the operands; if one
operand is an integer and the other is a pointer, it violates the
constraints.

6.5.16.1p2 says:

In_simple assignment_ (=), the value of the right operand is
converted to the type of the assignment expression and replaces
the value stored in the object designated by the left operand.

I reluctantly agree with your analysis. I wonder if that was the
intent. I think I'll bring it up in comp.std.c.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Apr 27 '06 #15

This discussion thread is closed

Replies have been disabled for this discussion.