2013-06-20 51 views
7

我偶然发现了一个令人困惑的情况,我发现了一个明显的缩小转换,但我感到失望的是编译器(gcc-4.7.2)没有发出警告,尽管标记为-Wall -Wnarrowing -pedantic。请看下面的程序:用圆括号初始化时没有缩小的警告

struct A { 
    int m; 
    A(int m) : m(m) {}; 
}; 

int main() { 
    unsigned long v = 0; 
    A a1(v); // narrowing, but no warning (should this not cause a warning?) 
    A a2{v}; // narrowing, warning raised (expected) 
} 

a1初始化似乎没有那么多飞从编译器窥视。为了确保我不会精神失常,我试图用相同的方式初始化a1,但用大括号代替parens。正如预期的那样,编译器警告在第二种情况下缩小范围。

要清楚:我没有问初始化列表中缩小转换的合法性。我知道这是不合法的 - a2的卷曲支撑初始化仅仅是一种健全检查。 我的问题与初始化列表无关。这不是一个重复的问题。

编译器不应该警告我缩小初始化a1

+0

'a1'的构造函数可以做一个隐式转换,而'a2'则不能。你为什么认为他们应该是一样的? –

+1

如果添加'-Wconversion'标志怎么办? –

+0

这不是重复的。我已经意识到缩小初始化列表中的转换是非法的。我用括号询问初始化。 –

回答

2

Wsign-conversion将生成该行代码的警告 - -Wconversion不会当unsigned longint具有相同的尺寸(这是真的在很多平台上,甚至有些64位平台)。对于C代码,-Wconversion将隐式启用-Wsign-conversion,但由于某些原因,C++不会发生这种情况。

如果更改的v类型long long-Wconversion本身会产生一个警告(假设int是32位)。

+0

非常感谢您的洞察力。我很高兴初始化程序列表语义对于转换非常具体 - 这可能是我开始使用'{}'的一个很好的理由,无论我需要哪种代码最便于移植,因此编译器可以在实际目标之前捕获转换缺陷一个新的平台。 –