【发布时间】:2019-12-15 15:04:03
【问题描述】:
我决定在启用 -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 的更详细的错误消息指向 static_cast 作为警告的来源。如果仅将 static_cast 作为参数传递,警告就会消失。 gcc 似乎对
int转换为size_t感到不满,但仅适用于加法操作。显然,对size_t的显式强制转换不足以为+运算符关闭它,但如果将结果作为参数传递,它会保持沉默。 -
有趣的是,如果我将
sizeof移动到局部变量中,它会在它被声明为auto时发出警告,但如果它被声明为size_t则不会发出警告。sizeof的返回类型可能有些奇怪? -
当然警告与从
i到size_t的转换有关,而不是添加。也许 clang 将显式转换视为程序员元通信以抑制警告 -
@MM 在问这个问题时,我假设警告按照文档所说的那样做,并且只对隐式转换发出警告,所以出于某种原因考虑 gcc 在某处进行隐式转换称呼。正如现在接受的答案中所述,问题在于 gcc 的警告实现与其文档不匹配,而不是它正在执行意外的隐式转换。
标签: c++ implicit-conversion gcc-warning