標籤:

C++中int(a) 為什麼沒有轉型?

const int a = 10;

void func()
{
std::cout &<&< a &<&< std::endl; int(a); std::cout &<&< a &<&< std::endl; }

怎麼理解這段代碼的輸出?

環境:vs2013

然後為什麼下面這段代碼會報重定義?

double k = 1.9;
std::cout &<&< k &<&< std::endl; int(k); std::cout &<&< k &<&< std::endl;


C++標準§ 6.8 Ambiguity resolution:

第1條:

There is an ambiguity in the grammar involving expression-statements and declarations: An expression statement with a function-style explicit type conversion as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (. In those cases the statement is a declaration.

第2條:

[ Note: If the statement cannot syntactically be a declaration, there is no ambiguity, so this rule does not apply. The whole statement might need to be examined to determine whether this is the case. This resolves the meaning of many examples. [ Example: Assuming T is a simple-type-specifier,

T(a)-&>m = 7; // expression-statement
T(a)++; // expression-statement
T(a,5)&<&

In the last example above, g, which is a pointer to T, is initialized to double(3). This is of course ill-formed for semantic reasons, but that does not affect the syntactic analysis. —end example ]

The remaining cases are declarations. [ Example:

class T {
// ...
public:
T();
T(int);
T(int, int);
};

T(a); // declaration
T(*b)(); // declaration
T(c)=7; // declaration
T(d),e,f=3; // declaration
extern int h;
T(g)(h,2); // declaration

—end example ] —end note ]

----------------------------------------------------------------------------------------------------------

C++標準明確規定:

  • 如果在一條語句中T(x)被解析為變數聲明會導致該語句不合法,T(x)就會被解析為函數式轉型。
  • 如果T(x)被解析為轉型和聲明都合法,則T(x)被視為變數聲明。

----------------------------------------------------------------------------------------------------------

在第一個例子中,int(a) 聲明了一個局部變數 a ,該變數隱藏了外部常量 a ,導致兩個 a 的地址不同。

在第二個例子中,double k 並沒有在大括弧外面,聲明另一個變數 k 就會報錯。


#include &
using namespace std;

int main() {
// your code goes here
int(k) = 123;
std::cout &<&< k &<&< std::endl; return 0; }

表示int(k) 可以被解析成 定義一個k。

第一個通過編譯並且地址不同是因為他就是兩個變數,因為在不同的scope所以不發生declaration衝突。

補充:

int(k)這種東西究竟可能會解析成什麼?

[1]Explicit type conversion

The functional cast expression consists of a simple type specifier or a typedef specifier (in other words, a single-word type name: unsigned int(expression) or int*(expression) are not valid), followed by a single expression in parentheses. This cast expression is exactly equivalent to the corresponding C-style cast expression.

也就是說這種情況下和C-style cast一樣的。

[2]一個

下文是ISO/IEC14882的8.4一部分(不完整)

Declarators have the syntax

declarator:
ptr-declarator
noptr-declarator parameters-and-qualifiers trailing-return-type
ptr-declarator:
noptr-declarator
ptr-operator ptr-declarator
noptr-declarator:
declarator-id attribute-specifier-seq[opt]
noptr-declarator parameters-and-qualifiers
noptr-declarator [ constant-expressionopt] attribute-specifier-seq[opt]
( ptr-declarator )

所以int(k)裡面,k是一個simple identifer--&>declarator-id--&>noptr-declarator--&>ptr-declarator

所以(k)就是一個( ptr-declarator ) --&> noptr-declarator --&> declarator

又因為3.1.2,所以int (k)還可以解析成一個定義式。

經過確認發現題主的情況沒有二義性。規定就是要解析成一種definition.

6.8.1

There is an ambiguity in the grammar involving expression-statements and declarations: An expression-
statement with a function-style explicit type conversion (5.2.3) as its leftmost subexpression can be indis-
tinguishable from a declaration where the first declarator starts with a (. In those cases the statement is a
declaration.


推薦閱讀:

編程除了學語言還要學什麼?
編程中你們都習慣怎麼使用大括弧?
關於指針數組的初始化的一個問題?
Qt 框架哪些方面效率高,哪些方面效率低?
C++怎樣讀取文件才有最快的速度?

TAG:C |