命名空間
變體
動作

常數運算式

出自 cppreference.com
< c‎ | 語言

有多種表達式被稱為常數表達式

目錄

[編輯] 預處理器常數表達式

#if#elif 後面的表達式必須展開為

字元常數在 #if 表達式中求值時,可能會根據原始碼字元集、執行字元集或其他實作定義的字元集進行解釋。

#if 表達式中的整數算術運算,對於帶號類型使用 intmax_t 的語意,對於無號類型使用 uintmax_t 的語意。

(自 C99 起)

[編輯] 整數常數表達式

整數常數表達式是僅由以下內容組成的表達式:

  • _Alignof(C23 前)alignas(C23 起) 運算子
(自 C11 起)
  • 整數類型的命名常數與複合字面值常數,或是算術類型且為轉型直接運算元的常數
(C23 起)

整數常數表達式在編譯時期求值。以下上下文需要被稱為整數常數表達式的表達式:

(自 C99 起)
(自 C11 起)
  • 位元精確整數類型 (_BitInt(N)) 的位元數 N。
(C23 起)

[編輯] 靜態初始化器

用於具有靜態與 thread_local 儲存期 (storage duration) 之物件的 初始化器中的表達式 或宣告為 constexpr 儲存類別指定符的物件(C23 起),必須是字串字面值或屬於下列類型的表達式:

1) 算術常數表達式:這是由以下內容組成之任何算術類型的表達式:
(自 C11 起)
  • 算術類型的命名常數或複合字面值常數
(C23 起)
2) 空指標常數 (例如 NULL)
3) 位址常數表達式,即:
  • 空指標
  • 指涉具有靜態 儲存期 之物件的 左值 (lvalue),或是函式指派符,經由以下方式轉換為指標:
  • 使用單元取址運算子 (&)
  • 將整數常數轉型為指標
  • 藉由陣列到指標或函式到指標的隱式 轉換
4) 某個完整物件類型的位址常數表達式,加上或減去一個整數常數表達式
5) 命名常數,即符合下列情況的識別符:
  • 列舉常數
  • 預定義常數 (truefalsenullptr 之一)
  • 宣告為儲存類別指定符 constexpr 且具有物件類型
或是對結構或聯合類型的命名常數套用 . 成員存取運算子的後綴表達式,即使是遞迴套用亦然。
6) 複合字面值常數,即:
  • 具有儲存類別指定符 constexpr複合字面值
  • 對結構或聯合類型的複合字面值常數套用 . 成員存取運算子的後綴表達式,即使是遞迴套用亦然。

結構或聯合常數分別是指具有結構或聯合類型的命名常數或複合字面值常數。如果成員存取運算子 . 存取聯合常數的成員,則被存取的成員必須與該聯合常數的初始化器所初始化的成員相同。

(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++ 文件 關於 常數表達式
English Deutsch 日本語 한국어 中文(简体) 中文(繁體)