c – 禁止精度损失的整数转换

如何防止这样的代码编译?
#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 -std = c 14 -Wall -Wextra -Werror -pedantic -Wold-style-cast -Wconversion -Wsign-conversion甚至都没有警告它.该示例还使用std :: vector< uint16_t>编译而没有警告.

解决方法

将-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实现的“内部”.编译器不知道这是调用者的错误并且抑制警告,因为它在系统头中.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...