[英]Compound literals and function-like macros: bug in gcc or the C standard?
在C99中,我們有復合文字,它們可以傳遞給函數,如:
f((int[2]){ 1, 2 });
但是,如果f
不是函數而是函數式宏,那么由於預處理器將其解析為不是一個參數而是作為兩個參數,“ (int[2]){ 1
”和“ 2 }
” 。
這是gcc或C標准中的錯誤嗎? 如果它是后者,那幾乎排除了所有透明使用類似函數的宏,這似乎是一個巨大的缺陷......
編輯:作為一個例子,人們會期望以下是一個符合要求的程序片段:
fgetc((FILE *[2]){ f1, f2 }[i]);
但由於fgetc
可以實現為宏(雖然需要保護其參數而不是多次評估它),但這段代碼實際上是不正確的。 這對我來說似乎很令人驚訝。
自C89以來,這個“bug”已存在於標准中:
#include <stdio.h>
void function(int a) {
printf("%d\n", a);
}
#define macro(a) do { printf("%d\n", a); } while (0)
int main() {
function(1 ? 1, 2: 3); /* comma operator */
macro(1 ? 1, 2: 3); /* macro argument separator - invalid code */
return 0;
}
我實際上沒有查看標准來檢查這個解析,我已經采用了gcc的話,但非正式地需要匹配:
每個?
勝過運算符優先級和參數列表語法,使第一個語句有效。 第二個沒有這樣的運氣。
這是按照C標准,與C ++中的類似,以下是一個問題:
f(ClassTemplate<X, Y>) // f gets two arguments: 'ClassTemplate<X' and 'Y>'
如果在C99中添加一些額外的括號是合法的,您可以使用:
f(((int[2]){ 1, 2 }));
^ ^
從C99§6.10.3/ 11開始,規定此行為的規則如下:
由最外部匹配括號限定的預處理標記序列形成類似函數的宏的參數列表。
列表中的各個參數由逗號預處理標記分隔,但匹配內部括號之間的逗號預處理標記不會分隔參數。
在某種程度上它是一個bug,它是標准的,而不是gcc(即,在這方面,我相信gcc正在做標准要求的)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.