我最近看了酷文章: https://akrzemi1.wordpress.com/2015/08/20/can-you-see-the-bug/ 降低版本上ideone打我得到了令人惊讶的行为:将const添加到size_t是否会导致编译失败的标准行为?
#include <iostream>
#include <cassert>
using namespace std;
int main() {
const size_t sz=258;
string s{sz,'#'};
assert(2==s.size());
}
不能编译,但 与常量同一程序中删除编译:
#include <iostream>
#include <cassert>
using namespace std;
int main() {
size_t sz=258;
string s{sz,'#'};
assert(2==s.size());
}
所以我的问题是这个标准是必需的,或者只是编译器决定一个是编译器警告,另一个是编译器错误。
如果有帮助,这里是来自GCC 5.1(TNX godbolt)的错误和警告
!!error: narrowing conversion of '258ul' from 'size_t {aka long unsigned int}' to 'char' inside { }
!!warning: narrowing conversion of 'sz' from 'size_t {aka long unsigned int}' to 'char' inside { } [-Wnarrowing]
好人铛3.6给出了在这两种情况下的错误,但仍然是一个问题,是一个合法和不良C++和其他非法C++?
请注意,该标准只需要诊断。它不区分错误和警告。在这个错误报告中讨论了这个问题:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55783 –
根本问题是'string s {32,32,32};'应该工作。但'32'是一个int,而int-char是一个缩小的转换。我们知道'32'可以安全地缩小,正是因为它是编译时常量。由于这个原因,编译时常量的处理方式不同。 (它不只是'const' - 'const sz = rand()'不是一个编译时常量,在缩小时可能会溢出) – MSalters