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

Warning against 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;
}

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

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

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

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

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

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

int64_t i;
int j = i;

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

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

这正是标准库的 header 个文件所发生的情况,包含目录默认指定为 -isystem

可以使用选项 -Wsystem-header

禁用系统 header 警告消息抑制

Demo

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