Dan*_*l H 14 c++ gcc compiler-warnings global-namespace
考虑以下(错误)C++代码:
#include <cmath>
#include <cstdlib>
#include <iostream>
int main() {
if (abs(-0.75) != 0.75) {
std::cout << "Math is broken!\n";
return 1;
} else {
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
这段代码是错误的,因为它调用abs(含义::abs)而不是std::abs.取决于实现,::abs可能不存在,或者它可能是C abs,或者它可能是包含版本的重载集double,如std::absis.
在Linux上使用Clang,至少在我的环境中,它被证明是第二种选择:C abs.这引发了两个警告,即使没有明确启用任何警告:
<source>:7:9: warning: using integer absolute value function 'abs' when argument is of floating point type [-Wabsolute-value]
if (abs(-0.75) != 0.75) {
^
<source>:7:9: note: use function 'std::abs' instead
if (abs(-0.75) != 0.75) {
^~~
std::abs
<source>:7:13: warning: implicit conversion from 'double' to 'int' changes value from -0.75 to 0 [-Wliteral-conversion]
if (abs(-0.75) != 0.75) {
~~~ ^~~~~
Run Code Online (Sandbox Code Playgroud)
在海湾合作委员会,我在不同的环境中得到不同的结果,我还没有弄清楚环境的哪些细节是相关的.但更常见的选择是它调用C abs函数.然而,即使有-Wall -Wextra -pedantic,它也没有发出警告.我可以强制发出警告-Wfloat-conversion,但这会给我的其余代码库带来太多误报(我可能会修复,但这是一个不同的问题):
<source>: In function 'int main()':
<source>:7:18: warning: conversion to 'int' alters 'double' constant value [-Wfloat-conversion]
if (abs(-0.75) != 0.75) {
^
Run Code Online (Sandbox Code Playgroud)
当命名空间中的版本std是重载时,有没有办法在我通过全局命名空间使用库函数时发出警告?
此代码将让您检测特定环境中是否存在陷阱:
double (*)(double) = &::abs; // fails if you haven't included math.h, possibly via cmath
Run Code Online (Sandbox Code Playgroud)
但它不会帮助你发现你落入陷阱的地方。