illegal void argument

Ö

Öö Tiib

In C++ we can have void return type and we can "return" it:

void foo();

void bar()
{
return (void)42; // ok #1
return foo(); // ok #2
}

Fun way to confuse novices indeed. However, it appears that we can not (for
whatever unknown reason) pass void arguments:

void bad()
{
foo((void)42); // illegal
}

Even if I think I will be extra clever and add overload of 'foo' that supposedly
accepts anything ...

void foo(...);

.... then I get different failures or successes on different mac/ubuntu clang/gcc
versions. Seems that compilers are confused.

Is there reason why we have such inconsistency?
 
V

Victor Bazarov

In C++ we can have void return type and we can "return" it:

void foo();

void bar()
{
return (void)42; // ok #1
return foo(); // ok #2
}

Fun way to confuse novices indeed. However, it appears that we can not (for
whatever unknown reason) pass void arguments:

void bad()
{
foo((void)42); // illegal
}

Even if I think I will be extra clever and add overload of 'foo' that supposedly
accepts anything ...

void foo(...);

... then I get different failures or successes on different mac/ubuntu clang/gcc
versions. Seems that compilers are confused.

Is there reason why we have such inconsistency?

Inconsistency? Returning from a 'void' function by calling another void
function is syntactic sugar. How would you reconcile passing a void
argument with overloading? What about conversions? I am too lazy to
check (with a compiler or the Standard), maybe you know, what would
happen if you do

int someth();

void foo() {
return someth();
}

? Would it be OK? IOW, is it the same as

void foo() {
someth();
return;
}

? If it's OK, then any expression value *can* be converted to 'void'
when used in a 'return' from a 'void' function. Would you allow the
same for any expression converted as a single argument? Or does it have
to be explicit?

And the clincher for me is the question "what problem does it solve?"
The ability to return an expression from a void function was added to
help resolve some template generation problems. And in this case it
seems that the sole purpose is obfuscation...

V
 
A

Alf P. Steinbach

In C++ we can have void return type and we can "return" it:

void foo();

void bar()
{
return (void)42; // ok #1
return foo(); // ok #2
}

Fun way to confuse novices indeed. However, it appears that we can not (for
whatever unknown reason) pass void arguments:

void bad()
{
foo((void)42); // illegal
}

Even if I think I will be extra clever and add overload of 'foo' that supposedly
accepts anything ...

void foo(...);

... then I get different failures or successes on different mac/ubuntu clang/gcc
versions. Seems that compilers are confused.

Is there reason why we have such inconsistency?

`(void)` as a formal argument list doesn't indicate a formal argument of
type `void`. It's just a special syntax from C, where it specifies that
the function really doesn't take *any* arguments, at all.

In C++ the special syntax is unnecessary, since in C++ `()` also says
that, but the special syntax is supported for C compatibility.

Also baffling: why you can create a "void value" via `void()`. I guess
for uniform treatment in template code. But still it's kind of
inconsistent with the basic idea of `void` as an incomplete type.


Cheers & hth.,

- Alf
 
M

Marcel Müller

Inconsistency? Returning from a 'void' function by calling another void
function is syntactic sugar.

I do not agree with you. In template programming it is essential to
accept this syntax, e.g. for function adapters.
How would you reconcile passing a void
argument with overloading? What about conversions?

This point is a different story. First, it have to be defined what
should happen when void is passed in the parameter list. This has not
yet been defined.

And the clincher for me is the question "what problem does it solve?"
The ability to return an expression from a void function was added to
help resolve some template generation problems.

Exactly. And maybe in conjunction with variadic templates at some time
passing void to a function may become well defined.
And in this case it
seems that the sole purpose is obfuscation...

?

Marcel
 
Ö

Öö Tiib

Inconsistency? Returning from a 'void' function by calling another void
function is syntactic sugar. How would you reconcile passing a void
argument with overloading?

What about conversions? I am too lazy to
check (with a compiler or the Standard), maybe you know, what would
happen if you do

int someth();

void foo() {
return someth();
}

? Would it be OK? IOW, is it the same as

void foo() {
someth();
return;
}

Yes, if to use explicit void cast in return then it would work like that.
The compiler may not implicitly cast to void.
? If it's OK, then any expression value *can* be converted to 'void'
when used in a 'return' from a 'void' function. Would you allow the
same for any expression converted as a single argument? Or does it have
to be explicit?

Yes it has to be explicit. The void cast is perhaps illusionary.
And the clincher for me is the question "what problem does it solve?"
The ability to return an expression from a void function was added to
help resolve some template generation problems. And in this case it
seems that the sole purpose is obfuscation...

My comment about "fun way to confuse novices" was may be too
harsh but that is how it feels because there is *illusionary* usage of
"values" of void type but such usage is only available for rather
*narrow* set of cases (like that 'return' statement).

Why ability to return is more essential for template programming than
ability to "pass" it to other callable? Other problem is that passing void
arguments does not seem to be even forbidden ... it seems to be
undefined.
 
V

Victor Bazarov

[..]
Why ability to return is more essential for template programming than
ability to "pass" it to other callable? Other problem is that passing void
arguments does not seem to be even forbidden ... it seems to be
undefined.

A function wrapper needs the return value type defined (or deduced) and
if/when the call is forwarded to the wrapped object, the return value
needs to be retained and returned to the caller [of the wrapper]. I am
guessing (since I've not followed that particular development in the
language) it to be the reason for introducing the ability to have a void
expression in a return statement. If I were to invent a situation in
which "passing" would be generically necessary, I can only think (right
now) of a "broker" emulator, some mechanism that calls one side and then
the other, while passing the return value of one to the other as its
argument, without necessarily knowing (or caring) what that value is or
where it exists (in the case of 'void'). Apparently the library
designers didn't think it common enough a problem to introduce such a
mechanism into the library. IOW, if you need one, you'd roll your own
instead of instantiating some standard template...

V
 
Ö

Öö Tiib

[..]
Why ability to return is more essential for template programming than
ability to "pass" it to other callable? Other problem is that passing void
arguments does not seem to be even forbidden ... it seems to be
undefined.

A function wrapper needs the return value type defined (or deduced) and
if/when the call is forwarded to the wrapped object, the return value
needs to be retained and returned to the caller [of the wrapper]. I am
guessing (since I've not followed that particular development in the
language) it to be the reason for introducing the ability to have a void
expression in a return statement. If I were to invent a situation in
which "passing" would be generically necessary, I can only think (right
now) of a "broker" emulator, some mechanism that calls one side and then
the other, while passing the return value of one to the other as its
argument, without necessarily knowing (or caring) what that value is or
where it exists (in the case of 'void'). Apparently the library
designers didn't think it common enough a problem to introduce such a
mechanism into the library. IOW, if you need one, you'd roll your own
instead of instantiating some standard template...

I noticed this whole trouble when working with variadic templates.
We can have rather variable list of parameters with rather variable types.
Trouble is only with 'void' that represents several things: lack of object,
lack of object's value, lack of object's type. On cases when 'void' value
is legal it differs what it is by context; on several cases it is illegal and
as actual argument it is undefined.
 
V

Victor Bazarov

[..]
Why ability to return is more essential for template programming than
ability to "pass" it to other callable? Other problem is that passing void
arguments does not seem to be even forbidden ... it seems to be
undefined.
[..]

I noticed this whole trouble when working with variadic templates.
We can have rather variable list of parameters with rather variable types.
Trouble is only with 'void' that represents several things: lack of object,
lack of object's value, lack of object's type. On cases when 'void' value
is legal it differs what it is by context; on several cases it is illegal and
as actual argument it is undefined.

Can you please post with a short example where a variadic template's
inability to pass 'void' as argument makes it hard for you to use it to
accomplish your task?

V
 
Ö

Öö Tiib

On 1/30/2014 9:30 AM, Öö Tiib wrote:
[..]
Why ability to return is more essential for template programming than
ability to "pass" it to other callable? Other problem is that passing void
arguments does not seem to be even forbidden ... it seems to be
undefined.
[..]

I noticed this whole trouble when working with variadic templates.
We can have rather variable list of parameters with rather variable types.
Trouble is only with 'void' that represents several things: lack of object,
lack of object's value, lack of object's type. On cases when 'void' value
is legal it differs what it is by context; on several cases it is illegal and
as actual argument it is undefined.

Can you please post with a short example where a variadic template's
inability to pass 'void' as argument makes it hard for you to use it to
accomplish your task?

I can accomplish anything with C++. It is just trouble when object has
alleged member function (lets say for random example 'getOrigin()')
but that is with 'void' return type. Needs to be extra checked or
enable_iffed, no way to resolve it with some overload that accepts void
arguments (because there are no such things); even the one with ellipsis
parameter crashes some compilers.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,743
Messages
2,569,477
Members
44,898
Latest member
BlairH7607

Latest Threads

Top