Forbid integer conversion with precision loss

后端 未结 3 735
庸人自扰
庸人自扰 2021-02-15 18:00

How to prevent such code from compiling?

#include 
#include 
#include 
#include 

int main() {
  std::         


        
3条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-02-15 18:24

    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.

提交回复
热议问题