如何防止此类代码被编译?
#include <vector>
#include <limits>
#include <iostream>
#include <cstdint>
int main() {
std::vector<int16_t> v;
v.emplace_back(std::numeric_limits<uint64_t>::max());
std::cout << v.back() << std::endl;
return 0;
}
g++ 和 clang with-std=c++14 -Wall -Wextra -Werror -pedantic -Wold-style-cast -Wconversion -Wsign-conversion
甚至不警告它。该示例也可以在没有警告的情况下进行编译std::vector<uint16_t>
Add -Wsystem-headers
到命令行。在众多虚假警告中,您会找到所需的警告。
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<std::allocator<_Tp1> >::construct(std::allocator_traits<std::allocator<_Tp1> >::allocator_type&, _Up*, _Args&& ...) [with _Up = short int; _Args = {long long unsigned int}; _Tp = short int; std::allocator_traits<std::allocator<_Tp1> >::allocator_type = std::allocator<short int>]'
(...)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<short int>]'
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)...); }
^
我知道这不是一个真正的解决方案,尽管它在技术上回答了问题。
问题是,emplace_back
转发所有参数,在本例中uint64_t
到所包含类型的构造函数。首先论证emplace_back
推导为uint64_t
。调用 emplace back 时不会发生任何转换。然后缩小转换发生在“内部”emplace_back
在系统头中实现。编译器不知道这是调用者的错误,因此会抑制警告,因为它位于系统标头中。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)