dim*_*mba 16 c++ gcc compilation
在以下示例中:
class A
{
public:
int len();
void setLen(int len) { len_ = len; } // warning at this line
private:
int len_;
};
Run Code Online (Sandbox Code Playgroud)
gcc with -Wshadow发出警告:
main.cpp:4: warning: declaration of `len' shadows a member of `this'
Run Code Online (Sandbox Code Playgroud)
函数len和整数len是不同类型的.为什么警告?
更新
我看到"阴影"的含义是广泛的.从形式上看,编译器也完全符合它的含义.
不过恕我直言,这面旗帜并不实用.例如常用的setter/getter成语:
class A {
void prop(int prop); // setter
int prop() const; // getter
int prop;
};
Run Code Online (Sandbox Code Playgroud)
如果有一个警告标志不会在这种情况下发出警告会很好,但会在"int a"隐藏"int a"的情况下发出警告.
添加-Wshadow对我的遗留代码发出大量警告,同时我不时发现由"阴影"问题引起的错误.
我不介意它会被称为"-Wmuch_more_practical_and_interesting_shadow"或"-Wfoooooo".
那么,是否有其他 gcc警告标志符合我的描述?
更新2
不仅我认为-Wshadow不知何故没有用的链接文本.我并不孤单:)不太严格的检查可能会更有用.
mMo*_*ntu 20
这似乎是在较新版本的GCC上解决的.
The option -Wshadow no longer warns if a declaration shadows a function declaration,
unless the former declares a function or pointer to function, because this is a common
and valid case in real-world code.
Run Code Online (Sandbox Code Playgroud)
它引用了Linus Torvalds关于这个主题的想法:https://lkml.org/lkml/2006/11/28/253
不幸的是,我目前正在使用的嵌入式系统的最新编译器仍然基于gcc 4.6.
Jam*_*lis 16
参数与成员函数具有不同类型的事实不会影响参数隐藏成员函数的事实.
为什么你不期望有关于此的警告呢?
我不明白为什么你只坚持某些特定类型的阴影.阴影是阴影,即使类型不同,即使变量影响函数,它的危险也是相同的,就像你的情况一样.阴影的危险在于代码可能会做出与其作者想要做的不同的事情.
当变量影响函数时,这很容易发生,因为在C++中,两者之间的区别比第一眼看上去要薄得多.
例如,这里的变量会影响函数
struct L {
void operator ()();
};
struct A {
void len();
A(L len) {
len();
// Intended to call the member function. Instead got a call to the functor
}
};
Run Code Online (Sandbox Code Playgroud)
而且我认为非常明显的是,由于阴影,代码可能会做一些作者不打算做的事情.
它完全符合它在盒子上的说法.它警告你阴影.
在setLen函数内部,两个符号在范围内,它们具有相同的名称.
len是函数参数的名称,也是函数的名称.
一个阴影对方的名字,所以当你编写引用代码len,你可能不会得到你想要的结果.由于您要求编译器警告您关于彼此的符号阴影,因此这是它警告您的内容.
小智 6
尽管这是一个相当老的问题,但在GCC >= 7中,现在存在三种变体,-Wshadow对程序员的理智产生不同的影响。来自 GCC 9.1.0 的手册页:
-Wshadow=global默认为 -Wshadow。对任何(全局)阴影发出警告。
-Wshadow=local 当局部变量遮蔽另一个局部变量或参数时发出警告。此警告由 -Wshadow=global 启用。
-Wshadow=compatible-local当局部变量遮蔽另一个局部变量或参数(其类型与遮蔽变量的类型兼容)时发出警告。在C++中,这里的类型兼容性是指影子变量的类型可以转换为影子变量的类型。创建此标志(除了
-Wshadow=local)是基于这样的想法:当一个局部变量遮蔽另一个不兼容类型时,它很可能是故意的,而不是错误或拼写错误,如以下示例所示:Run Code Online (Sandbox Code Playgroud)for (SomeIterator i = SomeObj.begin(); i != SomeObj.end(); ++i) { for (int i = 0; i < N; ++i) { ... } ... }
i由于上例中的两个变量“ ”具有不兼容的类型,因此仅启用-Wshadow=compatible-local不会发出警告。由于它们的类型不兼容,如果程序员意外地使用其中一种类型代替另一种类型,类型检查将捕获该类型并发出错误或警告。因此,在这种情况下不发出警告(关于阴影)不会导致未检测到的错误。使用此标志-Wshadow=local可能会减少由故意隐藏触发的警告数量。此警告由 启用
-Wshadow=local。