2014-12-03 23 views
21

所有編譯我試圖正確地拒絕代碼爲什麼'int x = +「foo」;'類型錯誤,但不是語法錯誤?

int main() { 
    int x = "foo"; 
} 

與一種類型的誤差:const char[4]不能轉換到int。爲什麼,同樣的編譯器(包括Ideone.com)給予相同錯誤

int main() { 
    int x = + "foo"; 
} 

,而不是(因爲我本來以爲)語法錯誤的因爲...標誌+的?我的第一個想法是const char[4]衰減到一個指針,而指針又被視爲一個整數值,所以+表示「正值」。雖然似乎有點牽強,但我預計會在錯誤消息中看到const char*

+0

http://ideone.com/LYHiH0將'x'改爲'const char *'編譯,顯然這個加號不是語法錯誤。但我很想知道爲什麼。作爲一個方面說明,在我的ideone中運行時,鏈接的錯誤表明'const char *'不能轉換爲'int',而不是'const char [4]'。 – IllusiveBrian 2014-12-03 15:41:51

回答

34

語法不涉及類型系統意義上的類型(整數和字符和指針),只包含關鍵字,運算符,表達式在語法上的類型。在C++語法中,+是可以在表達式之前的一元前綴運算符。 "foo"是一個表達式。因此,就解析器而言,+"foo"是一個有效的表達式。

你的想法,字符串常量衰變成一個指針和+是一個指針上的任何操作是正確的,下面的程序甚至可以編譯和運行:

#include <iostream> 

int main() 
{ 
    const char *message = +"Hello!\n"; 
    std::cout << message; 
} 

...那是無關緊要的。你看到的是一個類型錯誤,而不是語法錯誤。

編輯或許更令人信服的是,你可以重載一元+事實:

#include <iostream> 

struct SomeType { 
    const char *operator+() const 
    { 
     return "Hello, world!\n"; 
    } 
}; 

int main() 
{ 
    SomeType x; 
    std::cout << +x; 
} 
+0

我以某種方式假定'+'是一個一元前綴運算符,它只能在數字文字之前(即在解析時容易檢測到的東西)。它沒有發生在我之前,它可以在任何表達之前! – 2014-12-03 15:49:08

+0

@FrerichRaabe你甚至可以重載它,看到更新的答案:) – 2014-12-03 15:52:38

+3

有趣的事實包括由於負面或正面的跡象是一般操作符而不是文字的語法的一部分,C++實現基於二進制補碼錶示整數,所以不可能將有符號類型的最負值表示爲否定字面值。例如,對於16位「int」,表達式「-32768」相當於「0-32768」,其涉及超出範圍的正值32768:無效。 – 2014-12-03 15:59:36

9

一元+適用於指針,它只是返回類型的值並且不執行上的指針積分促銷所以結果是一個指針不是一個整數類型,從C++草案標準部5.3.1一元運算符

The operand of the unary + operator shall have arithmetic, unscoped enumeration, or pointer type and the result is the value of the argument. Integral promotion is performed on integral or enumeration operands. The type of the result is the type of the promoted operand.

文字串是常量字符的陣列,從2.14.5字符串文字

[...]A narrow string literal has type 「array of n const char」,[...]

這將衰減在此上下文中的指針。

+1

感謝您指出相關的標準部分。 – 2014-12-03 15:49:56

7

一元+操作者可以應用到指針類型:

C++11 5.3.1 [expr.unary.op]/7: The operand of the unary + operator shall have arithmetic, unscoped enumeration, or pointer type and the result is the value of the argument.

所以字面陣列被轉換爲const char *,並且操作者施加到該指針,不能將指針分配給int正如前在第一個例子中。

+0

有趣的是,使用Visual Studio 2012編譯我的測試程序會產生錯誤消息:const char [4]不能轉換爲int,即指針衰減在錯誤消息中不再可見(Ideone.com似乎使用了一個編譯,儘管使用'const char *')。 – 2014-12-03 15:51:06

4

Why is 'int x = + 「foo」;' a type error but not a syntax error?

因爲沒有語法錯誤。存在語義錯誤。

解析語句後,編譯器確定此類初始化是否可用。實際上在語法上,該語句看起來像

int x = + (expression); 

從語法上來說,這種說法是正確的。此外,一元加可以應用於指針。

相關問題