我有以下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
是因为从int
到int64
的隐式转换(请参见0
作为accumulate
函数的第三个参数)。将0
替换为(int64_t)0
后,一切正常。
但是我可以在编译时检测到这种情况吗? -Wconversion
在这种情况下不起作用。
答案 0 :(得分:5)
如果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
禁用系统标题警告消息抑制
在 Demo 上可以看到警告消息隐藏在一堆或不相关的警告消息中。