This question already has answers here:
what is the use of "static_cast<void>" in macro?
(3 answers)
Why cast unused return values to void?
(10 answers)
Closed 4 years ago.
static_cast<void>() is the 'C++ way' of writing void conversion
In the en.cppreference.com website mentioned as discards the value of the expression. In below link four points on Explanation section
http://en.cppreference.com/w/cpp/language/static_cast
Where and Why should we use static_cast<void>()? give a example..
This is a way to tell that it is ok for a variable to be unused suppressing corresponding compiler warning. This approach has been deprecated with introduction of [[maybe_unused]] attribute in C++17.
The usual purpose of casting to void is to “use” the result of a computation. In relatively strict build environments it is common to output warnings, or even errors, when a variable is declared, maybe even written to, but the result is never used. If, in your code, you know you do not need a result somewhere, you can use the static_cast<void> method to mark the result as discarded – but the compiler will consider the variable used then and no longer create a warning or error.
An example:
#include <iostream>
int myFunction() __attribute__ ((warn_unused_result));
int myFunction()
{
return 42;
}
int main()
{
// warning: ignoring return value of 'int myFunction()',
// declared with attribute warn_unused_result [-Wunused-result]
myFunction();
// warning: unused variable 'result' [-Wunused-variable]
auto result = myFunction();
// no warning
auto result2 = myFunction();
static_cast<void>(result2);
}
When compiled with g++ -std=c++14 -Wall example.cpp, the first two function calls will create warnings.
As VTT pointed out in his post, from C++17 you have the option of using the [[maybe_unused]] attribute instead.
Related
This question already has answers here:
Why should I use 'static_cast' for numeric casts in C++?
(2 answers)
Static cast to avoid IDE warnings? [closed]
(1 answer)
Why does this library refrain from using static_cast?
(1 answer)
Closed 3 months ago.
What will happen when you execute this code snippet?
#include <iostream>
int main() {
float a = 5.51;
int b = static_cast<int>(a);
std::cout << b;
}
Correct answer is:
5 will be printed on standard output, with no compilation warnings generated.
But for me would make more sense to generate compilation warning as precision would be lost. Why not?
I think it depends on compiler level of warning. In my case with Visual Studio 2022 and level warnings set to lvl 4, I get the following warning:
Warning C4305 'init': truncation from 'double' to 'float'.
As commented by #wohlstad:
The explicit cast tells the compiler you did the conversion
intenionally, and therefore there's no need for a warning. Most
compiler will issue a warning if you assign a float to an int
without a cast.
I have the following code in c++:
#include <iostream>
typedef struct Pair{
int x;
int y;
}Pair;
void dumFun(Pair p){}
int main() {
Pair p;
if (0){
p = {1,2};
}
dumFun(p);
return 0;
}
When I compiled the code, I expected to get a warning for the line with dumFun(p) since I'm calling a function with an uninitialized variable.
What I actually want is that my Makefile will give me warning for uninitialized scalar variable issues that I see with the tool Coverity.
Tried to use flag -Wall and I thought it shows warnings for unused variables usage as this - but it doesn't.
Is there any flag to use on a Makefile that will show me warning for the line I wrote above?
You did not tell the compiler, but at least in Clang there is no warning that would catch this. -Weverything shows all possible warnings, and you can use it to find the specific parameter needed to trigger each warning. Demonstration with -Weverything shows no warnings.
I did not find a suitable parameter in GCC either.
In C++, it is possible for pointer values to be compile-time constants. This is true, otherwise, non-type template parameters and constexpr won't work with pointers. However, as far as I know, addresses of functions and objects of static storage are known (at least) at link-time rather than compile-time. Following is an illustration:
main.cpp
#include <iostream>
template <int* p>
void f() { std::cout << p << '\n'; }
extern int a;
int main() {
f<&a>();
}
a.cpp
int a = 0;
I'm just wondering how the address of a could possibly be known when compiling main.cpp. I hope somebody could explain this a little to me.
In particular, consider this
template <int* p, int* pp>
constexpr std::size_t f() {
return (p + 1) == (pp + 7) ? 5 : 10;
}
int main() {
int arr[f<&a, &b>()] = {};
}
How should the storage for arr be allocated?
PLUS: This mechanism seems to be rather robust. Even when I enabled Randomized Base Address, the correct output is obtained.
The compiler doesn't need to know the value of &a at compile time any more than it needs the value of function addresses.
Think of it like this: the compiler will instantiate your function template with &a as a parameter and generate "object code" (in whatever format it uses to pass to the linker). The object code will look like (well it won't, but you get the idea):
func f__<funky_mangled_name_to_say_this_is_f_for_&a>__:
reg0 <- /* linker, pls put &std::cout here */
reg1 <- /* hey linker, stuff &a in there ok? */
call std::basic_stream::operator<<(int*) /* linker, fun addr please? */
[...]
If you instantiate f<b&>, assuming b is another global static, compiler does the same thing:
func f__<funky_mangled_name_to_say_this_is_f_for_&b>__:
reg0 <- /* linker, pls put &std::cout here */
reg1 <- /* hey linker, stuff &b in there ok? */
call std::basic_stream::operator<<(int*) /* linker, fun addr please? */
[...]
And when your code calls for calling either of those:
fun foo:
call f__<funky_mangled_name_to_say_this_is_f_for_&a>__
call f__<funky_mangled_name_to_say_this_is_f_for_&b>__
Which exact function to call is encoded in the mangled function name.
The generated code doesn't depend on the runtime value of &a or &b.
The compiler knows there will be such things at runtime (you told it so), that's all it needs. It'll let the linker fill in the blanks (or yell at you if you failed to deliver on your promise).
For your addition I'm afraid I'm not familiar enough about the constexpr rules, but the two compilers I have tell me that this function will be evaluated at runtime, which, according to them, makes the code non-conforming. (If they're wrong, then the answer above is, at least, incomplete.)
template <int* p, int* pp>
constexpr std::size_t f() {
return (p + 1) == (pp + 7) ? 5 : 10;
}
int main() {
int arr[f<&a, &b>()] = {};
}
clang 3.5 in C++14 standards conforming mode:
$ clang++ -std=c++14 -stdlib=libc++ t.cpp -pedantic
t.cpp:10:10: warning: variable length arrays are a C99 feature [-Wvla-extension]
int arr[f<&a, &b>()];
^
1 warning generated.
GCC g++ 5.1, same mode:
$ g++ -std=c++14 t.cpp -O3 -pedantic
t.cpp: In function 'int main()':
t.cpp:10:22: warning: ISO C++ forbids variable length array 'arr' [-Wvla]
int arr[f<&a, &b>()];
As far as I know, the variables of static storage and functions are stored simply as symbols/place holders in the symbol table while compiling. It is in the linking phase when the place holders are resolved.
The compiler outputs machine code keeping the placeholders intact. Then the linker replaces the placeholders of the variables / functions with their respective memory locations. So in this case too, if you just compile main.cpp without compiling a.cpp and linking with it, you are bound to face linker error, as you can see here http://codepad.org/QTdJCgle (I compiled main.cpp only)
This question already has answers here:
What is the strict aliasing rule?
(11 answers)
Closed 9 years ago.
In file included from /usr/local/Qt/linux-g++/include/QtCore/QLinkedList:2,
from /home/bamboo/Packages/Parser.h:17,
from /home/bamboo/Packages/Module.cpp:6:
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h: In member function 'void QLinkedList<T>::clear() [with T = int]':
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h:294: error: dereferencing pointer 'y' does break strict-aliasing rules
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h:293: note: initialized from here
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h:294: error: dereferencing pointer 'y' does break strict-aliasing rules
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h:293: note: initialized from here
where in big lines class Module contains a member template like: Parser<int> and the class parser is defined:
template <typename T> class Parser
{
// some stuff
QLinkedList<T> stuff;
};
and this piece of code compiles nicely with gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3 and nicely with g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2 and fails with g++ (Debian 4.4.5-8) 4.4.5 ... and I have no idea why? Anyone has seen this error message and anyone know what this might mean?... and more importantly how to solve it?
Aliasing means that a pointer int *i points to the same address as double *d.
So if
int i = 5;
int *pi = &i:
double *d = pi;
here d is aliasing pi.
this is in c99 >illegal<
I don't know how exactly c++ treats it, but I can't imagine it is welcome.
If you want to test a code where it will be getting funny, try this code in different optimisation levels.
You will get differen results with gcc 4.2
uint32_t anint;
int main(int arg, char** argv)
{
foo ((uint64_t *)&anint);
return 0;
}
void foo (uint64_t *dblptr)
{
anint = 88;
*dblptr = 86;
dosmthng (anint);
}
void dosmthng (uint32_t val)
{
printf ("%d\r\n", val);
}
if you do -O2 or higher the output will be 88. because the compiler expects you to respect the strict-aliasing rule and expects *dblptr as never been used in this code, and jsut takes the line out.
If you any way see no way of working wihtout aliasing, you can give the compiler the param -fno-strict-aliasing. This forces GCC to do not any optimisation based on this expection.
But anyway in C it is not strict ISO C code if you do wrong type punning.
(So if it may ease you, a lot of C code on famous programms gets compiled with -fno-strict-aliasing)
lint produces some warning like:
foo.c XXX Warning 534: Ignoring return value of function bar()
From the lint manual
534 Ignoring return value of function
'Symbol' (compare with Location) A
function that returns a value is
called just for side effects as, for
example, in a statement by itself or
the left-hand side of a comma
operator. Try: (void) function(); to
call a function and ignore its return
value. See also the fvr, fvo and fdr
flags in §5.5 "Flag Options".
I want to get this warning, if there exists any, during compilation. Is there any option in gcc/g++ to achieve this? I had turned on -Wall but that apparently did not detect this.
Since C++17 you can use the [[nodiscard]] attribute.
Example:
[[nodiscard]] int bar() {
return 42;
}
Thanks to WhirlWind and paxdiablo for the answer and comment. Here is my attempt to put the pieces together into a complete (?) answer.
-Wunused-result is the relevant gcc option. And it is turned on by default. Quoting from gcc warning options page:
-Wno-unused-result
Do not warn if a caller of a function marked with attribute warn_unused_result (see
Variable Attributes) does not use its return value. The default is -Wunused-result
So, the solution is to apply the warn_unused_result attribute on the function.
Here is a full example. The contents of the file unused_result.c
int foo() { return 3; }
int bar() __attribute__((warn_unused_result));
int bar() { return 5; }
int main()
{
foo();
bar(); /* line 9 */
return 0;
}
and corresponding compilation result:
$gcc unused_result.c
unused_result.c: In function ‘main’:
unused_result.c:9: warning: ignoring return value of ‘bar’, declared with attribute warn_unused_result
Note again that it is not necessary to have -Wunused-result since it is default. One may be tempted to explicitly mention it to communicate the intent. Though that is a noble intent, but after analyzing the situation, my choice, however, would be against that. Because, having -Wunused-result in the compile options may generate a false sense of security/satisfaction which is not true unless the all the functions in the code base are qualified with warn_unused_result.
-Wunused-result should do this for you. This isn't one of the warnings -Wall turns on:
http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
The function has to have the warn_unused_result attribute applied to it (Thanks paxdiablo).
The answers about using __attribute__((warn_unused_result)) are correct. GCC isn't so good at this functionality, though! Be aware: it will not warn for non-POD types. That means, for example, if you return a class with a destructor (or a class with instance variables with destructors) you'll never see a warning about ignoring the result.
Relevant bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66177
Example where it fails:
struct Error {
~Error();
};
__attribute__((warn_unused_result)) Error test();
int main()
{
test();
return 0;
}
So, don't rely on this for return types which aren't pretty simple.
I solved the problem like this:
#define ignore_result(x) if (x) {}
then instead of (void)foo() use ignore_result(foo())
Then the code compiles with -Wall just fine.