Paavo Helde
2024-04-23 11:31:43 UTC
There is an old third-party library where some function pointers are
casted to another type, then back to the original type before use. C++
standard says this is kosher, and there have never been any problems
with actual behavior. Alas, different versions and compile modes of g++
still produce warnings. What would be the best way to silence them
(without just switching off warnings)?
Simplified example:
typedef double (*Func)(double);
typedef double (*DoubleFunc_2_args)(double, double);
Func FuncCast2(DoubleFunc_2_args fp) {
return reinterpret_cast<Func>(fp);
}
$ g++ test1.cpp -Wall -Wextra
test1.cpp: In function ‘double (* FuncCast2(DoubleFunc_2_args))(double)’:
test1.cpp:26:34: warning: cast between incompatible function types from
‘DoubleFunc_2_args’ {aka ‘double (*)(double, double)’} to ‘Func’ {aka
‘double (*)(double)’} [-Wcast-function-type]
return reinterpret_cast<Func>(fp);
If I change the function to use more indirection, then there is a
warning with -O2 only:
Func FuncCast2(DoubleFunc_2_args fp) {
return *reinterpret_cast<Func*>(&fp);
}
$ g++ test1.cpp -Wall -Wextra -O2
test1.cpp: In function ‘double (* FuncCast2(DoubleFunc_2_args))(double)’:
test1.cpp:22:10: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
return *reinterpret_cast<Func*>(&fp);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
$ g++ --version
g++ (Debian 10.2.1-6) 10.2.1 20210110
casted to another type, then back to the original type before use. C++
standard says this is kosher, and there have never been any problems
with actual behavior. Alas, different versions and compile modes of g++
still produce warnings. What would be the best way to silence them
(without just switching off warnings)?
Simplified example:
typedef double (*Func)(double);
typedef double (*DoubleFunc_2_args)(double, double);
Func FuncCast2(DoubleFunc_2_args fp) {
return reinterpret_cast<Func>(fp);
}
$ g++ test1.cpp -Wall -Wextra
test1.cpp: In function ‘double (* FuncCast2(DoubleFunc_2_args))(double)’:
test1.cpp:26:34: warning: cast between incompatible function types from
‘DoubleFunc_2_args’ {aka ‘double (*)(double, double)’} to ‘Func’ {aka
‘double (*)(double)’} [-Wcast-function-type]
return reinterpret_cast<Func>(fp);
If I change the function to use more indirection, then there is a
warning with -O2 only:
Func FuncCast2(DoubleFunc_2_args fp) {
return *reinterpret_cast<Func*>(&fp);
}
$ g++ test1.cpp -Wall -Wextra -O2
test1.cpp: In function ‘double (* FuncCast2(DoubleFunc_2_args))(double)’:
test1.cpp:22:10: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
return *reinterpret_cast<Func*>(&fp);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
$ g++ --version
g++ (Debian 10.2.1-6) 10.2.1 20210110