簡體   English   中英

clang和gcc與復合文字的不同行為

[英]clang and gcc different behavior with compound literal

最近遇到了復合文字,據我所知,以下是使用它的正確方法。 幸運的是,它適用於ubuntu上的gcc和clang。

int main() {
  int *p = (int []) {1, 2};
  return 0;
}

但是,我注意到使用復合文字的另一種方法,如下所示。 感覺有點奇怪; 這只是數組初始化器。 下面的代碼使用clang編譯好,但是使用gcc, array initialized from non-constant array expression失敗。

int main() {
  int p[] = (int []) {1, 2};
  return 0;
}

這是故意還是什么?

ENV:

  • gcc(Ubuntu 4.8.2-19ubuntu1)4.8.2
  • Ubuntu clang版本3.5-1ubuntu1(主干)(基於LLVM 3.5)

CMD:

  • gcc test.c
  • clang test.c

簡短回答:Clang承認該程序使用了擴展名

接受你寫的內容, int p[] = (int []) {1, 2}; ,是一個Clang擴展。 GCC被允許拒絕它,因為它不是C99的一部分( C99標准引入了復合文字,可以作為參考)。

事實上,我的Clang版本可以在你的程序上發出警告。 有趣的是,它將您的行稱為“GNU擴展”:

~ $ clang -std=c99 -pedantic t.c
t.c:2:7: warning: initialization of an array of type 'int []' from a compound
      literal of type 'int [2]' is a GNU extension
      [-Wgnu-compound-literal-initializer]
  int p[] = (int []) {1, 2};
      ^     ~~~~~~~~~~~~~~~
1 warning generated.
~ $ clang -v
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.4.0
Thread model: posix

答案很長

int p[] = (int []) {1, 2}; 是宣言。 它應該遵循第6.7節中給出的語法:

6.7聲明

句法

1

  宣言:\n     declaration-specifiers init-declarator-list opt ;\n\n 聲明-符:\n     存儲類說明符聲明,符選擇\n     type-specifier declaration-specifiers opt\n     type-qualifier聲明 - 說明符opt\n     function-specifier declaration-specifiers opt\n\n 初始化聲明符列表:\n     初始化聲明符\n     init-declarator-list,init-declarator\n\n 初始化聲明符:\n     聲明符\n     declarator =初始化器 

所有這些都取決於初始化程序的定義,可以在6.7.8中找到:

6.7.8初始化

句法

1

  初始化:\n     賦值表達式\n     {initializer-list}\n     {initializer-list,}\n ... 

...

12本子條款的其余部分涉及具有聚合或聯合類型的對象的初始值設定項。

...

16否則,具有聚合或聯合類型的對象的初始值設定項應該是元素或命名成員的大括號括起來的初始值設定項列表

6.7.8:16的重點是我的。 基本上,這是您的程序不滿足的C99標准的一部分。

復合文字在C99和C ++中具有不同的行為。

在C ++中,它只有一個表達式存儲持續時間,而不是自動持續時間。 如果這是在C ++模式下編譯的,那么它將無法工作,因為復合文字對象在表達式完成后消失。

這可能解釋了@ cremno關於靜態存儲持續時間和自動存儲持續時間的描述。

暫無
暫無

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

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