How to prevent such code from compiling?
#include
#include
#include
#include
int main() {
std::
Add -Wsystem-headers
to the command line. Among the many spurious warnings you will find the desired warning.
In file included from (...)include/c++/6.3.0/x86_64-w64-mingw32/bits/c++allocator.h:33:0,
from (...)include/c++/6.3.0/bits/allocator.h:46,
from (...)include/c++/6.3.0/vector:61,
from test.cpp:1:
(...)include/c++/6.3.0/ext/new_allocator.h: In instantiation of 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = short int; _Args = {long long unsigned int}; _Tp = short int]':
(...)include/c++/6.3.0/bits/alloc_traits.h:455:4: required from 'static void std::allocator_traits >::construct(std::allocator_traits >::allocator_type&, _Up*, _Args&& ...) [with _Up = short int; _Args = {long long unsigned int}; _Tp = short int; std::allocator_traits >::allocator_type = std::allocator]'
(...)include/c++/6.3.0/bits/vector.tcc:96:30: required from 'void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {long long unsigned int}; _Tp = short int; _Alloc = std::allocator]'
test.cpp:9:54: required from here
(...)include/c++/6.3.0/ext/new_allocator.h:120:4: error: conversion to 'short int' from 'long long unsigned int' may alter its value [-Werror=conversion]
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^
I know this is not a real solution, although it technically answers the question.
The problem is, that emplace_back
forwards all the arguments, in this case the uint64_t
to the constructor of the contained type. First the argument to emplace_back
is deduced as uint64_t
. No conversion happens at the call of emplace back. The narrowing conversion then happens "inside" the emplace_back
implementation in the system header. The compiler does not know that this is the fault of the caller and suppresses the warning because it is in a system header.