我最近看了酷文章: 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