This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
casting unused return values to void
I read some source code, and in it many virtual functions in the interface classes are declared and default-implemented as such:
virtual bool FunctionName(TypeName* pointer)
{
(void)pointer;
return true;
}
May I ask what is the purpose of casting the pointer to void in the default implementation?
Multiple purposes depending on what you cast
Marking your intention to the compiler that an expression that is entirely a no-op is intended as written (for inhibiting warnings, for example)
Marking your intention to to the compiler and programmer that the result of something is ignored (the result of a function call, for example)
In a function template, if a return type is given by a template parameter type T, and you return the result of some function call that could be different from T in some situation. An explicit cast to T could, in the void case, prevent a compile time error:
int f() { return 0; } void g() { return (void)f(); }
Inhibiting the compiler to choose a comma operator overload ((void)a, b will never invoke an overloaded comma operator function).
Note that the Standard guarantees that there will never be an operator void() called if you cast a class object to void (some GCC versions ignore that rule, though).
In this case it's just to avoid compiler's warning about unused parameter.
Related
Why is the following allowed to be compiled in C++?
#include<iostream>
using namespace std;
class mytest
{
public:
operator int()
{
return 10;
}
operator const int()
{
return 5;
}
};
int main()
{
mytest mt;
//int x = mt; //ERROR ambigious
//const int x = mt; //ERROR ambigious
}
Why does it make sense to allow different versions (based on constness) of the conversion operator to be compiled when their use always results in ambiguity?
Can someone clarify what I am missing here?
For conversion they're ambiguous; but you might call them explicitly. e.g.
int x = mt.operator int();
const int x = mt.operator const int();
I believe that in the strictest sense, even if it doesn't really make much sense for const, this is legitimate.
There is a difference between a function declaration and a function type, and they do not have the same constraints.
Function declarations may not differ in only their return type or (since C++17) exception specification. However, no such thing is said about the function type (to my knowledge).
The standard [class.conv.fct] decribes conversion functions as having such-and-such form (three alternatives listed), all of which do not look like normal function declarations, in particular they very obviously have no return type.
It does state, that the function type is "function taking no parameter returning conversion-type-id", but nowhere is it mentioned that conversion function declarations have any such thing as a return type. On the contrary, the three alternative forms listed very clearly do not have a return type.
Since conversion functions don't have a return type (... in their declaration), it cannot conflict. So, I guess, in the strictest, most pedantic sense, it's even kinda "legal", whether it makes sense or not.
If you think about it, then it somehow has to be legal, too. A class may very well have more than one conversion function to different things (not just differing by const). Such code does exist, and it sometimes makes a lot of sense going that way.
You might for example have a class File that converts to either a string (the filename) or to a handle_t (the operating system handle) in case you want to use some OS-specific or exotic function that your wrapper class doesn't directly support (think writev, tee, or epoll?) It's certainly something you'd expect to work!
If, however, we treated conversion functions as "just functions", then they'd only differ in their return type, which would render the declarations illegal. So... that wouldn't work.
why does it make sense to allow different version(based on constness) of conversion operator (to be compiled) when their use always result in ambiguity;
It usually makes no sense (apart from highly artificial use cases) and a compiler could warn you about it:
prog.cc:12:25: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
operator const int()
^
I come to the conclusion, that it's not explicitly allowed to write conversation operators that only differ by constness of their return value. It is too expensive for the compilation process to explicitly disallow it.
Remember that (member) functions that only differ by their return type
class mytest
{
int f();
const int f();
};
are forbidden:
error: ‘const int mytest::f()’ cannot be overloaded
It's just that conversion operators start with operator that makes the difference.
I "wanted" to use void as a placeholder (or overload disambiguator) or even as a shortcut to have functions with void return type called before entering a specific function like in the following example:
int f(void , int)
{
return 0;
}
void g()
{
}
int main()
{
f(g(), 1);
}
Now, this is not a real world problem (I know that I could just call g() before calling f()) but I was wondering why this is not doable, especially when I can e.g. explicitly return void types i.e. this is legal :
void h()
{
return g(); // this does a return void
}
EDIT
To explain the rationale behind asking this, I first thought that according to C legacy, void would be an incomplete type, so incomplete types cannot appear as function parameters, unlike pointers to incomplete types and hence the void* commonality. Now this would explain void as a "special case" signal for "no parameters" but after C++11 the Standard reads (3.9 [basic.types]) :
A type is a literal type if it is:
void; or
a scalar type; or
....
Being a literal type, I can't find elsewhere any rationale that would exclude void from candidate types for function parameters, neither the equivalent of old C's (prior to C11) "void is not a type". Now, my search may be lacking the required depth which is what I try to compensate for in this Q
A void parameter means the function has no parameters*. It wouldn't make much sense for a function with no parameters to have some parameters.
* This is inherited from C (and presumably kept for compatibility with that language), where a function declared without a parameter list is a function that can take any number of parameters of any type. In C++, such a function would have no parameters, removing the need to use void parameters.
The only real problem here is your function prototype:
int f(void , int)
You cannot give a void as a parameter. You can set it as a return value, meaning "this function returns nothing", or you can give it as only parameter, like this:
int f(void)
It would means "this function takes no parameter", but not as a parameter.
But to give a parameter of void type would mean you could declare a void variable and give it to your function, which would have no sense.
In your sample:
void h()
{
return g(); // this does a return void
}
This does not a return void. This does return nothing. This is as legal as:
void h()
{
return;
}
So here, you can clearly see void is just a meaning of nothing.
Try to use functions returning void as arguments, like you did:
f(g(), 1);
Should be avoided as much as possible.
I've wanted a void argument type in order to have a parameter that is zero-cost in release builds:
#ifdef NDEBUG
typedef DebugTracker* Foo;
#else
typedef void Foo;
#endif
int SomeFunction(Foo foo, ...) {
...
}
I can't find elsewhere any rationale that would exclude void from candidate types for function parameters
#juanchopanza has pointed out one thing, which is that C++ inherited C's f(void) meaning a function that takes no arguments. That being so, C++ still could have the feature but make void parameters act as if they had a default value of nothing...so having such a default if they were at the end of argument lists.
In language-design space, it's always easy to think of the case you have in mind and say "why not?". And if you look at something like libffi then it seems like prohibiting void for arguments makes the system less "pure". There's a count of bytes for each argument, how hard would it be to allow 0?
But there are questions to answer.
If void parameters are possible, then that posits the existence of void variables. How does a void variable act? What's its address? If you can't take the address of a void variable, how does that impact the compiler...the linker...what's going to happen with name-mangling, etc.
I don't know enough to tell you if the pretzel of the existing C and C++ standard can be untwisted in a way that void parameters do more good than harm. It would be an interesting study to take a compiler and some large body of code and think through the details. I upvoted the question as reasonable to ask, but also voted to close as primarily opinion-based, so... that's my 0.02.
This question already has answers here:
Why cast an unused function parameter value to void?
(2 answers)
Closed 8 years ago.
I'm looking at some code that has a function that looks like this:
void f(A* a, B& b, C* c)
{
(void)a;
(void)b;
(void)c;
}
What exactly does the (void) at the start of every line do?
What you see there is really just a "trick" to fake variable/parameter usage.
Without those lines, a pedantic compiler will warn you about the variables not being used.
Using a construct (void)variablename; will result in no instructions being generated, but the compiler will consider it a valid "use" of those variables.
It's simply a kludge to avoid compiler warnings. For example, that code will emit
warning: unused parameter ‘a’ [-Wunused-parameter]
warning: unused parameter ‘b’ [-Wunused-parameter]
warning: unused parameter ‘c’ [-Wunused-parameter]
when compiled with gcc -Wall -Wextra if the kludge is not used. There are cleaner looking ways to achieve this though. You could omit the parameter names:
void f(A*, B&, C*) {
}
A gcc-specifc and somewhat verbose alternative is to use the unused attribute on each unused parameter:
void f(A* a __attribute__((unused)), B& b, C* c) {
}
I see at least two rerasons. The first one is to avoid warnings of the compiler that the variables are defined but not used in the body of the function.
The second one is that it is very old code and sometimes programmers wrote casting to void before expressions if the result of the expressions is not used. This helped the compiler to optimize generated object code.
Whenever we are writing a function in C++, we need to follow prototype of function, i.e.
type name ( parameter1, parameter2, ...) { statements }
here type- stands for type of value it returns
A return type of void allows you to define a function that does not return a value. Note that it is NOT the same as returning 0. The value of 0 is of type integer, float, double, etc; it is not a void. (In other languages, a function with no return value may be called a "subroutine" or "procedure", whereas a "function" always returns something. In C/C++, they are all called functions.)
returning void means returning nothing.
A pointer to void is a generic pointer that can be used when the type of the data at the location is unknown. So you can use a type of void * to refer to an address in memory without knowing what is actually located there.
I encountered this "beautiful" example of "highly readable" and "elegant" code, but I'm having troubles understanding it:
struct S {
[[noreturn]] virtual inline auto f(const unsigned long int *const)
–> void const noexcept;
};
Here's what I understand (please correct me if I'm wrong):
f() is a member function of S
virtual - can be overridden by derived classes
inline - compiler should attempt to generate code for a call to f rather than calling it normally
const - the function is not able to change any of S's members
noexcept - the function will never throw (cannot throw or not allowed to throw)
parameter: a const pointer to a const unsigned long int
auto .... -> void - suffix return type void
[[noreturn]] - it never returns
Here are my main concerns:
If a function is declared as [[noreturn]], it never returns to its caller; so how can it have a return type void? What is the point of a return type in this function anyway?
Would this code compile with int instead of void for example?
What would be a practical use for a function like that? To throw an exception?
Where does the flow of the code go after this function finishes executing (after } )?
I couldn't get this code to run on VS2013 Preview, so I guess these features weren't implemented yet.
I'm very curious about this, so I'll appreciate it if someone can explain! Cheers
The [[noreturn]] is an attribute which has whatever semantics it has. It doesn't change, however, how the function is declared: all normal functions in C++ (i.e., all functions except the constructors, destructors, and conversion operators) have a declared return type. Adding any attribute doesn't change this rule.
The purpose of the [[noreturn]] attribute is probably to indicate that the function never returns in a normal way. Given that the function is also declared to be noexcept it basically means that the corresponding function also can't thrown an exception. One example of a function with similar behavior is exit() which terminates the program. I could imagine that functions implementing some sort of application-loop could also qualify. In any case, the [[noreturn]] tells the system that the corresponding function will never normally return, i.e., falling off the function ("after }") will probably result in undefined behavior.
If a function is declared as [[noreturn]], it never returns to its caller; so how can it have a return type void? What is the point of a return type in this function anyway?
From this Q&A you can see that noreturn is a way to tell the compiler that a function does not return. Normally this means it either has an infinite loop (often seen in servers that are supposed to run indefinitely) or it calls exit(), terminate() and the like, exiting the application without returning to main.
[[noreturn]] is optional, i.e. you don't have to specify it. It's an attribute, i.e. the basic syntax of defining/declaring the function remains untouched, so the function has to have a return type as any other function has.
Would this code compile with int instead of void for example?
Yes, it would, although the compiler might warn you that it does not make sense having something returned from a function that never returns.
What would be a practical use for a function like that? To throw an exception?
The first thing that comes to mind is some endless loop, e.g. handling incoming requests at a server. Throwing an exception is ok for [[noreturn]] functions as well, but its not really an option here, because it explicitly says noexcept. Throwing would trigger a call to std::terminate(), leading to program termination itself but previosuly to an implementation defined amount of stack unwinding, wich in fact means [[noreturn]] would still be applicable.
Where does the flow of the code go after this function finishes executing (after } )?
The function never reaches its closing }. It either runs endlessly (until someone pulls the plug), or it exits abnormally, i.e. by program termination. In other words, if the function does not execute any more, it has not really finished but aborted execution, and there is no program and no control flow to go to.
The other answers are great, but I'm going to present an alternative answer for
If a function is declared as [[noreturn]], it never returns to its caller; so how can it have a return type void? What is the point of a return type in this function anyway?
One reason why you might need a return type (and a non-void return type at that) is if the function is overriding a super classes method.
struct Parent {
virtual int f()=0;
}
struct Child {
[[noreturn]] override int f() noexcept { ... }
};
In some contexts the compiler will be able to use the [[noreturn]] to produce better code. But in other situations f might be called polymorhically, and thus needs to conform to its parents signature.
If a function is declared as [[noreturn]], it never returns to its caller; so how can it have a return type void? What is the point of a return type in this function anyway?
I have found one practical example of a non-void [[noreturn]] function. It is in a case, when used in ?: operator to provide a correct result type of ?: operator:
template <class T> [[noreturn]] T fail(char const *s) noexcept { puts(s); exit(1); }
enum E { V1, V2 };
int f(E e) {
return (e == V1) ? 1 : (e == V2) ? 2 : fail<E>("bad e");
}
Note: One could have a feeling that [[noreturn]] functions in ?: operator could be ignored for calculation of ?: result type. But it is not possible because [[noreturn]] is not a part of result type of an expression (fail<T>("") has result type T and not [[noreturn]] T).
What would be a practical use for a function like that? To throw an exception?
See the example of such function fail above.
Suppose I have a function that performs some side effect and then returns an answer:
int foo()
{
perform_some_side_effect();
return 42;
}
I want to bind foo to a function pointer, but I'm not interested in the answer, just the side effect:
void (*bar)() = foo;
However, this appears to be a type error:
error: invalid conversion from ‘int (*)()’ to ‘void (*)()’
What is the rationale behind that error? Why doesn't the type system allow me to ignore the answer?
On a side note, it works if I wrap the function pointer in a std::function:
std::function<void()> baz = foo;
How does std::function (apparently) manage to circumvent this restriction in the type system?
What is the rationale behind that error? Why doesn't the type system allow me to ignore the answer?
The reason is that the types are different, and the generated code at the place of call (through the function pointer) is different. Consider a calling convention where all arguments are written to the stack and space for the return value is also reserved in the stack. If the call goes through a void (*)() then no space will be reserved in the stack for the return value, but the function (unaware of how it is being called) will still write the 42 to the location where the caller should have reserved space.
How does std::function (apparently) manage to circumvent this restriction in the type system?
It does not. It creates a function object that wraps the call to the actual function. It will contain a member like:
void operator()() const {
foo();
}
Now when the compiler processes the call to foo it knows what it has to do to call a function that returns an int and it will do so according to the calling convention. Because the template does not return, it will just ignore the value --that was actually returned.
std::function need only be source compatible- that is, it can generate a new class which generates new caling code that ignores the result. The function pointer must be binary compatible and cannot do that job- void(*)() and int(*)() point to the exact same code.
You can think of std::function<> doing this for your particular case:
void __func_void()
{
foo();
}
It's actually a bit more complicated than that, but the point is that it generates template code together with type-erasure to not care about the specifics.
In addition to what others have been saying, the caller also need the return type to know what destructor it should invoke on the result (the return value may be a temporary).
Unfortunately it is not as easy as
auto (*bar)() = foo;
Although GCC and Clang accept this. I need to recheck the spec to see whether that's actually correct.
Update: The spec says
The auto type-specifier signifies that the type of a variable being declared shall be deduced from its initializer or that a function declarator shall include a trailing-return-type.
This can be misleading when read fast, but this is implemented by GCC and clang to only apply to the toplevel declarator. In our case, this is a pointer declarator. The declarator nested in it is a function declarator. So just substitute auto for void and then the compiler will deduce the type for you.
By the way, you can always make this work manually, but it takes some trickery to make it work
template<typename FunctionType>
struct Params;
template<typename ...Params>
struct Params<void(Params...)> {
template<typename T>
using Identity = T;
template<typename R>
static Identity<R(Params...)> *get(R f(Params...)) {
return f;
}
};
// now it's easy
auto bar = Params<void()>::get(foo);