GCC 和 Clang 之间的不同行为

Posted

技术标签:

【中文标题】GCC 和 Clang 之间的不同行为【英文标题】:Different behaviors between GCC and Clang 【发布时间】:2017-11-27 11:53:05 【问题描述】:

代码:

#include <cstdio>

int main() 
    unsigned char a = -300.f;
    printf("%d\n", a);

GCC 编译:

g++ test.cpp -o test -std=c++11
test.cpp: In function ‘int main()’:
test.cpp:4:21: warning: overflow in implicit constant conversion [-Woverflow]
  unsigned char a = -300.f;
                     ^

GCC 结果:

0

GCC 版本:

gcc (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609

Clang 编译:

clang++ test.cpp -o test -std=c++11
test.cpp:4:21: warning: implicit conversion from 'float' to 'unsigned char' changes value from 300 to 255
      [-Wliteral-conversion]
        unsigned char a = -300.f;
                      ~    ^~~~~
1 warning generated.

Clang 结果:

160

Clang 版本:

clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)

也许标准没有定义这种行为。


添加-fsanitize=undefined后:

GCC结果(相同):

0

Clang 结果 (48!?):

test.cpp:4:20: runtime error: value -300 is outside the range of representable values of type 'unsigned char'
48

【问题讨论】:

Maybe the standard doesn't define this behavior. 中删除maybe,你得到了答案。 您可能还想将您的问题限制在您指的是哪个标准。特别是,不要添加不相关的标签。 在两个编译器中都考虑-fsanitize=undefined。那么两者都将始终不打印任何结果。 未定义的行为是未定义的 使用像unsigned char a-300.f;这样的统一初始化将无法编译。 【参考方案1】:

浮点类型转换为unsigned char(其中浮点值超出unsigned char 的范围)的行为未定义

请注意,这与原始类型是更宽的整数类型的情况不同。

【讨论】:

以上是关于GCC 和 Clang 之间的不同行为的主要内容,如果未能解决你的问题,请参考以下文章

const 成员初始化之前的用法,这是 gcc 和 clang 的预期行为吗?

g++ 和 clang++ 使用变量模板和 SFINAE 的不同行为

vc9 和 gcc 之间的不同析构函数行为

ctypes c_char_p的不同行为?

Visual Studio 2010 和 gcc/g++ 4.6.3 之间 iostream 行为的意外差异

C++ 编译器在封装行为上存在分歧——哪一个做对了?