2013-12-18 65 views
5

我偶然發現了我不明白的代碼。下面是它的一個簡化版本:C++ 98大括號const標量初始化

template <int> struct A {}; 

int const i = { 42 }; 
typedef A<i> Ai; 

int const j = 42; 
typedef A<j> Aj; 

此代碼在C++ 98模式下編譯爲GCC,但不在Clang中編譯。鏘產生以下錯誤:

$ clang -Wall -Wextra -std=c++98 -c test.cpp 

test.cpp:4:11: error: non-type template argument of type 'int' is not an integral constant expression 
typedef A<i> Ai; 
     ^
test.cpp:4:11: note: initializer of 'i' is not a constant expression 
test.cpp:3:11: note: declared here 
int const i = { 42 }; 
     ^

據我瞭解有和沒有大括號應該是相當於int初始化。 Clang將i初始化爲42,但並不認爲這是編譯時間常量。

此代碼在C++ 11模式下編譯良好。

是否有原因j被視爲編譯時間常量,i是不是?或者它僅僅是Clang中的一個錯誤?

更新:我在LLVM bug跟蹤器中打開了一個ticket這個問題。

+0

我會說這是在編譯器中的錯誤。 – Raxvan

+2

@Raxvan:這是一個非常大膽的陳述......考慮到它在C++ 11中工作,而不是在C++ 98中,它似乎是非常慎重的,所以我實際上期望它是*按規格*(在Clang部分) ,並且gcc像往常一樣更寬鬆。 –

+0

@MatthieuM .:我認爲這是他想說的:它是一個gcc中的bug。沒有C++ 98的語法,clang正確地拒絕它。所以接受它在gcc中,儘管不是C++ 98,是一個錯誤。 – PlasmaHH

回答

2

編譯器錯誤指出"template argument of type 'int' is not an integral constant expression"int const i = { 42 };

根據98 standard模板參數應屬於這一類:

14.3.2/1

A template-argument for a non-type, non-template template-parameter shall be one of:

  • an integral constant-expression of integral or enumeration type; or

...

和積分常數表達式的定義int const i fa LL這一類:

5.19 Constant expressions

An integral constant-expression can involve only literals (2.13), enumerators, const variables or static data members

併爲i初始化(像邁克·西摩後):

8.5 Initializers /13

If T is a scalar type, then a declaration of the form

T x = { a };

is equivalent to

T x = a;

現在基於this postconst intint const聲明應該是相同的(找不到這特別在標準中)使得i a const變量。因此,無論初始化方法如何,i的任何用法都應該是一個整型常量表達式。看起來在叮噹中有一個錯誤。檢查網絡我找不到只有兩個或多或少類似的錯誤報告:

http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=666539

http://lists.cs.uiuc.edu/pipermail/llvmbugs/2011-March/017353.html

5

是的,雙方的聲明是等價的,每個C++ 98 8.5/13:

If T is a scalar type, then a declaration of the form

T x = { a }; 

is equivalent to

T x = a; 

所以這兩個變量是恆定的,並從一個常量表達式初始化,所以(據我所知)應該都可以用作常量表達式。

1

我認爲鏘是正確的。初始值設定項列表不是表達式。聚集對象和基本對象的初始化有所不同。當一個POD對象被初始化時,每個初始化器都可以被認爲是一個const表達式。然而,當你處理基本類型時,初始化器列表不是一個表達式,也不是一個常量表達式。

在標準第14號有寫:

The source type is not defined when the initializer is brace-enclosed or when it is a parenthesized list of expressions