[英]How do C++ compilers distingush between shift bits left / shift bits right and ostream<< / ostream>> operators?
[英]How compilers identify the length of byte shift operators
考慮以下行:
int mask = 1 << shift_amount;
我們知道mask
是 4 個字節,因為它被顯式聲明為int
,但是要移動的這個1
的長度未知。 如果編譯器選擇類型為char
它將是 8 位,或者它可以是大小為 16 位的unsigned short
,因此移位結果將真正取決於編譯器關於如何處理該1
的決定的大小。 編譯器如何在這里決定? 以這種方式保留代碼是否安全,或者應該改為:
int flag = 1
;
int mask = flag << shift_amount;
1
是一個int
(通常為 4 個字節)。 如果您希望它是int
以外的類型,則可以使用后綴,例如1L
for long
。 有關更多詳細信息,請參閱https://en.cppreference.com/w/cpp/language/integer_literal 。
你也可以使用像(long)1
這樣的強制轉換,或者如果你想要一個已知的固定長度, (int32_t)1
。
正如 Eric Postpischil 在評論中指出的那樣,小於int
的值(如(short)1
沒有用處,因為<<
的左側參數無論如何都會提升為int
。
2018 C 標准在 6.4.4 3 中說:
每個常量都有一個類型,由其形式和值決定,稍后詳述。
這意味着我們總是可以從常量本身的文本中判斷常量的類型是什么,而不用考慮它出現的表達式。(這里,“常量”實際上是指一個字面量:一個其值由其給出的事物文本。例如34
和'A'
字面上表示數字 34 和字符 A,而標識符foo
表示某些 object。)
(這個答案具體針對C。下面描述的規則在C++中有所不同。)
6.4.4 的小節詳細介紹了各種常量(整數、浮點數、枚舉和字符)。 沒有可以用int
表示的后綴的 integer 常量是int
,因此1
是int
。
如果 integer 常量有后綴或不適合int
,則根據 6.4.4.1 5 中的表,其類型受其后綴、其值以及是十進制、八進制還是十六進制的影響。
如果浮點常量沒有后綴,則為double
, f
或F
為float
, l
或L
為long double
。
枚舉常量(用enum
聲明)具有int
類型。 (並且這些不是我上面描述的直接文字,因為它們是值的名稱,但名稱確實通過enum
聲明表示值。)
沒有前綴的字符常量的類型為int
。 帶有前綴L
、 u
或U
的常量分別具有wchar_t
、 char16_t
或char32_t
類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.