[英]gcc size_t and sizeof arithmetic conversion to int
我决定在启用 -Wsign-conversion 的情况下测试编译一个项目,看看会出现什么警告,并遇到一些似乎不正确的东西,其中 gcc 的行为与 clang 不同。 有人可以告诉我哪个是正确的吗?
我有一个接受size_t
参数的函数:
void func(size_t) {}
其他一些结构
struct Test {};
和调用代码
int i = some_initialiser();
func(sizeof(Test) + static_cast<size_t>(i));
因此,从我的理解, sizeof
回报size_t
,和类型的两个变量之间的算术size_t
应返回size_t
,所以应该不会在这里比我的其他任何转换static_cast
,但GCC给我的警告
warning: conversion to ‘long unsigned int’ from ‘int’ may change the sign of the result [-Wsign-conversion]
Clang 不会在这里发出警告,但如果我按预期删除函数调用中的static_cast
,则会发出警告。
这是 gcc 中的一个已知错误,已在 9.3.0 及更高版本中修复。
警告是有效的(编译器可以警告任何他们喜欢的东西),但 gcc 的行为与其自己的文档相矛盾。 这个问题有一个现有的错误报告(见下文)。
这是一个更简单的测试用例,说明了这个问题:
#include <cstddef>
int main() {
int i = 42;
size_t s0 = sizeof (int) + (size_t)i;
size_t s1 = sizeof (int) + static_cast<size_t>(i);
}
当我使用 gcc 9.1.0 在我的系统上编译它时,我得到:
$ g++ -Wsign-conversion -c c.cpp
c.cpp: In function ‘int main()’:
c.cpp:4:32: warning: conversion to ‘long unsigned int’ from ‘int’ may change the sign of the result [-Wsign-conversion]
4 | size_t s0 = sizeof (int) + (size_t)i;
| ^~~~~~~~~
c.cpp:5:32: warning: conversion to ‘long unsigned int’ from ‘int’ may change the sign of the result [-Wsign-conversion]
5 | size_t s1 = sizeof (int) + static_cast<size_t>(i);
| ^~~~~~~~~~~~~~~~~~~~~~
$
请注意,C 样式转换和static_cast
都会出现警告。
确实,转换可能会改变结果的符号(将负int
转换为size_t
产生正结果),但 gcc 的-Wsign-conversion
文档说:
'-Wsign-conversion'
Warn for implicit conversions that may change the sign of an
integer value, like assigning a signed integer expression to an
unsigned integer variable. An explicit cast silences the warning.
In C, this option is enabled also by '-Wconversion'.
在这种情况下,显式强制转换不会使警告静音。
这个错误已经被报告了:
错误 87519 - -Wsign-conversion -Wconversion 显式转换无法使警告静音
修复是在 gcc git repo 中提交61e52125c935279af11b10d27060a96bff7477a4
于61e52125c935279af11b10d27060a96bff7477a4
年 8 月 8 日提交。
警告是正确的。
如果i
有一个负值,铸造就会有问题。 您的函数应该返回一个无符号值(例如 unsigned int)。
来自 GCC 文档 - https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html :
对于 C++,还警告混淆用户定义转换的重载解析; 和从不使用类型转换运算符的转换:转换为
void
、相同类型、基类或对它们的引用。 除非显式启用-Wsign-conversion
否则 C++ 中默认禁用有关有符号和无符号整数之间转换的警告。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.