[英]Mistake with streaming and conditional operators
最近,我在代碼中遇到了一個錯誤,我認為這可能是一個常見錯誤。 我已將錯誤概括為一個錯誤,並且我想了解為什么它不生成編譯器警告或錯誤。 提前致謝。
錯誤是以下使用條件運算符和流運算符進行提示:
int i=0;
int array[] = {1};
std::cout << false ? array[i++] : 2;
std::cout << std::endl << "i = " << i << std::endl;
// output:
// 0
// i = 1
我假設第一個打印為0
的數字是false
的數字表示。 我不確定編譯器如何解釋其余部分。 array[i++]
正在評估,因為i
已經增加了。 這必須是有效的語法,但是完全不需要解釋。 還是?
對於那些犯了相同錯誤但不知道解決方案的人,更正后的代碼在條件運算符的周圍帶有括號:
int i=0;
int array[] = {1};
std::cout << (false ? array[i++] : 2);
std::cout << std::endl << "i = " << i << std::endl;
// output:
// 2
// i = 0
另外,在條件操作之后調用流運算符會生成編譯器錯誤:
int i=0;
int array[] = {1};
std::cout << false ? array[i++] : 2 << std::endl;
std::cout << std::endl << "i = " << i << std::endl;
// fails to compile
// error: invalid operands of types 'int' and '<unresolved overloaded function type>' to binary 'operator<<'
我假設第一個打印為0的數字是false的數字表示。
正確。
我不確定編譯器如何解釋其余部分。
? :
? :
是三元條件運算符。 第一個子表達式( std::cout << false
)被評估為布爾值,如果為true,則對中間子表達式進行評估( array[i++]
),否則對最后一個子表達式進行評估( 2
)。
std::cout
類型為std::ostream
。 流插入操作符返回流本身。 流具有布爾值的轉換運算符(自C ++ 11開始;在轉換運算符之前是指向void指針的,在這種情況下,該指針具有相同的行為)。 轉換運算符的行為是:
如果流沒有錯誤並且可以進行I / O操作,則返回true。
由於輸出流沒有錯誤,因此轉換返回true,因此對中間子表達式( array[i++]
)進行求值。
我想了解為什么這不會生成編譯器警告或錯誤。
因為沒有錯誤,並且(毫無疑問)沒有警告。 您可能打算寫其他東西,但是您寫的是一個有效的程序,編譯器無法理解您的意圖。
請注意,如果您從三元結果中刪除了任何副作用: std::cout << false ? array[i] : 2;
std::cout << false ? array[i] : 2;
,那么編譯器可能會警告您,因為頂級表達式現在沒有副作用了。
如果啟用了警告,則PS Clang會警告您的程序:
main.cpp:7:20: warning: operator '?:' has lower precedence than '<<'; '<<' will be evaluated first [-Wparentheses]
std::cout << false ? array[i++] : 2;
~~~~~~~~~~~~~~~~~~ ^
main.cpp:7:20: note: place parentheses around the '<<' expression to silence this warning
std::cout << false ? array[i++] : 2;
^
main.cpp:7:20: note: place parentheses around the '?:' expression to evaluate it first
std::cout << false ? array[i++] : 2;
int i = 0; std::cout << false ? array[i++] : 2;
如果std::cout
沒有錯誤,失敗...狀態,則std::cout.operator<<(bool)
將轉換為布爾值true
。 i++
得到評估,整個語句產生array[0]
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.