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.
Related
This question already has answers here:
Why cast unused return values to void?
(10 answers)
Closed 1 year ago.
An often used statement like (void)x; allows to suppress warnings about unused variable x. But if I try compiling the following, I get some results I don't quite understand:
int main()
{
int x;
(short)x;
(void)x;
(int)x;
}
Compiling this with g++, I get the following warnings:
$ g++ test.cpp -Wall -Wextra -o test
test.cpp: In function ‘int main()’:
test.cpp:4:13: warning: statement has no effect [-Wunused-value]
(short)x;
^
test.cpp:6:11: warning: statement has no effect [-Wunused-value]
(int)x;
^
So I conclude that casting to void is very different from casting to any other types, be the target type the same as decltype(x) or something different. My guess at possible explanations is:
It is just a convention that (void)x; but not the other casts will suppress warnings. All the statements equally don't have any effect.
This difference is somehow related to the fact that void x; isn't a valid statement while short x; is.
Which of these if any is more correct? If none, then how can the difference in compiler warnings be explained?
Casting to void is used to suppress compiler warnings. The Standard says in §5.2.9/4 says,
Any expression can be explicitly converted to type “cv void.” The
expression value is discarded.
This statement:
(void)x;
Says "Ignore the value of x." There is no such type as void - it is the absence of a type. So it's very different from this:
(int)x;
Which says "Treat x as if it were an integer." When the resulting integer is ignored, you get a warning (if it's enabled).
When you ignore something which is nothing, it is not considered a problem by GCC--and with good reason, since casting to void is an idiomatic way to ignore a variable explicitly in C and C++.
The standard does not mandate generating a warning ("diagnostic" in standardese) for unused local variables or function parameters. Likewise, it does not mandate how such a warning might be suppressed. Casting a variable expression to void to suppress this warning has become an idiom in the C and later C++ community instead because the result cannot be used in any way (other than e.g. (int)x), so it's unlikely that the corresponding code is just missing. E.g.:
(int)x; // maybe you meant f((int)x);
(void)x; // cannot have intended f((void)x);
(void)x; // but remote possibility: f((void*)x);
Personally, I find this convention too obscure still, which is why I prefer to use a function template:
template<typename T>
inline void ignore(const T&) {} // e.g. ignore(x);
The idiomatic way to ignore function parameters is, however, to omit their name (as seen above). A frequent use I have for this function is when I need to be able to name a function parameter in conditionally compiled code such as an assert. I find e.g. the following more legible than the use of #ifdef NDEBUG:
void rate(bool fantastic)
{
assert(fantastic);
ignore(fantastic);
}
Possible use:
auto it = list_.before_begin();
for (auto& entry : list_)
{
(void)entry; //suppress warning
++it;
}
Now the iterator 'it' points to the last element
This question already has answers here:
Why cast unused return values to void?
(10 answers)
Closed 1 year ago.
An often used statement like (void)x; allows to suppress warnings about unused variable x. But if I try compiling the following, I get some results I don't quite understand:
int main()
{
int x;
(short)x;
(void)x;
(int)x;
}
Compiling this with g++, I get the following warnings:
$ g++ test.cpp -Wall -Wextra -o test
test.cpp: In function ‘int main()’:
test.cpp:4:13: warning: statement has no effect [-Wunused-value]
(short)x;
^
test.cpp:6:11: warning: statement has no effect [-Wunused-value]
(int)x;
^
So I conclude that casting to void is very different from casting to any other types, be the target type the same as decltype(x) or something different. My guess at possible explanations is:
It is just a convention that (void)x; but not the other casts will suppress warnings. All the statements equally don't have any effect.
This difference is somehow related to the fact that void x; isn't a valid statement while short x; is.
Which of these if any is more correct? If none, then how can the difference in compiler warnings be explained?
Casting to void is used to suppress compiler warnings. The Standard says in §5.2.9/4 says,
Any expression can be explicitly converted to type “cv void.” The
expression value is discarded.
This statement:
(void)x;
Says "Ignore the value of x." There is no such type as void - it is the absence of a type. So it's very different from this:
(int)x;
Which says "Treat x as if it were an integer." When the resulting integer is ignored, you get a warning (if it's enabled).
When you ignore something which is nothing, it is not considered a problem by GCC--and with good reason, since casting to void is an idiomatic way to ignore a variable explicitly in C and C++.
The standard does not mandate generating a warning ("diagnostic" in standardese) for unused local variables or function parameters. Likewise, it does not mandate how such a warning might be suppressed. Casting a variable expression to void to suppress this warning has become an idiom in the C and later C++ community instead because the result cannot be used in any way (other than e.g. (int)x), so it's unlikely that the corresponding code is just missing. E.g.:
(int)x; // maybe you meant f((int)x);
(void)x; // cannot have intended f((void)x);
(void)x; // but remote possibility: f((void*)x);
Personally, I find this convention too obscure still, which is why I prefer to use a function template:
template<typename T>
inline void ignore(const T&) {} // e.g. ignore(x);
The idiomatic way to ignore function parameters is, however, to omit their name (as seen above). A frequent use I have for this function is when I need to be able to name a function parameter in conditionally compiled code such as an assert. I find e.g. the following more legible than the use of #ifdef NDEBUG:
void rate(bool fantastic)
{
assert(fantastic);
ignore(fantastic);
}
Possible use:
auto it = list_.before_begin();
for (auto& entry : list_)
{
(void)entry; //suppress warning
++it;
}
Now the iterator 'it' points to the last element
While reading about *this, I saw:
When a nonstatic member function is called for an object, the compiler
passes the object's address to the function as a hidden argument.
Then I tried:
#include <iostream>
class MyClass
{
int myVar;
public:
MyClass(const int& val) : myVar{val} {}
// int getVar(MyClass* this) <-- Error: expected ',' or '...' before 'this'
int getVar()
{
return this->myVar;
}
};
int main()
{
MyClass obj(22);
// std::cout << obj.getVar(&obj); <-- Error: no matching function
// std::cout << MyClass::getVar(&obj); <-- Error: no matching function
std::cout << obj.getVar();
return 0;
}
Why am I not able to access the hidden argument? Is it called 'hidden' because of that?
Are only compilers allowed to do this? Can't we explicitly mention *this in the function signature?
The closest answer I've found before asking this is this. But I tried that way and still got the error. Could I get an explanation of those error messages? Because, if the compiler actually modifies those function signatures to contain *this then that should have worked, isn't it?
Are only compilers allowed to do this?
Precisely. That's why it's called hidden: It's something that the compiler does on your behalf, but which is hidden from the C++ code that uses it.
The compiler must pass the this pointer to the member function somehow, but it does not need to tell you how it does it. It could compile the code to the equivalent of MyClass::getVar(&obj), passing the this pointer in the same way that it would pass the argument for the C function free(foo). Or it might use a different mechanism that is totally incompatible with non-member argument passing. What it does under the hood is defined by the platform's Abstract Binary Interface standard (ABI), which is not part of the C++ language standard. What happens under Windows could be vastly different from what happens under Linux, and Linux on ARM could be different from Linux on X86, etc.
That said, you can take a look at what actually happens by telling your compiler to produce the assembly code. For gcc, the incantation would be
g++ -S -Os interestingCode.cpp
This will produce a .s file that contains how g++ actually translated your code.
obj.getVar(&obj)
This version cannot compile because the getVar() member function is not declared to take any parameters.
MyClass::getVar(&obj)
This version is using the syntax to access a static function but getVar() is not static, nor does it accept any parameters.
Note: The obj.getVar() call works because it is specifying which object instance to use (i.e., the obj. part) to execute the member function and is conceptually how the member function is passed the this pointer.
When you are doing obj.getVar() it is already explicitly specified the pointer *this=&obj and passed implicitly to getVar. It is not hidden. It is explicitly passed leftside of the function. You can use obj.getVar() or ptrObj->getVar() but in C++ is not allowed to use such construction getVar(thisptr). Hidden means the variable named this is nowhere declared, but you can use inside the function.
This question already has answers here:
Why cast unused return values to void?
(10 answers)
Closed 1 year ago.
An often used statement like (void)x; allows to suppress warnings about unused variable x. But if I try compiling the following, I get some results I don't quite understand:
int main()
{
int x;
(short)x;
(void)x;
(int)x;
}
Compiling this with g++, I get the following warnings:
$ g++ test.cpp -Wall -Wextra -o test
test.cpp: In function ‘int main()’:
test.cpp:4:13: warning: statement has no effect [-Wunused-value]
(short)x;
^
test.cpp:6:11: warning: statement has no effect [-Wunused-value]
(int)x;
^
So I conclude that casting to void is very different from casting to any other types, be the target type the same as decltype(x) or something different. My guess at possible explanations is:
It is just a convention that (void)x; but not the other casts will suppress warnings. All the statements equally don't have any effect.
This difference is somehow related to the fact that void x; isn't a valid statement while short x; is.
Which of these if any is more correct? If none, then how can the difference in compiler warnings be explained?
Casting to void is used to suppress compiler warnings. The Standard says in §5.2.9/4 says,
Any expression can be explicitly converted to type “cv void.” The
expression value is discarded.
This statement:
(void)x;
Says "Ignore the value of x." There is no such type as void - it is the absence of a type. So it's very different from this:
(int)x;
Which says "Treat x as if it were an integer." When the resulting integer is ignored, you get a warning (if it's enabled).
When you ignore something which is nothing, it is not considered a problem by GCC--and with good reason, since casting to void is an idiomatic way to ignore a variable explicitly in C and C++.
The standard does not mandate generating a warning ("diagnostic" in standardese) for unused local variables or function parameters. Likewise, it does not mandate how such a warning might be suppressed. Casting a variable expression to void to suppress this warning has become an idiom in the C and later C++ community instead because the result cannot be used in any way (other than e.g. (int)x), so it's unlikely that the corresponding code is just missing. E.g.:
(int)x; // maybe you meant f((int)x);
(void)x; // cannot have intended f((void)x);
(void)x; // but remote possibility: f((void*)x);
Personally, I find this convention too obscure still, which is why I prefer to use a function template:
template<typename T>
inline void ignore(const T&) {} // e.g. ignore(x);
The idiomatic way to ignore function parameters is, however, to omit their name (as seen above). A frequent use I have for this function is when I need to be able to name a function parameter in conditionally compiled code such as an assert. I find e.g. the following more legible than the use of #ifdef NDEBUG:
void rate(bool fantastic)
{
assert(fantastic);
ignore(fantastic);
}
Possible use:
auto it = list_.before_begin();
for (auto& entry : list_)
{
(void)entry; //suppress warning
++it;
}
Now the iterator 'it' points to the last element
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.