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

void vs void* (philosophical question)

P: n/a
According to the standard (ISO C99 draft WG14/N1124), void is the
incomplete type that cannot be completed and comprises the empty set of
values. Since it declares the absense of a value can it be considered a
data type?

Regarding void*, is it just a simple reuse of the same keyword (void) or
they have a closer relationship? I could think of only one - a pointer
to an incomplete type. However, if one could say that void is the
absense of a value, how can we have a pointer to something that does not
exist?
--
one's freedom stops where others' begin

Giannis Papadopoulos
Computer and Communications Engineering dept. (CCED)
University of Thessaly
http://dop.freegr.net/
Jun 30 '06 #1
Share this Question
Share on Google+
18 Replies


P: n/a
Giannis Papadopoulos wrote:
According to the standard (ISO C99 draft WG14/N1124), void is the
incomplete type that cannot be completed and comprises the empty set of
values. Since it declares the absense of a value can it be considered a
data type?

Regarding void*, is it just a simple reuse of the same keyword (void) or
they have a closer relationship? I could think of only one - a pointer
to an incomplete type. However, if one could say that void is the
absense of a value, how can we have a pointer to something that does not
exist?


Here's my best explanation:

A void * is a pointer to (just about) anything. If you dereference a
void *, you might be referring to a 32 bit integer or a 128 bit
floating point value. You might be referring to a structure or a
union. You might be referring to damn near __anything__. In C, you do
the bookkeeping, not the compiler (usually).

Since a void * may point to just about anything, it's safest for the
compiler to treat it as if it points to __nothing in particular__. You
must convert a void * to another pointer type before using it:

#include <stdio.h>

int main(void)
{
int a = 42;
void *p = &a;
printf("%d\n", *(int *) p);
return 0;
}

[mark@icepick]$ gcc -ansi -pedantic -Wall -O2 -o foo foo.c
[mark@icepick]$ ./foo
42
Mark F. Haigh
mf*****@sbcglobal.net

Jun 30 '06 #2

P: n/a
Mark F. Haigh wrote:
Giannis Papadopoulos wrote:
According to the standard (ISO C99 draft WG14/N1124), void is the
incomplete type that cannot be completed and comprises the empty set of
values. Since it declares the absense of a value can it be considered a
data type?

Regarding void*, is it just a simple reuse of the same keyword (void) or
they have a closer relationship? I could think of only one - a pointer
to an incomplete type. However, if one could say that void is the
absense of a value, how can we have a pointer to something that does not
exist?


Here's my best explanation:

A void * is a pointer to (just about) anything. If you dereference a
void *, you might be referring to a 32 bit integer or a 128 bit
floating point value. You might be referring to a structure or a
union. You might be referring to damn near __anything__. In C, you do
the bookkeeping, not the compiler (usually).

Since a void * may point to just about anything, it's safest for the
compiler to treat it as if it points to __nothing in particular__. You
must convert a void * to another pointer type before using it:

#include <stdio.h>

int main(void)
{
int a = 42;
void *p = &a;
printf("%d\n", *(int *) p);
return 0;
}

[mark@icepick]$ gcc -ansi -pedantic -Wall -O2 -o foo foo.c
[mark@icepick]$ ./foo
42
Mark F. Haigh
mf*****@sbcglobal.net


I do not want to know about the usage of void and void*. I want to know
if they have some common meaning, apart from the first 4 letters.

Thanks anyway however.

--
one's freedom stops where others' begin

Giannis Papadopoulos
Computer and Communications Engineering dept. (CCED)
University of Thessaly
http://dop.freegr.net/
Jun 30 '06 #3

P: n/a
Giannis Papadopoulos said:
According to the standard (ISO C99 draft WG14/N1124), void is the
incomplete type that cannot be completed and comprises the empty set of
values. Since it declares the absense of a value can it be considered a
data type?

Regarding void*, is it just a simple reuse of the same keyword (void)
Yes.
or they have a closer relationship? I could think of only one - a pointer
to an incomplete type.
Apart from that, they pretty much mean *opposite* things. void means
"nothing", and void * means "pointer to anything" (in the "whaddya mean,
what am I pointing at? How should I know?" sense).
However, if one could say that void is the
absense of a value, how can we have a pointer to something that does not
exist?


If void means "absence of value", surely void * means "a pointer which you
can't dereference because to do so would yield the absence of a value".

But yes, it's sticky-icky. I'd have bitten the bullet and introduced a new
keyword, e.g. object, which I'd have used to replace void in pointer
contexts. Thus: object *malloc(size_t), etc.

You can do this easily enough in your own code with:

#define object void /* possible; just not very wise */

But I am NOT advocating this! :-) If the language supported it, that would
be different, but it doesn't.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 30 '06 #4

P: n/a
Giannis Papadopoulos wrote:
Mark F. Haigh wrote:
Giannis Papadopoulos wrote:
According to the standard (ISO C99 draft WG14/N1124), void is the
incomplete type that cannot be completed and comprises the empty set of
values. Since it declares the absense of a value can it be considered a
data type?

Regarding void*, is it just a simple reuse of the same keyword (void) or
they have a closer relationship? I could think of only one - a pointer
to an incomplete type. However, if one could say that void is the
absense of a value, how can we have a pointer to something that does not
exist?


I do not want to know about the usage of void and void*. I want to know
if they have some common meaning, apart from the first 4 letters.


My 2 pence: void is an incomplete type, a pointer to the incomplete
type must be able to point to any possible object, therefore void *
must be the generic pointer.

Consider analogously the pointer to an incomplete struct.

--
imalone
Jun 30 '06 #5

P: n/a
On 2006-06-30, Giannis Papadopoulos <ip******@inf.uth.gr> wrote:
Mark F. Haigh wrote:
Giannis Papadopoulos wrote:
According to the standard (ISO C99 draft WG14/N1124), void is the
incomplete type that cannot be completed and comprises the empty set of
values. Since it declares the absense of a value can it be considered a
data type?

Regarding void*, is it just a simple reuse of the same keyword (void) or
they have a closer relationship? I could think of only one - a pointer
to an incomplete type. However, if one could say that void is the
absense of a value, how can we have a pointer to something that does not
exist?

Here's my best explanation:

A void * is a pointer to (just about) anything. If you dereference a
void *, you might be referring to a 32 bit integer or a 128 bit
floating point value. You might be referring to a structure or a
union. You might be referring to damn near __anything__. In C, you do
the bookkeeping, not the compiler (usually).

Since a void * may point to just about anything, it's safest for the
compiler to treat it as if it points to __nothing in particular__. You
must convert a void * to another pointer type before using it:


[snip]
I do not want to know about the usage of void and void*. I want to know
if they have some common meaning, apart from the first 4 letters.

Thanks anyway however.


I think Mark F. Haigh has elucidated this a bit: "void" means "nothing",
"void *" means "pointer to anything".

Anything != nothing, although anything ~= "nothing in particular". So
they're not the same void. But closely related ideas, so we use the same
keyword.

void * is not quite consistent with void as follows:

int *p;

can be read as "p is a pointer and *p is an int". But:

void *p;

"p is a pointer [true] and *p is a void [false]"
Jun 30 '06 #6

P: n/a
Giannis Papadopoulos wrote:

According to the standard (ISO C99 draft WG14/N1124),
void is the incomplete type that cannot be completed
and comprises the empty set of values.
Since it declares the absense of a value can it be considered a
data type?


No.

sizeof(void) is undefined.
You can't declare an object of type void.
You can't have an array of type void elements.
An expression of type void can neither be
the left nor right operand of the assignment operator.

--
pete
Jun 30 '06 #7

P: n/a
Ben C wrote:
void * is not quite consistent with void as follows:

int *p;

can be read as "p is a pointer and *p is an int". But:

void *p;

"p is a pointer [true] and *p is a void [false]"


[true] and [true], actually. *p is a valid expression of type void, and
&*p evaluates to p. (Of course, it's pointless to do this except for
very special cases.)

Jun 30 '06 #8

P: n/a
Giannis Papadopoulos schrieb:
According to the standard (ISO C99 draft WG14/N1124), void is the
incomplete type that cannot be completed and comprises the empty set of
values. Since it declares the absense of a value can it be considered a
data type?

Regarding void*, is it just a simple reuse of the same keyword (void) or
they have a closer relationship? I could think of only one - a pointer
to an incomplete type. However, if one could say that void is the
absense of a value, how can we have a pointer to something that does not
exist?


Its logical if you think about it in terms of set theorie.

Think of two structs:

struct person
{
char* name;
};
struct worker
{
char* name;
char* job;
};

A pointer person* can point to a struct person and to a struct worker,
so it is a pointer to "at least a person".

A void* is a pointer to "at least nothing", so it can't point to
effectively everything.

Thomas
Jun 30 '06 #9

P: n/a
In article <e8**********@volcano1.grnet.gr>
Giannis Papadopoulos <ip******@inf.uth.gr> wrote:
According to the standard (ISO C99 draft WG14/N1124), void is the
incomplete type that cannot be completed and comprises the empty set of
values. Since it declares the absense of a value can it be considered a
data type?
In a larger, "not Standard C" sense, yes. In Standard C, however,
types are partitioned into "object types", "function types", and
"incomplete types". (The Standard does not define "data type" but
logically it would appear to map to "object type". Interestingly,
my C99 draft *uses* the phrase "data types" in the description of
<wchar.h>, in paragraph 1 of section 7.19.1. It is clear enough
that it does not mean "incomplete types" here. Perhaps the phrasing
was changed in the final standard, though.)

(If I were in charge of things, I would probably make "void" an
ordinary object type whose size is zero, so that sizeof(void) ==
0; its value, upon conversion to any other scalar type, would be
zero. Thus:

void v, *pv = &v;
printf("%d %d\n", v, *pv);

would print "0 0\n". :-) Of course, I would also add zero-sized
arrays:

int a[0], b;

with the allowance -- but not requirement -- that &a[0] == &b. Then
I might also remove the "flexible array member" and simply bless the
Struct Hack.)
Regarding void*, is it just a simple reuse of the same keyword (void) or
they have a closer relationship?


As most others have said, it is just reuse of the keyword.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jun 30 '06 #10

P: n/a
Chris Torek wrote:
[...]
(If I were in charge of things, I would probably make "void" an
ordinary object type whose size is zero, so that sizeof(void) ==
0; its value, upon conversion to any other scalar type, would be
zero. Thus:

[...]

How would you handle functions which don't return anything?

void foo()
{
void retval;

... do stuff ...

return retval;
}

And how would you resolve the use of an uninitialized variable for
the return?

Would you allow comparing voids, and void arithmetic?

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

Jun 30 '06 #11

P: n/a
>Chris Torek wrote:
(If I were in charge of things, I would probably make "void" an
ordinary object type whose size is zero, so that sizeof(void) ==
0; its value, upon conversion to any other scalar type, would be
zero. Thus:

In article <44***************@spamcop.net>
Kenneth Brody <ke******@spamcop.net> wrote:How would you handle functions which don't return anything?

void foo()
{
void retval;

... do stuff ...

return retval;
}
Legal, if unnecessarily verbose.
And how would you resolve the use of an uninitialized variable for
the return?
Since objects of type "void" have no bits, it does not matter whether
you initialize them. Their "apparent value" would always be zero.
Assigning any value to a "void" variable throws away its value;
Would you allow comparing voids,
Sure:

void a, b;
if (a == b) /* means "if (0 == 0)" */
...
and void arithmetic?


Yes, with the caveat that any "void" object is alwys zero, so you
cannot divide by a "void":

a + b /* 0 + 0 */
a * 42 /* 0 * 42 */
a / 3 /* 0 / 3 */
a / b /* error, division by zero */

Also, since sizeof(a) == 0 and sizeof(b) == 0, it is possible (but
not required) that &a == &b (or indeed, &a == &anyothervar).

Since sizeof(void) == 0, in this not-quite-C language, arithmetic
on "void *" is also well-defined, and causes nothing to happen:

void *p = malloc(100), *q;
int k = 12;

if (p == NULL) ... handle error ...
q = p + k;
if (q == p)
printf("always true\n");
else
abort();

I think most compilers would warn about arithmetic on "void *",
since the fact that "q = p + k" means the same thing as "q = p"
means that it is not useful to add anything to "p" here. But it
would be allowed.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jun 30 '06 #12

P: n/a
Chris Torek <no****@torek.net> writes:
In article <e8**********@volcano1.grnet.gr>
Giannis Papadopoulos <ip******@inf.uth.gr> wrote:
According to the standard (ISO C99 draft WG14/N1124), void is the
incomplete type that cannot be completed and comprises the empty set of
values. Since it declares the absense of a value can it be considered a
data type?


In a larger, "not Standard C" sense, yes. In Standard C, however,
types are partitioned into "object types", "function types", and
"incomplete types". (The Standard does not define "data type" but
logically it would appear to map to "object type". Interestingly,
my C99 draft *uses* the phrase "data types" in the description of
<wchar.h>, in paragraph 1 of section 7.19.1. It is clear enough
that it does not mean "incomplete types" here. Perhaps the phrasing
was changed in the final standard, though.)


Are you sure about that section number? In both n869 and the final
standard, 7.19 is <stdio.h>; <wchar.h> is 7.24.

In the C99 standard, 7.19.1p1 says:

The header <stdio.h> declares three types, several macros, and
many functions for performing input and output.

and 7.24.1p1 says:

The header <wchar.h> declares four data types, one tag, four
macros, and many functions.

--
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.
Jun 30 '06 #13

P: n/a
Chris Torek <no****@torek.net> writes:
Chris Torek wrote:
(If I were in charge of things, I would probably make "void" an
ordinary object type whose size is zero, so that sizeof(void) ==
0; its value, upon conversion to any other scalar type, would be
zero. Thus:


In article <44***************@spamcop.net>
Kenneth Brody <ke******@spamcop.net> wrote:
How would you handle functions which don't return anything?

void foo()
{
void retval;

... do stuff ...

return retval;
}


Legal, if unnecessarily verbose.
And how would you resolve the use of an uninitialized variable for
the return?


Since objects of type "void" have no bits, it does not matter whether
you initialize them. Their "apparent value" would always be zero.
Assigning any value to a "void" variable throws away its value;
Would you allow comparing voids,


Sure:

void a, b;
if (a == b) /* means "if (0 == 0)" */
...
and void arithmetic?


Yes, with the caveat that any "void" object is alwys zero, so you
cannot divide by a "void":

a + b /* 0 + 0 */
a * 42 /* 0 * 42 */
a / 3 /* 0 / 3 */
a / b /* error, division by zero */

Also, since sizeof(a) == 0 and sizeof(b) == 0, it is possible (but
not required) that &a == &b (or indeed, &a == &anyothervar).

Since sizeof(void) == 0, in this not-quite-C language, arithmetic
on "void *" is also well-defined, and causes nothing to happen:

void *p = malloc(100), *q;
int k = 12;

if (p == NULL) ... handle error ...
q = p + k;
if (q == p)
printf("always true\n");
else
abort();

I think most compilers would warn about arithmetic on "void *",
since the fact that "q = p + k" means the same thing as "q = p"
means that it is not useful to add anything to "p" here. But it
would be allowed.


I think your not-quite-C language is consistent, or can be made so.
But the major difference between real C and your not-quite-C is that
your language allows certain operations that C doesn't -- and as far
as I can tell, few if any of the additional allowed operations are
useful. (Unless I've missed something, which is always a
possibility.)

--
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.
Jun 30 '06 #14

P: n/a
"Kenneth Brody" <ke******@spamcop.net> wrote in message
news:44***************@spamcop.net...
Chris Torek wrote:
[...]
(If I were in charge of things, I would probably make "void" an
ordinary object type whose size is zero, so that sizeof(void) ==
0; its value, upon conversion to any other scalar type, would be
zero. Thus: [...]

How would you handle functions which don't return anything?

void foo()
{
void retval;

... do stuff ...

return retval;
}


They return void, which is valueless.
And how would you resolve the use of an uninitialized variable for
the return?
Since it's impossible for a void variable to hold any value, all void
variables are initialized by merely declaring them.
Would you allow comparing voids, and void arithmetic?


IMHO, the result of any void comparison or arithmetic is necessarily void,
and could only be assigned to a void variable. Likewise, dereferencing a
void* would result in an expression of type void, which couldn't be assigned
except to a void variable.

Chris diverges from my take, as he appears to consider void an integral type
with no value bits (and possibly no padding bits either), so that if it's
used in a context that requires another integer type, it is promoted to 0.
If you assign a non-void to a void variable, the same rules would apply as
trying to assign INT_MAX+1 to an int.

Either way, I don't see any reason a compiler would do anything with a void
variable other than optimize it out of existence. None of this has any use
other than trying to explain what relation (void*) has to (void).

S

--
Stephen Sprunk "Stupid people surround themselves with smart
CCIE #3723 people. Smart people surround themselves with
K5SSS smart people who disagree with them." --Aaron Sorkin
--
Posted via a free Usenet account from http://www.teranews.com

Jun 30 '06 #15

P: n/a
>Chris Torek <no****@torek.netwrites:
>my C99 draft *uses* the phrase "data types" in the description of
<wchar.h>, in paragraph 1 of section 7.19.1. ...
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>Are you sure about that section number? In both n869 and the final
standard, 7.19 is <stdio.h>; <wchar.his 7.24.
My draft is considerably older than those two.

(It is, however, in plain-text, a format I find much more suitable
in general.)
>In the C99 standard, 7.19.1p1 says:

The header <stdio.hdeclares three types, several macros, and
many functions for performing input and output.

and 7.24.1p1 says:

The header <wchar.hdeclares four data types, one tag, four
macros, and many functions.
Yes; but the rest of the standard appears not to define the term
"data type" (thus leaving it to other included standards).
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jul 3 '06 #16

P: n/a
Chris Torek wrote:
Chris Torek wrote:
(If I were in charge of things, I would probably make "void" an
ordinary object type whose size is zero, so that sizeof(void) ==
0; its value, upon conversion to any other scalar type, would be
zero. Thus:

In article <44***************@spamcop.net>
Kenneth Brody <ke******@spamcop.netwrote:
How would you handle functions which don't return anything?

void foo()
{
void retval;

... do stuff ...

return retval;
}

Legal, if unnecessarily verbose.
And how would you resolve the use of an uninitialized variable for
the return?

Since objects of type "void" have no bits, it does not matter whether
you initialize them. Their "apparent value" would always be zero.
Assigning any value to a "void" variable throws away its value;
Would you allow comparing voids,

Sure:

void a, b;
if (a == b) /* means "if (0 == 0)" */
...
and void arithmetic?

Yes, with the caveat that any "void" object is alwys zero, so you
cannot divide by a "void":

a + b /* 0 + 0 */
a * 42 /* 0 * 42 */
a / 3 /* 0 / 3 */
a / b /* error, division by zero */

Also, since sizeof(a) == 0 and sizeof(b) == 0, it is possible (but
not required) that &a == &b (or indeed, &a == &anyothervar).

Since sizeof(void) == 0, in this not-quite-C language, arithmetic
on "void *" is also well-defined, and causes nothing to happen:
Continuing from where Kenneth Brody left off.
<tongue-in-cheek>
What about the logical operations on void-of-the-TorekC? In case you
allow them too; we'd no longer need `bool' -- would we?
</tongue-in-cheek>

Jul 3 '06 #17

P: n/a
pete wrote:
sizeof(void) is undefined.
It is defined to be a violation of the constraint "The sizeof operator
shall not be applied to an expression that has ... an incomplete type,
to the parenthesized name of such a type, or ..."; so it's prohibited.
--
Dietmar
Jul 6 '06 #18

P: n/a
On 30 Jun 2006 19:15:34 GMT, Chris Torek <no****@torek.netwrote:
Chris Torek wrote:
(If I were in charge of things, I would probably make "void" an
ordinary object type whose size is zero, so that sizeof(void) ==
0; its value, upon conversion to any other scalar type, would be
zero. Thus:

In article <44***************@spamcop.net>
Kenneth Brody <ke******@spamcop.netwrote:
How would you handle functions which don't return anything?

void foo()
{
void retval;

... do stuff ...

return retval;
}

Legal, if unnecessarily verbose.
FWIW, <OTC++ </does allow a void function to have a return
statement with an expression of void type. Primarily AFAICT for
regularity in (uses aka instantiations of) templates.
And how would you resolve the use of an uninitialized variable for
the return?

Since objects of type "void" have no bits, it does not matter whether
you initialize them. Their "apparent value" would always be zero.
Assigning any value to a "void" variable throws away its value;
So would any void expression be a null pointer constant? <gd&r>

<snip rest>

- David.Thompson1 at worldnet.att.net
Jul 10 '06 #19

This discussion thread is closed

Replies have been disabled for this discussion.