Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Void variables

103 views
Skip to first unread message

Raj Pashwar

unread,
May 21, 2012, 5:53:26 PM5/21/12
to
Hello

I would like to define a variable of void type. However I get compiler
errors:

void x; // error: variable or field ‘x’ declared void

Infact there is a typedef and I want to allow the defined type to be,
void. However, the error is the same.

Thankyou

John Gordon

unread,
May 21, 2012, 6:05:39 PM5/21/12
to
I believe you are only allowed to declare void pointers, not plain voids.

This is allowable:

void *x;

But not this:

void x;

--
John Gordon A is for Amy, who fell down the stairs
gor...@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"

Ike Naar

unread,
May 21, 2012, 6:07:02 PM5/21/12
to
On 2012-05-21, Raj Pashwar <raj1...@hotmail.NOSPAM.com> wrote:
> I would like to define a variable of void type.

How would such a variable be useful?

Ian Collins

unread,
May 21, 2012, 6:09:55 PM5/21/12
to
void is an incomplete type. You can't do anything with one, so why
would you want one?

--
Ian Collins

Joe Pfeiffer

unread,
May 21, 2012, 6:17:06 PM5/21/12
to
As others have pointed out, you can't do this. This is one of those
questions that leads me to believe that there's something else you're
actually trying to do, and declaring a variable of type void seems like
a way to achive that underlying goal. So... what are you really trying
to do?

Kenny McCormack

unread,
May 21, 2012, 6:22:30 PM5/21/12
to
In article <a1vspk...@mid.individual.net>,
I wonder if the goal was to get access to what in some languages (*) is
referred to as "WORD" - that is, something that isn't really an int or an
unsigned or anything else - but is just a unit of memory of whatever size
the native word size on the machine is. I think BCPL (a C ancestor) had
this.

(*) Or C with MS's Windows defines in place.

--
Just for a change of pace, this sig is *not* an obscure reference to
comp.lang.c...

James Kuyper

unread,
May 21, 2012, 6:24:09 PM5/21/12
to
You're making essentially the same fundamental conceptual mistake as a
little child who says "I want a nothing. Give me a nothing! Why won't
you give me a nothing?"

Why do you think that you'd like to define a variable of void type? What
would you expect to be able to do with it? We won't be able to show you
how to define an object of void type, there's no such thing. However, if
we know what you wanted to do with it, we could probably suggest
alternative ways of achieving the same goals.

Kaz Kylheku

unread,
May 21, 2012, 10:18:21 PM5/21/12
to
Furthermore, among what domain values would it vary?

--
If you ever need any coding done, I'm your goto man!

88888 Dihedral

unread,
May 22, 2012, 2:17:50 AM5/22/12
to
John Gordon於 2012年5月22日星期二UTC+8上午6時05分39秒寫道:
The type void * is useful for holding an address that supports the polymorphism in the types of the content poined by a pointer in the run time.

nick_keigh...@hotmail.com

unread,
May 22, 2012, 3:15:32 AM5/22/12
to
there is no such thing as a void type. What do you think it means. If you explain we might be able to tell you how to achieve what you want some other way.

nick_keigh...@hotmail.com

unread,
May 22, 2012, 3:18:00 AM5/22/12
to
On Monday, May 21, 2012 11:22:30 PM UTC+1, Kenny McCormack wrote:
> In article <a1vspk...@mid.individual.net>,
> Ian Collins <ian-...@hotmail.com> wrote:
> >On 05/22/12 09:53 AM, Raj Pashwar wrote:
> >> Hello
> >>
> >> I would like to define a variable of void type. However I get compiler
> >> errors:
> >>
> >> void x; // error: variable or field ‘x’ declared void
> >>
> >> Infact there is a typedef and I want to allow the defined type to be,
> >> void. However, the error is the same.
> >
> >void is an incomplete type. You can't do anything with one, so why
> >would you want one?
>
> I wonder if the goal was to get access to what in some languages (*) is
> referred to as "WORD" - that is, something that isn't really an int or an
> unsigned or anything else - but is just a unit of memory of whatever size
> the native word size on the machine is. I think BCPL (a C ancestor) had
> this.

yes. But that's really *all* it had. int is probably C's nearest approach to a Word.

> (*) Or C with MS's Windows defines in place.

not really

BartC

unread,
May 22, 2012, 5:32:24 AM5/22/12
to
"Kaz Kylheku" <k...@kylheku.com> wrote in message
news:201205211...@kylheku.com...
> On 2012-05-21, Ike Naar <i...@iceland.freeshell.org> wrote:
>> On 2012-05-21, Raj Pashwar <raj1...@hotmail.NOSPAM.com> wrote:
>>> I would like to define a variable of void type.
>>
>> How would such a variable be useful?
>
> Furthermore, among what domain values would it vary?

It wouldn't have any values. Or rather, it would only have one. Since it's
value can then always be implied, it wouldn't actually need any memory.

That means an array of 1000000 (or even SIZE_MAX) void values would use zero
bytes.

I can see this being useful as a marker, in a list of struct fields, or in a
parameter list. So If a struct has fields a,b,c,d,e, then printing them
might give:

(1200, 6, void, 5.6, 0)

when c is void. It doesn't look like it adds any useful information, but
it's presence, and the fact it could be any of the five, does provide
something extra. So if b was void instead, then the output might be:

(1200, void, 6, 5.6, 0)

In both cases, the bit-pattern is the same. Of course, it can only vary
between one compilation and the next, not during at runtime, but that
applies also to a lot of conditional macro preprocessor code.

It can also be made slightly more useful, with a directive to map a void
'value' to a specific numeric or string constant:

#pragma void is 42

void x;

printf("X is %d\n",x);

will display "42".

--
Bartc


Eric Sosman

unread,
May 22, 2012, 8:14:34 AM5/22/12
to
The void type certainly exists, and is described by 6.2.5p19:

"The void type comprises an empty set of values; it is an
incomplete object type that cannot be completed."

ITYM there is no such thing as a void *object*, hence no such thing
as a void variable, an array of voids, and so on.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Stephen Sprunk

unread,
May 22, 2012, 9:15:42 AM5/22/12
to
On 22-May-12 04:32, BartC wrote:
> "Kaz Kylheku" <k...@kylheku.com> wrote in message
> news:201205211...@kylheku.com...
>> On 2012-05-21, Ike Naar <i...@iceland.freeshell.org> wrote:
>>> On 2012-05-21, Raj Pashwar <raj1...@hotmail.NOSPAM.com> wrote:
>>>> I would like to define a variable of void type.
>>>
>>> How would such a variable be useful?
>>
>> Furthermore, among what domain values would it vary?
>
> It wouldn't have any values. Or rather, it would only have one. Since
> it's value can then always be implied, it wouldn't actually need any
> memory.
>
> That means an array of 1000000 (or even SIZE_MAX) void values would use
> zero bytes.

I don't think that's possible since pointers to different objects must
compare unequal. Likewise, offsets of different members of a struct
must be unique. Finally, given that the representation of a (void *)
must be the same as the representation of a (char *), it would seem most
logical for sizeof(void) to be 1, with zero value bits and CHAR_BIT
padding bits.

> It can also be made slightly more useful, with a directive to map a void
> 'value' to a specific numeric or string constant:
>
> #pragma void is 42
>
> void x;
>
> printf("X is %d\n",x);
>
> will display "42".

I have a serious problem with that. AFAIK, every other type must be
able to represent the value 0, and (void) should as well. It's just
that a (void) couldn't represent any _other_ value.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking

James Kuyper

unread,
May 22, 2012, 9:28:58 AM5/22/12
to
On 05/22/2012 05:32 AM, BartC wrote:
> "Kaz Kylheku" <k...@kylheku.com> wrote in message
> news:201205211...@kylheku.com...
>> On 2012-05-21, Ike Naar <i...@iceland.freeshell.org> wrote:
>>> On 2012-05-21, Raj Pashwar <raj1...@hotmail.NOSPAM.com> wrote:
>>>> I would like to define a variable of void type.
>>>
>>> How would such a variable be useful?
>>
>> Furthermore, among what domain values would it vary?
>
> It wouldn't have any values. Or rather, it would only have one.

You were right the first time. "one value" is one more than the number
specified by the standard: "The void type comprises an empty set of
values" (6.2.5p19).

BartC

unread,
May 22, 2012, 12:08:42 PM5/22/12
to


"James Kuyper" <james...@verizon.net> wrote in message
news:4FBB949...@verizon.net...
An 8-bit type has 256 distinct values. An N-bit one would have 2**N values.

Since a 'void' type would have zero bits, that suggests it would have 2**0
values, or just one.

--
Bartc

Barry Schwarz

unread,
May 22, 2012, 12:19:15 PM5/22/12
to
You are assuming the function is continuous over the number of bits.
The standard clearly states it is not continuous at the value N = 0.

--
Remove del for email

James Kuyper

unread,
May 22, 2012, 12:25:08 PM5/22/12
to
On 05/22/2012 12:08 PM, BartC wrote:
>
>
> "James Kuyper" <james...@verizon.net> wrote in message
> news:4FBB949...@verizon.net...
>> On 05/22/2012 05:32 AM, BartC wrote:
[Re: an object of void type]
>>> It wouldn't have any values. Or rather, it would only have one.
>>
>> You were right the first time. "one value" is one more than the number
>> specified by the standard: "The void type comprises an empty set of
>> values" (6.2.5p19).
>
> An 8-bit type has 256 distinct values. An N-bit one would have 2**N values.
>
> Since a 'void' type would have zero bits, that suggests it would have 2**0
> values, or just one.

The standard does not say that objects of void type require zero bits;
it says that objects cannot have that type. It does say that "The void
type comprises an empty set of values", so inverting your argument, that
would suggest that an object of void type should contain -INFINITY bits.
That presents certain practical problems :-), so I suppose that's one
reason why we're not allowed to create such an object.

BartC

unread,
May 22, 2012, 12:30:59 PM5/22/12
to


"James Kuyper" <james...@verizon.net> wrote in message
news:4FBBBDE4...@verizon.net...
So a void type is just the empty set of values { }.

But the empty set is itself a value. So the empty set must contain itself:
{{{...}}}.

There seems to be some paradox here.

--
Bartc

James Kuyper

unread,
May 22, 2012, 1:00:12 PM5/22/12
to
On 05/22/2012 12:30 PM, BartC wrote:
>
>
> "James Kuyper" <james...@verizon.net> wrote in message
> news:4FBBBDE4...@verizon.net...
...
>> The standard does not say that objects of void type require zero bits;
>> it says that objects cannot have that type. It does say that "The void
>> type comprises an empty set of values", so inverting your argument, that
>> would suggest that an object of void type should contain -INFINITY bits.
>> That presents certain practical problems :-), so I suppose that's one
>> reason why we're not allowed to create such an object.
>
> So a void type is just the empty set of values { }.
>
> But the empty set is itself a value. So the empty set must contain itself:
> {{{...}}}.
>
> There seems to be some paradox here.

No, just a problem with your logic.

You could define a type that includes the empty set among it's
representable values - such a type could be useful for applications
involving set theory. However, the C standard says that the set of
values of void type is empty, so in particular, it cannot include the
empty set itself as a value.

Maybe that argument would be clearer if I used a non-void type for a
comparison. The set of values that comprise the 'int' type is the
integers from INT_MIN to INT_MAX; that set is not, itself, one of the
values contained in that set; all of the members of that set are
integers, none of them are sets of integers.

Your conclusion that "the empty set must contain itself" is wrong; it
wouldn't be "the empty set" if that conclusion were true. There are
people here with a stronger mathematical background than I have; I hope
that one of them can explain more precisely than I can what's wrong with
that conclusion.

You don't explain how you went from your premise to your conclusion.
Even if the premise were correct, I can't come up with any valid
argument connecting it to your conclusion.

Tim Rentsch

unread,
May 22, 2012, 5:53:26 PM5/22/12
to
James Kuyper <james...@verizon.net> writes:

> On 05/22/2012 12:08 PM, BartC wrote:
>>
>>
>> "James Kuyper" <james...@verizon.net> wrote in message
>> news:4FBB949...@verizon.net...
>>> On 05/22/2012 05:32 AM, BartC wrote:
> [Re: an object of void type]
>>>> It wouldn't have any values. Or rather, it would only have one.
>>>
>>> You were right the first time. "one value" is one more than the number
>>> specified by the standard: "The void type comprises an empty set of
>>> values" (6.2.5p19).
>>
>> An 8-bit type has 256 distinct values. An N-bit one would have 2**N values.
>>
>> Since a 'void' type would have zero bits, that suggests it would have 2**0
>> values, or just one.
>
> The standard does not say that objects of void type require zero bits;
> it says that objects cannot have that type. [snip]

It doesn't, at least not that I could find. More specifically,
AFAICT the following program

int
main(){
void x;
return 0;
}

may be accepted by a conforming implementation, with
no diagnostic messages required.

Joe Pfeiffer

unread,
May 22, 2012, 6:43:09 PM5/22/12
to
If I'm reading correctly:

6.2.5 Types
19 The void type comprises an empty set of values; it is an incomplete
object type that cannot be completed.

6.7.2.1 Structure and union specifiers
3 A structure or union shall not contain a member with incomplete or
function type (hence, a structure shall not contain an instance of
itself, but may contain a pointer to an instance of itself), except
that the last member of a structure with more than one named member
may have incomplete array type; such a structure (and any union
containing, possibly recursively, a member that is such a structure)
shall not be a member of a structure or an element of an array.

5.1.1.3 Diagnostics
1 A conforming implementation shall produce at least one diagnostic
message (identified in an implementation-defined manner) if a
preprocessing translation unit or translation unit contains a
violation of any syntax rule or constraint, even if the behavior is
also explicitly specified as undefined or
implementation-defined. Diagnostic messages need not be produced in
other circumstances.

Tim Rentsch

unread,
May 22, 2012, 7:14:03 PM5/22/12
to
The example program has no structs or unions in
it, so 6.7.2.1 doesn't apply.

Jens Gustedt

unread,
May 23, 2012, 1:27:34 AM5/23/12
to
Am 23.05.2012 01:14, schrieb Tim Rentsch:
> The example program has no structs or unions in
> it, so 6.7.2.1 doesn't apply.

But 6.7 para 7 applies

If an identifier for an object is declared with no linkage, the type for
the object shall be
complete by the end of its declarator, or by the end of its
init-declarator if it has an
initializer; in the case of function parameters (including in
prototypes), it is the adjusted
type (see 6.7.6.3) that is required to be complete.

Jens

Hans Vlems

unread,
May 23, 2012, 2:32:10 AM5/23/12
to
On 22 mei, 00:17, Joe Pfeiffer <pfeif...@cs.nmsu.edu> wrote:
Writing obfuscated C very likely.
Hans

somenath

unread,
May 23, 2012, 3:05:57 AM5/23/12
to
Out my curiosity when I compiled the following program I did not get
any diagnostic for the incomplete type. So Will v be treated as
complete type then ?

int main(void)
{
extern void v;

return 0;
}

$ gcc -ansic -pedantic -Wall voidTest.c
voidTest.c: In function `main':
voidTest.c:5: warning: unused variable `v'


Also please see the following program
#include<stdio.h>

extern void v;

int main(void)
{
int v = 2;
printf("Value of v = %d\n",v);
return 0;
}

The Out put is
Value of v = 2
So is the type of v getting changed dynamically from incomplete to
complete type ?

Vallabha

unread,
May 23, 2012, 9:10:23 AM5/23/12
to
On May 22, 2:53 am, Raj Pashwar <raj121...@hotmail.NOSPAM.com> wrote:
> Hello
>
> I would like to define a variable of void type. However I get compiler
> errors:
>
> void x; // error: variable or field ‘x’ declared void
>
> Infact there is a typedef and I want to allow the defined type to be,
> void. However, the error is the same.
>
> Thankyou

You can only declare pointers of type void *. In my understanding when
we declare a variable of some type (int/float etc) compiler knows how
much space has to be set aside for this variable. However compiler
will have no clue how much space is required for a void variable.

Cheers,
-Vallabha

Tim Rentsch

unread,
May 23, 2012, 9:34:19 AM5/23/12
to
This paragraph is listed under Semantics, not Constraints. The
example program has undefined behavior, but it is still an
admissible program, ie, acceptable with no diagnostics by a
conforming implementation, under which its behavior could
be defined by the implementation to be something perfectly
reasonable.

David T. Ashley

unread,
May 23, 2012, 9:41:41 AM5/23/12
to
On Mon, 21 May 2012 21:53:26 +0000 (UTC), Raj Pashwar
<raj1...@hotmail.NOSPAM.com> wrote:

>Hello
>
>I would like to define a variable of void type. However I get compiler
>errors:
>
>void x; // error: variable or field ‘x’ declared void
>
>Infact there is a typedef and I want to allow the defined type to be,
>void. However, the error is the same.
>
>Thankyou

The other posters are wrong.

You can declare a void variable in C, just like this:

void x;

But, the variable doesn't occupy any storage, and can't be printed or
assigned to another variable.

A "void" variable can only be used in two ways:

a)It can be assigned the return value of a function that doesn't
actually return a value. (That is why a function is defined to return
"void"--you can assign its return value only to a "void" variable.)

b)The "void" variable can be passed in the paramter list of a function
that has no parameters.

Here is a small program illustrating the proper usage of a void
variable.

void x;

void a(int a)
{
}

int b(void)
{
return(0);
}


int main(void)
{
int rv;

x = a(3);
rv = b(x);
}

DTA

Eric Sosman

unread,
May 23, 2012, 9:53:04 AM5/23/12
to
On 5/23/2012 9:41 AM, David T. Ashley wrote:
> On Mon, 21 May 2012 21:53:26 +0000 (UTC), Raj Pashwar
> <raj1...@hotmail.NOSPAM.com> wrote:
>
>> Hello
>>
>> I would like to define a variable of void type. However I get compiler
>> errors:
>>
>> void x; // error: variable or field ‘x’ declared void
>>
>> Infact there is a typedef and I want to allow the defined type to be,
>> void. However, the error is the same.
>>
>> Thankyou
>
> The other posters are wrong.
>
> You can declare a void variable in C, just like this:
>
> void x;

Hmmm. When I put that into a one-line source file, gcc says

foo.c:1: error: storage size of 'x' isn't known
Compilation exited abnormally with code 1 at Wed May 23 09:44:17

So: gcc bug?

> Here is a small program illustrating the proper usage of a void
> variable.
>
> void x;
>
> void a(int a)
> {
> }
>
> int b(void)
> {
> return(0);
> }
>
>
> int main(void)
> {
> int rv;
>
> x = a(3);
> rv = b(x);
> }

gcc has even more to say about this one:

foo.c: In function 'main':
foo.c:17: error: 'x' has an incomplete type
foo.c:18: error: too many arguments to function 'b'
Compilation exited abnormally with code 1 at Wed May 23 09:48:28

Another gcc bug? Perhaps you should contact the gcc people and
give them the benefit of your superior knowledge of C.

Or maybe, just maybe, "the other posters are wrong" is wrong.

--
Eric Sosman
eso...@ieee-dot-org.invalid

David T. Ashley

unread,
May 23, 2012, 10:04:32 AM5/23/12
to
Think about it ... why would the C language designers have allowed the
return type of "void" unless they wanted this to be assignable to a
variable of type "void"?

This is just common sense.

The gcc compiler writers can't be trusted. They are conspiring even
at this moment with the remnants of the Stasi to conduct weather
modification experiments in the upper atmosphere.

I propose that we trust Archimedes Plutonium to arbitrate this
disagreement? Surely the answer is already embedded in the properties
of the plutonium atom ...

DTA

Bartc

unread,
May 23, 2012, 6:41:26 PM5/23/12
to
"David T. Ashley" <das...@gmail.com> wrote in message
news:tbrpr75iq09rih7j9...@4ax.com...


> Think about it ... why would the C language designers have allowed the
> return type of "void" unless they wanted this to be assignable to a
> variable of type "void"?

Because C uses a 'void' type to identify those functions which are really
procedures.

It further overloads 'void' in a function signature, to specify functions
(or procedures) with 0 parameters, rather than an unknown number.

I agree C could have maybe done more with 'void', after having invented it.

--
Bartc


Eric Sosman

unread,
May 23, 2012, 6:34:55 PM5/23/12
to
"Hysterical raisins."

Original C had no `void' type at all. A function returning no
value simply omitted specifying a return type (which formally declared
that it returned `int'), and the caller simply knew to ignore whatever
garbage happened to land in the conventional place for `int' results.

Also, malloc() et al. were usually declared as returning `char*'
("usually," because the usual suite of system-provided headers usually
had no malloc() declaration). This may be why we still see people
applying casts to malloc() results: In the days when the results
were `char*' and needed to be assigned to a `struct foo*', the cast
was in fact necessary.

A third thing: In original C, there was no way to describe a
function's parameter list to its callers. You simply said "This is
a function returning a `foobar'; read the documentation if you
want to know how to call it. (Oh, yeah, I'll write the documentation
Real Soon Now.)"

Along came the Committee that developed the ANSI Standard, and
they saw that "ignore the `int' that wasn't returned" was fragile, and
could even be burdensome for some implementations (they might need to
set aside a place for the non-existent result, or might need to use
up a CPU register to not hold it). They also wanted to fix up the
cast-malloc() mess, and to borrow the C++ idea of describing the
parameter lists in a way the compiler could use. And thus were born
the three uses of `void':

- You could declare a function as "returning `void'", which truly
means it returns nothing at all. (No, not even a vacuous value.)
Hooray! C got procedures that were recognizable as such.

- You could declare pointers to the non-instantiable `void' type,
and then you could introduce special rules for silent conversion of
such pointers to all other data pointer types. Hooray! All those
malloc() casts became unnecessary, *and* the compiler could still
diagnose failures to declare malloc() properly. (And a Standard
declaration was inserted into a brand-new header, too.)

- Ah, but the parameter lists were a bit of a problem. The empty
list `()' didn't really mean "no parameters," but "parameters in the
style of traditional C, that is, we don't know what they are or how
many." It would be nice to get rid of the traditional meaning of `()'
and co-opt it as meaning "no parameters," but this would invalidate
just about all the C code that had been written in the prior twenty-
odd years. Hence, a kludge: `()' retained its traditional meaning,
while `(void)' was invented to mean what `()' "should" have meant.

And that, O Best Beloved, is how the Ritchie's Child got his trunk.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Joachim Schmitz

unread,
May 24, 2012, 3:31:47 AM5/24/12
to
somenath wrote:
> On May 23, 10:27 am, Jens Gustedt <jens.gust...@loria.fr> wrote:
>> Am 23.05.2012 01:14, schrieb Tim Rentsch:
>>
>>> The example program has no structs or unions in
>>> it, so 6.7.2.1 doesn't apply.
>>
>> But 6.7 para 7 applies
>>
>> If an identifier for an object is declared with no linkage, the type
>> for the object shall be
>> complete by the end of its declarator, or by the end of its
>> init-declarator if it has an
>> initializer; in the case of function parameters (including in
>> prototypes), it is the adjusted
>> type (see 6.7.6.3) that is required to be complete.
>
> Out my curiosity when I compiled the following program I did not get
> any diagnostic for the incomplete type. So Will v be treated as
> complete type then ?
>
> int main(void)
> {
> extern void v;

This only declares it but doesn't define nor use it

> return 0;
> }
>
> $ gcc -ansic -pedantic -Wall voidTest.c
> voidTest.c: In function `main':
> voidTest.c:5: warning: unused variable `v'
>
>
> Also please see the following program
> #include<stdio.h>
>
> extern void v;
>
> int main(void)
> {
> int v = 2;

This 'shadows' the prev declarion with a new variable

> printf("Value of v = %d\n",v);
> return 0;
> }
>
> The Out put is
> Value of v = 2
> So is the type of v getting changed dynamically from incomplete to
> complete type ?

No

Joel C. Salomon

unread,
May 25, 2012, 8:03:07 AM5/25/12
to
On 05/21/2012 05:53 PM, Raj Pashwar wrote:
> I would like to define a variable of void type. However I get compiler
> errors:
>
> void x; // error: variable or field ‘x’ declared void
>
> Infact there is a typedef and I want to allow the defined type to be,
> void. However, the error is the same.

The problem is that void variables cannot be named; more formally, a
void object can never be an lvalue. (This is why you cannot dereference
a void* pointer.) Unfortunately, the line

void /* no variable name */ ;

is not valid. This was due to a bug in the original C grammar, kept for
backward compatibility reasons. ANSI therefore defined a special syntax

(void) 0;

for the operation you want.

--Joel

P.S. Exercise: Which of my claims above are (a) correct, (b) *almost*
correct but misleadingly phrased or otherwise subtly wrong, or (c)
outright lies?

James Kuyper

unread,
May 25, 2012, 8:19:28 AM5/25/12
to
On 05/21/2012 05:53 PM, Raj Pashwar wrote:
> Hello
>
> I would like to define a variable of void type. However I get compiler
> errors:
>
> void x; // error: variable or field ‘x’ declared void
>
> Infact there is a typedef and I want to allow the defined type to be,
> void. However, the error is the same.

It just occurred to me what your last paragraph might mean. Are you
trying to to this:

typedef void x;

If so, you shouldn't be getting the same error message.
--
James Kuyper

James Kuyper

unread,
May 25, 2012, 8:19:55 AM5/25/12
to
On 05/25/2012 08:03 AM, Joel C. Salomon wrote:
> On 05/21/2012 05:53 PM, Raj Pashwar wrote:
>> I would like to define a variable of void type. However I get compiler
>> errors:
>>
>> void x; // error: variable or field ‘x’ declared void
>>
>> Infact there is a typedef and I want to allow the defined type to be,
>> void. However, the error is the same.
>
> The problem is that void variables cannot be named; more formally, a
> void object can never be an lvalue. (This is why you cannot dereference
> a void* pointer.) Unfortunately, the line
>
> void /* no variable name */ ;
>
> is not valid. This was due to a bug in the original C grammar, kept for
> backward compatibility reasons. ANSI therefore defined a special syntax
>
> (void) 0;
>
> for the operation you want.

He didn't say anything about wanting an operation of any kind - most of
the responses have asked him what he actually wants to do
He has said that "I would like to define a variable of void type; what
you've provided is an expression-statement, not a definition of a variable.
--
James Kuyper

Raj Pashwar

unread,
May 25, 2012, 5:22:27 PM5/25/12
to
On Tue, 22 May 2012 00:15:32 -0700, nick_keighley_nospam wrote:
> On Monday, May 21, 2012 10:53:26 PM UTC+1, Raj Pashwar wrote:
>
>> I would like to define a variable of void type. However I get compiler
>> errors:
>>
>> void x; // error: variable or field ‘x’ declared void
>>
>> Infact there is a typedef and I want to allow the defined type to be,
>> void. However, the error is the same.
>
> there is no such thing as a void type. What do you think it means. If
> you explain we might be able to tell you how to achieve what you want
> some other way.

Thanks for the many replies, just got back from a trip. Sorry I don't
have time to read them all fully, this thread has got too long.

The situation is this: I have a typedef'd variable. This might be
typedef'd to say FILE*:

typedef FILE* mytype;

and then the code
mytype x;

compiles fine.

However, if instead it is typedef'd to void:

typedef void mytype;

then the same code
mytype x;

no longer compiles.

I hope this is clearer.

Cheers Raj

Eric Sosman

unread,
May 25, 2012, 5:38:34 PM5/25/12
to
On 5/25/2012 5:22 PM, Raj Pashwar wrote:
> On Tue, 22 May 2012 00:15:32 -0700, nick_keighley_nospam wrote:
>> On Monday, May 21, 2012 10:53:26 PM UTC+1, Raj Pashwar wrote:
>>
>>> I would like to define a variable of void type. However I get compiler
>>> errors:
>>>
>>> void x; // error: variable or field ‘x’ declared void
>>>
>>> Infact there is a typedef and I want to allow the defined type to be,
>>> void. However, the error is the same.
>>
>> there is no such thing as a void type. What do you think it means. If
>> you explain we might be able to tell you how to achieve what you want
>> some other way.
>
> Thanks for the many replies, just got back from a trip. Sorry I don't
> have time to read them all fully, this thread has got too long.

Oh, I see. *We* can spend *our* time writing answers to your
question, but *you* can't be bothered to read them? Sweet ...

> The situation is this: I have a typedef'd variable. This might be
> typedef'd to say FILE*:
>
> typedef FILE* mytype;
>
> and then the code
> mytype x;
>
> compiles fine.
>
> However, if instead it is typedef'd to void:
>
> typedef void mytype;
>
> then the same code
> mytype x;
>
> no longer compiles.
>
> I hope this is clearer.

Several respondents have explained why it won't compile.

One thing remains UNclear: What are you trying to achieve?
The meaningless `void x;' (in whatever spelling) won't help, so
simply repeating that it doesn't gets us nowhere. Tell us what
you want to accomplish, and someone will quite likely suggest an
approach that will get you nearer your goal.

Assuming you take the trouble to read the suggestion, that is.

--
Eric Sosman
eso...@ieee-dot-org.invalid

James Kuyper

unread,
May 25, 2012, 5:48:24 PM5/25/12
to
On 05/25/2012 05:22 PM, Raj Pashwar wrote:
...
> The situation is this: I have a typedef'd variable. This might be
> typedef'd to say FILE*:
>
> typedef FILE* mytype;
>
> and then the code
> mytype x;
>
> compiles fine.
>
> However, if instead it is typedef'd to void:
>
> typedef void mytype;
>
> then the same code
> mytype x;
>
> no longer compiles.
>
> I hope this is clearer.

It is.

The simple answer is, you can't do that, and you should re-write your
code to avoid doing it. If it's not obvious how the re-write should be
done, we can give you advice on that matter. But in order to give you
that advice, we would need more information about the context than
you've given us:

Under what circumstances would 'mytype' be void?
What is the purpose of 'x'?

It should be the case that the purpose served by 'x' becomes meaningless
under those circumstances where 'mytype' is void. If not, you've got big
problems; otherwise, something similar to the following example might do
the trick:

#define VOID_MYTYPE

typedef
#ifdef VOID_MYTYPE
void
#else
other_type
#endif
mytype;

mytype *func(
mytype *p
#ifndef VOID_MYTYPE
, mytype x
#endif
){
#ifndef VOID_MYTYPE
*p++ = x;
#endif
// Other operations not involving x
return p;
}

You have to use the #if #else #endif family for this purpose, you can't
use if(){}else{}, because the definitions of 'x' and 'y' are constraint
violations if mytype is void. You must make sure that they don't even
exist anymore after preprocessing is complete, if that is the case.

Joe Pfeiffer

unread,
May 25, 2012, 8:05:23 PM5/25/12
to
No, it was perfectly clear the first time. And many people answered the
first time. Why would anyone answer again?

Raj Pashwar

unread,
May 26, 2012, 3:08:30 PM5/26/12
to
OK, I will explain, but I didn't think these details are relevant.

The program has a LOG functionality. This may be enabled, then log_t will
be FILE* pointing to the LOG location. Or it may be unenabled when log_t
must be void typed.

It appears a workaround may be needed here.

Cheers Raj

Joe Pfeiffer

unread,
May 26, 2012, 3:22:30 PM5/26/12
to
How on earth could something like this have any hope of working? If
log_t is void, then anything you pass it to that expects a FILE* will
fail at compile time. Or were you also hoping that you could pass a
void to something expecting other types without error (in analogy to
being able to use void*'s in pointer assignments)?

Do you really want your log_t to be a void, or do you want to point it
to NULL to disable logging? I've normally enabled/disabled logging with
a boolean (or a mask of booleans to enable/disable different log
statements), or by having LOG macroes that are either #defined as doing
something or as being empty.

> It appears a workaround may be needed here.

This isn't even a workaround, it's doing something sensible...

Eric Sosman

unread,
May 26, 2012, 3:23:53 PM5/26/12
to
On 5/26/2012 3:08 PM, Raj Pashwar wrote:
> On Fri, 25 May 2012 17:38:34 -0400, Eric Sosman wrote:
> [...]
>> One thing remains UNclear: What are you trying to achieve?
>> The meaningless `void x;' (in whatever spelling) won't help, so simply
>> repeating that it doesn't gets us nowhere. Tell us what you want to
>> accomplish, and someone will quite likely suggest an approach that will
>> get you nearer your goal.
>>
>> Assuming you take the trouble to read the suggestion, that is.
>
> OK, I will explain, but I didn't think these details are relevant.

Six days from the first post, do you still trust your judgement?

> The program has a LOG functionality. This may be enabled, then log_t will
> be FILE* pointing to the LOG location. Or it may be unenabled when log_t
> must be void typed.

Okay: That's a non-starter.

> It appears a workaround may be needed here.

Several other approaches are possible. One is to keep a FILE*
variable for logging, but to set the variable NULL when you don't
want log output. Another is to use a FILE* for logging, but to
open it to a system-specific destination that just discards its
data, like "/dev/null" or "NUL:". Yet another is to control the
logging through another variable altogether, leading to the
possibility of different logging levels like "errors only,"
"errors and warnings only," "all messages of all severities."

--
Eric Sosman
eso...@ieee-dot-org.invalid

James Kuyper

unread,
May 26, 2012, 11:37:50 PM5/26/12
to
On 05/26/2012 03:08 PM, Raj Pashwar wrote:
> On Fri, 25 May 2012 17:38:34 -0400, Eric Sosman wrote:
...
>> One thing remains UNclear: What are you trying to achieve?
>> The meaningless `void x;' (in whatever spelling) won't help, so simply
>> repeating that it doesn't gets us nowhere. Tell us what you want to
>> accomplish, and someone will quite likely suggest an approach that will
>> get you nearer your goal.
>>
>> Assuming you take the trouble to read the suggestion, that is.
>
> OK, I will explain, but I didn't think these details are relevant.

You're wrong; they're very relevant. You want to do something that can't
be done. Until you tell us why you want to do this, no one can tell you
anything other than "it can't be done". With those reasons, alternatives
can be suggested.

> The program has a LOG functionality. This may be enabled, then log_t will
> be FILE* pointing to the LOG location. Or it may be unenabled when log_t
> must be void typed.

It is never the case that "log_t MUST be void typed"; that's a choice
you made, and it doesn't work. You can't define a object with void type,
but even if you could, you wouldn't be able to perform any operations on
such an object. Therefore, in order for your program to work properly,
even if you could define an object with void type, your program would
still have to be written in such a way as to avoid doing anything with
it. That's being the case, what's the point of defining such an object
in the first place?

The key thing you really need is not the ability to create an object of
type void; what you need is a way of changing which code is executed,
based upon whether or not the LOG functionality is enabled.

Prior to 2011, C didn't provide any mechanism for choosing to execute
different code depending upon what type something was. In C2011, there's
a new feature, _Generic(), that does provide such a mechanism, but using
it for this purpose would be more complicated than necessary. More
appropriate mechanisms include:

1. Using the preprocessor
// Enable logging:
#define LOG_MESSAGE(arguments) log_message(arguments)
// Disable logging:
#define LOG_MESSAGE(arguments)

Or
// Enable logging
#define LOGGING_ENABLED

#ifdef LOGGING_ENABLED
log_message(arguments)
#endif

2. Using conditional statements:

FILE *log_file;

// Enable logging:
log_file = fopen(log_file_name, "w");
// Disable logging:
log_file = NULL;

if(log_file)
log_message(log_file, arguments)

OR
#include <stdbool>
bool logging_enabled;
// Enable logging:
logging_enabled = true;
// disable logging:
logging_enabled = false;

if(logging_enabled)
log_message(arguments);
--
James Kuyper

Kaz Kylheku

unread,
May 27, 2012, 10:07:42 AM5/27/12
to
On 2012-05-26, Raj Pashwar <raj1...@hotmail.NOSPAM.com> wrote:
> OK, I will explain, but I didn't think these details are relevant.
>
> The program has a LOG functionality. This may be enabled, then log_t will
> be FILE* pointing to the LOG location. Or it may be unenabled when log_t
> must be void typed.
>
> It appears a workaround may be needed here.

C does not support compile-time reasoning over types such as "if this type is
void, customize the code this way".

What you want is achieved in C using the preprocessor:

#if LOGGING_ENABLED
...
#else
...
#endif

The switch cannot be a typedef expression, but a #define directive:

#define LOGGING_ENABLED 1

You can solve this problem in C++. In the following program, you can define the
logging_enabled typedef name as either void, or FILE *. This will turn logging on
and off.

Logging is performed through the global logger object, via its logit member
function.

#include <cstdio>
#include <cstdarg>

// typedef void logging_enabled; // int means it is disabled
typedef FILE *logging_enabled; // FILE * means it is enabled

// base template for log class:
template <typename logtype> class log {
};

// log<int> specialization: constructor throws away the argument,
// and "logit" function does nothing.
template <> class log<void> {
public:
log(FILE *) { }
void logit(const char *fmt, ...) { }
};

// log<FILE *> specialization: constructor keeps FILE * object
// and "logit" function prints to that file
template <> class log<FILE *> {
private:
FILE *logfile;
public:
log(FILE *f) : logfile(f) { }
void logit(const char *fmt, ...)
{
va_list vl;
va_start (vl, fmt);
vfprintf(logfile, fmt, vl);
va_end (vl);
}
};

#include <cstdio>
log<logging_enabled> logger(stdout);

int main()
{
logger.logit("hello, world!\n");
return 0;
}

If you have questions, please ask in comp.lang.c++.

Raj Pashwar

unread,
May 27, 2012, 5:01:40 PM5/27/12
to
OK, so I didn't explain the clever bit.

In the LOG function there is an extra typecast:

...

if(severity < __log_sev_thresh) (log_t) fprintf(log,"%12s: %6s: %s
\n",timedate,__log_sev_name[severity],message);

...

Here, log has type, log_t.

The point is: if log_t is void, then the statement becomes typecast to
void, so is silently removed by the compiler. And the issue of evaluting
the void type, log, is neatly side-stepped.

Cheers Raj

Eric Sosman

unread,
May 27, 2012, 5:38:13 PM5/27/12
to
On 5/27/2012 5:01 PM, Raj Pashwar wrote:
> [...]
> OK, so I didn't explain the clever bit.

Reticence is no virtue when you're seeking help. Dribbling
out the details one by painful each may amuse you, but it just
frustrates those who try to help you.

> In the LOG function there is an extra typecast:
>
> ...
>
> if(severity< __log_sev_thresh) (log_t) fprintf(log,"%12s: %6s: %s
> \n",timedate,__log_sev_name[severity],message);
>
> ...
>
> Here, log has type, log_t.
>
> The point is: if log_t is void, then the statement becomes typecast to
> void, so is silently removed by the compiler. And the issue of evaluting
> the void type, log, is neatly side-stepped.

You are wrong about the cast to void: It does not cause the
compiler to remove anything at all. The fprintf() call will still
be performed. You can test this for yourself:

#include <stdio.h>
int main(void) {
fprintf(stdout, "Hello, world!\n");
(void) fprintf(stdout, "Hello, void!\n");
return 0;
}

By the definition of the C language, this *must* produce two lines
of output, not one.

So much for "clever."

By the way, `__log_sev_thresh' and `__log_sev_name' are
identifiers that are "always reserved for any use" (7.1.3p1),
meaning that if you use them in your own code the C Standard
provides no guarantees at all about what your code may or may
not do, or even whether it will compile. Change the names.

--
Eric Sosman
eso...@ieee-dot-org.invalid

James Kuyper

unread,
May 27, 2012, 8:54:40 PM5/27/12
to
On 05/27/2012 05:01 PM, Raj Pashwar wrote:
> On Sat, 26 May 2012 13:22:30 -0600, Joe Pfeiffer wrote:
...
>> How on earth could something like this have any hope of working? If
>> log_t is void, then anything you pass it to that expects a FILE* will
>> fail at compile time. Or were you also hoping that you could pass a
>> void to something expecting other types without error (in analogy to
>> being able to use void*'s in pointer assignments)?
>>
>> Do you really want your log_t to be a void, or do you want to point it
>> to NULL to disable logging? I've normally enabled/disabled logging with
>> a boolean (or a mask of booleans to enable/disable different log
>> statements), or by having LOG macroes that are either #defined as doing
>> something or as being empty.
>>
>>> It appears a workaround may be needed here.
>>
>> This isn't even a workaround, it's doing something sensible...
>
> OK, so I didn't explain the clever bit.
>
> In the LOG function there is an extra typecast:
>
> ...
>
> if(severity < __log_sev_thresh) (log_t) fprintf(log,"%12s: %6s: %s
> \n",timedate,__log_sev_name[severity],message);
>
> ...
>
> Here, log has type, log_t.
>
> The point is: if log_t is void, then the statement becomes typecast to
> void, so is silently removed by the compiler. ...

Typecasting is something that happens to actors. In C, there's only
casting, not type casting.

"A void expression is evaluated for its side effects." (6.3.2.2p1) "side
effects" includes causing output to occur, so the fprintf() call WILL be
evaluated before being cast to void, because it has to be in order to
produce those side effects. In particular, the compiler will notice that
your code tries to retrieve the non-existent value of 'log', and should
therefore identify this code as a constraint violation.

> ... And the issue of evaluting
> the void type, log, is neatly side-stepped.

Not at all.
--
James Kuyper

Joe Pfeiffer

unread,
May 28, 2012, 1:18:59 AM5/28/12
to
Raj Pashwar <raj1...@hotmail.NOSPAM.com> writes:
>
> OK, so I didn't explain the clever bit.

Any time the best way to describe some code is "clever", You're Doing It
Wrong. In this case, you're lucky that your clever idea was based on a
bunch of misunderstandings severe enough to keep your code from
compiling; far worse is when it all works but comes back to bite the
poor guy who has to maintain the code some day....
0 new messages