在库函数原型的参数声明列表中出现的标识符若被宏定义,是否会导致语法错误?
Shall macro definition of an identifier (placed before an associated header is included and with definition other than itself) that appears within the list of parameter declarations in a library function prototype lead to syntax error?
示例:
#define stream 23
/*
* int fprintf(FILE * restrict stream, const char * restrict format, ...);
*/
#include <stdio.h> /* leads to syntax error ?? */
据我所知,在C11中,标识符 stream 并非保留。
然而,标识符 stream 出现在库函数原型的参数声明列表中 fprintf(见上文)。因此,对 FILE * restrict 23 的处理应导致语法错误。这样对吗?
再问:C11(及更新版本)是否要求实现必须在所有库函数原型的参数声明列表中使用出现在标准中的确切标识符?换句话说:如果实现使用,例如 __stream 而不是 stream,是否会违反标准?
解决方案
据我所知,在C11中,标识符
stream并非保留。
该标识符的形式并不会自动使其成为保留标识符。没有文档表明它会被 stdio.h 或任何其他标准库头文件定义为宏,也没有在任何标准库头文件中被定义为具有外部链接性,或在文件作用域中定义。没有其他保留标识符的情况(C11 7.1.3/1-2)。因此,你是对的,stream 不是保留标识符。
然而,标识符
stream出现在库函数原型的参数声明列表fprintf中(见上文)。
是吗?函数参数名在规范中出现,是为了阐明参数的用途并便于规范引用它们,但除了随同的函数体(若有)外,参数名并不重要。完全不能确定规范是否应被解释为在包含相应头文件时,章节7中给出的函数参数名需要被翻译/遵循。
因此,对
FILE * restrict 23的翻译应导致语法错误。这样对吗?
这个问题本身就无关紧要。因为标识符 stream 的确并未被保留,这是一段严格符合规范的程序:
#define stream 23
#include <stdio.h>
int main(void) {
return 0;
}
规范规定:
兼容的托管实现应当接受任何严格符合规范的程序。
(C11 4/6)
因此,符合规范的实现将接受该程序。
C11(及更新版本)是否要求实现必须在所有库函数原型的参数声明列表中使用出现在标准中的确切标识符?
正如上文所述,这一点既不清楚也无实际意义。然而,因为符合规范的实现必须接受上面的示例程序及类似的程序,我认为最一致的解释是:C不要求把标准库头文件展现给程序,好像规范中出现的函数参数名确实出现在头文件中一样。