c++ - 针对 C++ 隐式转换的警告

标签 c++ implicit-conversion

我有这个 C++ 代码:

#include <iostream>
#include <vector>
#include <numeric>

using namespace std;

int main() {
  vector<int64_t> vec = {4294967296, 4294967296, 4294967296};
  int64_t sum = accumulate(vec.begin(), vec.end(), 0, [](int64_t sum, int64_t val){
    return sum + val;
  });
  cout << "sum = " << sum << endl;
}

它返回 sum = 0 因为从 intint64 的隐式转换(参见 0 作为第三个参数accumulate 函数)。将 0 替换为 (int64_t)0 后一切正常。

但是我可以在编译时检测到这些东西吗? -Wconversion 在这种情况下不起作用。

最佳答案

如果 std::accumulate 的代码不在系统头文件中,您将收到警告:

int init=0;
init += *vec.begin() //warning: conversion from 'int64_t' {aka 'long int'} to 'int' may change value [-Wconversion]

但是系统头文件的许多警告被禁用,因为这样的警告会导致许多嘈杂和不相关的消息。

此行为可以重现。假设您有此文件 test.hpp:

int64_t i;
int j = i;

如果在包含此文件的同一目录中编译文件 test.cpp:

  • 使用 c++ -I 。 test.cpp -Wconversion,打印警告信息;
  • 使用 c++ -isystem 。 test.cpp -Wconversion 警告消息 未打印!

这正是标准库的头文件所发生的情况,默认情况下,包含目录是用 -isystem 指定的。

可以使用选项 -Wsystem-header 禁用系统 header 警告消息抑制

Demo

并且在Demo中可以看到,警告信息隐藏在一堆或不相关的警告信息中。

关于c++ - 针对 C++ 隐式转换的警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53690788/

相关文章:

c++ - 如何从 Linux for Windows 交叉编译 SDL 2

c++ - 在 C++ 中使用变量作为数组参数

短裤上的 C# 按位运算 - 为什么要转换为 int?

c - 指针声明/引用后的方括号

C++:使用函数重载和 char 到 int 之间的隐式转换,反之亦然

从函数返回 vector 时 C++ 中止(核心转储)

c++ - 融合多个 Haar 分类器进行人脸检测

c++ - GL_QUADS 绘制凹五边形而不是矩形

c# - 从泛型接口(interface)类型隐式转换

c - MISRA - 禁止转换复杂整数表达式 : Signed versus Unsigned