[英]Excess elements in scalar initializer code compiles with gcc but not g++
只是好奇為什么這個代碼(顯然是錯誤的)使用gcc編譯,但是使用g ++的相同代碼卻沒有。
int main()
{
char *foo = {"bar", "fred", "bob"};
return 0;
}
gcc提供此警告但仍編譯並生成二進制文件:
% gcc -ox xc
xc:在函數'main'中:xc:3:5:警告:標量初始化程序中的多余元素[默認啟用] xc:3:5:警告:(接近初始化'foo')[默認啟用] xc:3 :5:警告:標量初始化程序中的多余元素[默認啟用] xc:3:5:警告:(接近初始化'foo')[默認啟用]
% ls -lx
-rwxr-xr-x 1 overdrive overdrive 6593 Jul 28 21:51 x
g ++給出了這個錯誤,沒有任何二進制文件作為輸出:
% g ++ -oy y.cpp
y.cpp:在函數'int main()'中:y.cpp:3:38:錯誤:標量對象'foo'在初始化程序中需要一個元素
% ls -ly
ls:無法訪問y:沒有這樣的文件或目錄
我使用的gcc和g ++版本是:
% g ++ - 版本
g ++(Debian 4.7.2-5)4.7.2版權所有(C)2012 Free Software Foundation,Inc。這是免費軟件; 查看復制條件的來源。 沒有保修; 甚至不適用於適銷性或特定用途的適用性。
有沒有什么好的理由為什么這個用gcc編譯而不是用g ++編譯? 或者它顯然是一個錯誤?
是的,有一個很好的理由使它成為C ++中的一個硬錯誤,即使在歷史上在C中接受的實現:
template <typename T, int = sizeof(T{1,2,3,4})>
void f();
template <typename T>
void f(...) { }
int main() { f<int>(); }
這是一個有效的C ++程序。 編譯器不能拒絕這一點,抱怨模糊調用或鏈接器錯誤抱怨第一個重載未定義:C ++標准要求f<int>()
調用第二個重載,因為第一個重載有一個替換錯誤。
考慮到這一點,實現面臨兩個選擇:它們可以始終拒絕多余的初始化者,或者他們可以仔細確定標准要求拒絕它們的上下文,以及實現可以繼續允許它們的上下文。 GCC和clang開發人員選擇不斷拒絕它們,這更容易實現。
C沒有任何在編譯時確定表達式有效性的工具,因此對於C,這種擴展無法使有效程序被拒絕。
根據C 2011標准
標量的初始值設定項應為單個表達式,可選擇用大括號括起來
動詞應表示編譯器應發出診斷消息,:)
所以它是編譯器的一個特性或錯誤。:)
根據C標准
1如果預處理轉換單元或轉換單元包含違反任何語法規則或約束的情況,則符合要求的實現應生成至少一條診斷消息(以實現定義的方式標識),即使該行為也明確指定為未定義或實現-defined
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.