簡體   English   中英

為什么 Clang 抱怨本地復合文字的“初始化元素不是編譯時常量”?

[英]Why does Clang complain an "initializer element is not a compile-time constant" for a local compound literal?

使用以下代碼,

#define REINT(T, X) (union {__typeof__(X) x; T t;}){X}.t

int f2i(float x) {
  return REINT(int, x);
}

float i2f(int x) {
  return REINT(float, x);
}

float f2i2f(float x) {
  return REINT(float, REINT(int, x));
}

Clang 抱怨f2i2f “初始化器元素不是編譯時常量”。 這看起來很奇怪,因為復合文字“具有與封閉塊關聯的自動存儲持續時間”(6.5.2.5p5),並且此類對象的初始化列表中的元素不必是編譯時常量。

在問題下的評論中,提到這是一個已知的錯誤,並且“這是一個相當古老的錯誤,仍未修復” 所以在它修復之前,你必須解決它。

我能找到的最簡單的觸發錯誤的代碼是

int x = 3;
struct { __typeof__((int){x}) y; };

在以下情況下會觸發該錯誤:

  • 具有非常量初始值設定項的復合文字
  • __typeof__的參數中使用
  • structunion中的成員變量的聲明中

f2ii2f函數中使用REINT宏時,它不會觸發錯誤,因為參數X不是復合文字。 這些函數中的X是具有原始類型的變量。

但是在f2i2f函數中,傳遞給REINT外部調用的參數X包含一個復合文字。 並且該復合文字是__typeof__參數的一部分,用於外部union的定義。

所以解決方法是避免嵌套REINT宏。 例如, f2i2f可以如下實現:

float f2i2f(float x) {
    int temp = REINT(int, x);
    return REINT(float, temp);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM