常數運算式
出自 cppreference.com
有多種表達式被稱為常數表達式
目錄 |
[編輯] 預處理器常數表達式
#if 或 #elif 後面的表達式必須展開為
字元常數在 #if 表達式中求值時,可能會根據原始碼字元集、執行字元集或其他實作定義的字元集進行解釋。
|
|
(自 C99 起) |
[編輯] 整數常數表達式
整數常數表達式是僅由以下內容組成的表達式:
- 除了賦值、遞增、遞減、函式呼叫或逗號以外的運算子,但轉型 (cast) 運算子只能將算術類型轉換為整數類型,除非它們是 sizeof 、_Alignof(C11 起)(C23 前)、alignas(C23 起) 或 typeof/typeof_unqual(C23 起) 運算子的運算元。
- 整數常數
- 列舉常數
- 字元常數
- 浮點常數,但僅當它們被直接用作轉換為整數類型的轉型運算子之運算元時
-
sizeof運算子 (其運算元不是 VLA)(C99 起)
|
(自 C11 起) |
|
(C23 起) |
整數常數表達式在編譯時期求值。以下上下文需要被稱為整數常數表達式的表達式:
- 位元欄位 (bit-field) 的大小。
- 列舉常數 的值。
- switch 陳述式 的
case標籤。 - 非 VLA(C99 起) 陣列的大小。
- 整數轉指標的隱式 轉換。
|
(自 C99 起) |
|
(自 C11 起) |
|
(C23 起) |
[編輯] 靜態初始化器
用於具有靜態與 thread_local 儲存期 (storage duration) 之物件的 初始化器中的表達式 或宣告為 constexpr 儲存類別指定符的物件(C23 起),必須是字串字面值或屬於下列類型的表達式:
1) 算術常數表達式:這是由以下內容組成之任何算術類型的表達式:
| (自 C11 起) |
|
(C23 起) |
2) 空指標常數 (例如 NULL)
3) 位址常數表達式,即:
- 空指標
- 指涉具有靜態 儲存期 之物件的 左值 (lvalue),或是函式指派符,經由以下方式轉換為指標:
- 使用單元取址運算子 (&)
- 將整數常數轉型為指標
- 藉由陣列到指標或函式到指標的隱式 轉換
4) 某個完整物件類型的位址常數表達式,加上或減去一個整數常數表達式
|
5) 命名常數,即符合下列情況的識別符:
. 成員存取運算子的後綴表達式,即使是遞迴套用亦然。6) 複合字面值常數,即:
結構或聯合常數分別是指具有結構或聯合類型的命名常數或複合字面值常數。如果成員存取運算子 |
(C23 起) |
7) 實作所接受的其他形式之常數表達式。
與整數常數表達式不同,靜態初始化器表達式不需要在編譯時期求值;編譯器可以自由地將此類初始化器轉換為在程式啟動前呼叫的可執行程式碼。
static int i = 2 || 1 / 0; // initializes i to value 1
| 本節尚不完整 原因:其他微型範例 |
浮點數靜態初始化器的值絕不會比在執行時期執行相同表達式的值精確度低,但可能會更好。
[編輯] 浮點常數表達式
未用於靜態初始化器的浮點類型算術常數表達式,始終會「如同在執行時期般」求值,並受當前捨入模式影響(若啟用 FENV_ACCESS),並依據 math_errhandling 的規定報告錯誤。
void f(void) { #pragma STDC FENV_ACCESS ON static float x = 0.0 / 0.0; // static initializer: does not raise an exception float w[] = { 0.0 / 0.0 }; // raises an exception float y = 0.0 / 0.0; // raises an exception double z = 0.0 / 0.0; // raises an exception }
[編輯] 附註
如果一個表達式求出的值無法由其類型表示,則它不能用作常數表達式。
實作可以接受其他形式的常數表達式。然而,這些常數表達式不被視為整數常數表達式、算術常數表達式或位址常數表達式,因此不能用於需要這些類型常數表達式的上下文。例如,int arr[(int)+1.0]; 宣告了一個 VLA。
[編輯] 參考資料
- C23 標準 (ISO/IEC 9899:2024)
- 6.6 常數表達式 (頁碼:待定)
- C17 標準 (ISO/IEC 9899:2018)
- 6.6 常數表達式 (頁碼:76-77)
- C11 標準 (ISO/IEC 9899:2011)
- 6.6 常數表達式 (頁碼:106-107)
- C99 標準 (ISO/IEC 9899:1999)
- 6.6 常數表達式 (頁碼:95-96)
- C89/C90 標準 (ISO/IEC 9899:1990)
- 3.4 常數表達式
[編輯] 參見
| C++ 文件 關於 常數表達式
|