C 可选初始值设定项,通过预处理器欺骗?

C 可选初始值设定项,通过预处理器欺骗?,c,c-preprocessor,C,C Preprocessor,我知道这是行不通的,但希望你能看到我在努力做什么 #if ASSIGN_ALLOWED #define MAYBE_SKIP_REST_OF_LINE #else #define MAYBE_SKIP_REST_OF_LINE ; // #endif char str[80] MAYBE_SKIP_REST_OF_LINE = "Hello\n"; long array[3] MAYBE_SKIP_REST_OF_LINE = { 7,8,9 }; int x

我知道这是行不通的,但希望你能看到我在努力做什么

#if ASSIGN_ALLOWED
    #define MAYBE_SKIP_REST_OF_LINE 
#else
    #define MAYBE_SKIP_REST_OF_LINE ; //
#endif

char str[80]  MAYBE_SKIP_REST_OF_LINE = "Hello\n";
long array[3] MAYBE_SKIP_REST_OF_LINE = { 7,8,9 };
int x         MAYBE_SKIP_REST_OF_LINE = 3;
//...many many more similar lines...

有没有办法做到这一点

由于评论在预处理器运行时被过滤掉,我不这么认为

确定:

#ifdef ASSIGN_ALLOWED
    #define OPTIONAL_INITIALISER(x) = x 
#else
    #define OPTIONAL_INITIALISER(x) 
#endif

char str[80] OPTIONAL_INTIALISER("Hello\n");
#define ARRAY_INIT { 7,8,9 }
long array[3] OPTIONAL_INITIALISER(ARRAY_INIT);
#undef ARRAY_INIT
int x OPTIONAL_INITIALISER(3);
任何包含逗号的初始化器,如示例中的
array
,都需要从它们自己的宏中展开,如上面的
array\u INIT
。如果您的编译器支持C99 varargs宏,则可以采用更简洁的方式:

#ifdef ASSIGN_ALLOWED
    #define OPTIONAL_INITIALISER(...) = __VA_ARGS__ 
#else
    #define OPTIONAL_INITIALISER(...) 
#endif

char str[80] OPTIONAL_INTIALISER("Hello\n");
long array[3] OPTIONAL_INITIALISER({ 7,8,9 });
int x OPTIONAL_INITIALISER(3);

这将取决于预处理器如何处理注释和宏。如果它在宏展开后剥离注释,那么您的操作将一帆风顺,但由于预处理器的实现,它可能无法正常工作

你可以试试这个吗?(不过会很混乱)


预处理器将删除已注释的部分。试着跑步

gcc -E source.c

这将在您的代码上运行预处理器,但实际上不会编译它,允许您查看宏扩展后发生的情况。你应该注意到所有的注释都从任何扩展的宏中消失了。

7,8,9中的逗号不会导致预处理器认为宏已经被赋予了三个参数吗?米克:啊,是的,修改为修复这个问题。现在就改好了。另一个建议:在宏定义中添加大括号,即
={VA_ARGS}
;这也适用于标量类型:
intfoo={4}有效吗?您想用该技巧解决哪种类型的问题?对不起,太复杂了,无法解释。但这是对一个非常大、非常旧的程序的可怕攻击的一部分。我并不是建议任何人复制我。评论被剥夺之前,还为时过早,以工作。也许你应该在建议答案之前检查一下;它将避免否决票。(不,不是我的。)准确的观察——但没有关于如何达到预期结果的建议。
gcc -E source.c