Consuming void parameters

Nov 16, 2013 at 9:49pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>

void f()
{
}
int g(...)
{
	return 0;
}

int main()
{
	int x = g(f());
	std::cout << "x = " << x << std::endl;
}
This code compiles and runs fine with clang, but gcc complains about invalid use of void expression.

http://coliru.stacked-crooked.com/a/32b1f81c72156d1d (clang++)
http://coliru.stacked-crooked.com/a/a66b958a01dc2475 (gcc 4.8)

Which compiler is correct? (Hopefully the answer isn't 'both' like it was the last time clang accepted code and gcc didn't...) If gcc is correct and there is a bug in clang 3.1->3.3, then how else would you recommend achieving this? (My actual situation is different and I can fix it without this trick, but I am still curious)
Last edited on Nov 16, 2013 at 11:24pm
Nov 16, 2013 at 10:55pm
Purely at a guess I'd say that it shouldn't compile because it's impossible to pass literally nothing... as something.

I'm afraid I'm not a wizard in such standards though and I suppose I'm just rather curious to see the answers too... I'll see if I can sniff out some info.
Nov 16, 2013 at 11:08pm
So far the best I have is this from the GCC standards (rephrased)

A value of type void is really not a value at all, so it can't appear in any context where an actual value is required.

Such contexts include the following:
the right side of an assignment
an argument of a function
the controlling expression of an if, for, or while statement.


So I imaging that GCC compiler attempts to allocate memory for every value passed to the ... but as void has no value it is unable to do so and hence the behavior is undefined and must be prohibited.

The CLang compilers must just evaluate void as being unable to locate a space in physical memory and completely ignore any variables passed to ..., (Again most of this is assumption so please don't scream if I'm wrong :D )
Last edited on Nov 16, 2013 at 11:11pm
Nov 16, 2013 at 11:10pm
for added variety,

Intel says:
test.cc(13): error: incomplete type is not allowed
        int x = g(f());
                  ^


Oracle said
"test.cc", line 13: Error: A value of type void is not allowed.


IBM said
"test.cc", line 13.16: 1540-0216 (S) An expression of type "void" cannot be converted to type "...".
"test.cc", line 13.16: 1540-1205 (I) The error occurred while converting to parameter 1 of "g(...)".


I think the relevant chapter is §5.2.2[expr.call]/7
After these conversions, if the argument does not have arithmetic, enumeration, pointer, pointer to member, or class type, the program is ill-formed.


You may wish to visit http://llvm.org/bugs/

(but make the testcase more plausible, g(const char* s, ...) or something)

Nov 16, 2013 at 11:13pm
Thanks Cubbi, this was what I was looking for.
Nov 16, 2013 at 11:20pm
Don't know what version of Clang++ that is, but it won't compile on 3.4:
$ clang++ -v
Debian clang version 3.4-1 (trunk) (based on LLVM 3.4)
Target: x86_64-pc-linux-gnu


$ clang++ -std=c++11 main.cpp
main.cpp:13:11: error: cannot pass expression of type 'void' to variadic function
int x = g(f());
Nov 16, 2013 at 11:24pm
Ah, I meant 3.3, not 3.4. Good to know it's already fixed.
Topic archived. No new replies allowed.