【发布时间】:2019-12-05 05:25:46
【问题描述】:
在某些情况下,某些标记序列未完全预处理。 例如:
#define EMPTY()
#define DELAY(x) x EMPTY()
#define PRAGMA(args) _Pragma(args)
#define WRAP( BODY ) { BODY }
#define LOOP_Good( body, i, LB, UB ) \
WRAP( \
DELAY(PRAGMA)("omp parallel for") \
for( i = LB; i < UB; ++i ){ \
body \
} \
)
#define LOOP_Bad( body, i, LB, UB ) \
{ \
DELAY(PRAGMA)("omp parallel for") \
for( i = LB; i < UB; ++i ){ \
body \
} \
}
#define LOOP_Good_Again( body, i, LB, UB ) \
{ \
PRAGMA("omp parallel for") \
for( i = LB; i < UB; ++i ){ \
body \
} \
}
// Good
int i;
int lower_i = 0;
int upper_i = 10;
LOOP_Good( printf("%d\n", i);, i, lower_i, upper_i )
// Bad
LOOP_Bad( printf("%d\n", i);, i, lower_i, upper_i )
// Good again
LOOP_Good_Again( printf("%d\n", i);, i, lower_i, upper_i )
其中(使用-E -fopenmp gcc 9.1)扩展为以下(带格式):
int i;
int lower_i = 0;
int upper_i = 10;
// Good
{
#pragma omp parallel for
for( i = lower_i; i < upper_i; ++i ){
printf("%d\n", i);
}
}
// Bad
{
PRAGMA ("omp parallel for")
for( i = lower_i; i < upper_i; ++i ){
printf("%d\n", i);
}
}
// Good again
{
#pragma omp parallel for
for( i = lower_i; i < upper_i; ++i ){
printf("%d\n", i);
}
}
在“好”的情况下,DELAY(PRAGMA) 扩展为 PRAGMA,然后(使用相邻参数)扩展为 _Pragma(...)
在“坏”情况下,DELAY(PRAGMA) 扩展为 PRAGMA,但处理停止,PRAGMA 留在输出中。
如果您采用“坏”输出并对其进行重新预处理(使用之前定义的所有宏),它会正确展开。
唯一的区别是“好”案例DELAY(PRAGMA) 是WRAP 宏的参数的一部分,而“坏”案例不会将DELAY(PRAGMA) 传递给任何宏。如果在“坏”的情况下,我们改为单独使用PRAGMA,问题就解决了(就像在“再次好”的情况下一样)。
在“好”和“坏”案例中出现不同行为的原因是什么?
【问题讨论】:
标签: c macros c-preprocessor preprocessor pragma