Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Warning against C++ implicit conversion

I have this C++ code:

#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;
}

It returns sum = 0 because implicit conversion from int to int64 (see 0 as third argument of accumulate function). After replacing 0 with (int64_t)0 everything works fine.

But can I detect such things in compile time? -Wconversion does not work in this case.

like image 698
Pavel Naydenov Avatar asked Dec 09 '18 09:12

Pavel Naydenov


1 Answers

If the code of std::accumulate were not in a system header file, you would get the warning:

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

But many warnings are disabled for system header files because such warning would cause many noisy and irrelevant messages.

This behavior can be reproduced. Suppose you have this file test.hpp:

int64_t i;
int j = i;

If you compile a file test.cpp in the same directory that includes this file:

  • with c++ -I . test.cpp -Wconversion, the warning message is printed;
  • with c++ -isystem . test.cpp -Wconversion the warning message is not printed!

This is exactly what happens to header files of the standard library, the include directory is by default specified with -isystem.

The system header warning message suppression can be disabled with option -Wsystem-header

Demo

And it can be seen on the Demo the warning message is hidden within a bunch or irrelevant warning messages.

like image 111
Oliv Avatar answered Oct 20 '22 04:10

Oliv