簡體   English   中英

新表達式中詳細類型說明符的條件表達式解析錯誤

[英]Conditional expression parse error on an elaborated-type-specifier inside a new-expression

考慮以下C ++代碼:

struct A {};
struct A* b = (1 == 1) ? new struct A : new struct A;

MSVC接受了這一點,但GCC和Clang沒有。 我想了解根據標准哪個是正確的,以及為什么。

Clang給出的錯誤是:

test.cpp:2:37: error: redefinition of 'A'
struct A* b = (1 == 1) ? new struct A : new struct A;
                                    ^
test.cpp:1:8: note: previous definition is here
struct A {};
       ^
test.cpp:2:37: error: '(anonymous struct at test.cpp:2:37)' cannot be defined in a type specifier
struct A* b = (1 == 1) ? new struct A : new struct A;
                                    ^
test.cpp:2:41: error: expected class name
struct A* b = (1 == 1) ? new struct A : new struct A;
                                        ^
test.cpp:2:53: error: expected '{' after base class list
struct A* b = (1 == 1) ? new struct A : new struct A;
                                                    ^
test.cpp:2:53: error: expected ':'
struct A* b = (1 == 1) ? new struct A : new struct A;
                                                    ^
                                                    :
test.cpp:2:24: note: to match this '?'
struct A* b = (1 == 1) ? new struct A : new struct A;
                       ^
test.cpp:2:53: error: expected expression
struct A* b = (1 == 1) ? new struct A : new struct A;
                                                    ^

這告訴我clang正在嘗試解析標記struct A :作為類說明符 ,冒號引入了一個base-clause ,然后在該解析失敗時保釋。

但是,我不明白為什么它會嘗試解析一個類說明符 最新草案標准中查看new-expression的語法,它使用了一個new-type-id語法生成,它使用了type-specifier-seq ,它使用了type-specifier 但是, 類說明符 不是 類型說明符的替代方法之一 - 它只作為定義類型說明符的替代方法出現。 在另一方面, 闡述類型說明符 類型說明符的選擇之一,並會在這里給我們預期的解析。

雖然我沒有權威的答案,但我有一個有根據的猜測。

最近, 定義類型說明符生成被添加到標准中:如果從2015年末開始查看草案 ,它就不存在了,在引入之前, 類型說明符 確實類別說明符作為其替代方案之一。

引入定義類型說明符生成的更改DR 2141的解決方案,它涉及 - 等待它 - 涉及帶有詳細類型說明符新表達式的歧義(盡管它沒有提到條件表達式 s特別)。

Clang的DR 2141 實施狀態目前列為“未知”。

所以,我受過教育的猜測是:

  • Clang和GCC尚未實施DR 2141的決議
  • 因此,他們試圖基於舊的類型說明符生成來解析新類型的id ,其中包括類說明符作為其替代之一。

我仍然有點困惑的一件事是:即使嘗試解析類說明符失敗,為什么不回溯並嘗試解析一個精心設計的類型說明符呢? 據推測,有必要消除類別說明符詳細類型說明符的歧義,以便在允許其中任何一個的上下文中開始。

在C ++中, structclass相同,只是初始范圍假定為public:而不是private: . 所以,一旦你聲明了struct A {}; 引用該類型的表達式應僅使用類型標識符A ,而不使用struct關鍵字:

A* b = (1 == 1) ? new A : new A;

編輯

正如OP在注釋中指出的那樣, struct A是一個有效的類型名稱,因此它可以作為new的參數出現。 但是, new表達式中的type-id被認為是貪婪的。 以下是cppreference.com的示例:

new int + 1 // syntactically okay, '+1' offsets the pointer returned by 'new int'
new int * 1 // error, type (int *) is assumed and 1 doesn't make sense in '(new (int *)) 1'

因此,當編譯器在class A之后創建一個冒號時,它可能會假設完整的聲明語法( class A : public base_class )看起來不完整並且在這里不允許 - 因此error: redefinition of 'A'消息。

解決方案:通過將其括在括號中來明確界定類型:

1 ? new (struct A) : new struct A;

注意第二個struct A不會引起任何問題,因為它后跟分號,而不是冒號,因此不需要括號。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM