C预处理器的任何选项只能扩展特殊的宏?

Hon*_*hen 1 c macros c-preprocessor

对于源级别分析,我需要扩展宏,除了那些#include,是否可能?

例如,在下面的代码片段中,我只希望assert扩展为__assert_fail,而不是包含assert.h和扩展assert.

#include <assert.h>

int main(void) {
  assert(0); // expand this
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

kin*_*rus 5

如果您正在使用gcc,则可以将其-E用作在文件上运行预处理器的开关.这将扩展文件中找到的所有宏,但保持源的其余部分不变.此外,您可以使用在unifdef中在源中展开的任何宏-U.请参阅GCC预处理器.

所以,在这:

#include <assert.h>

int main(int argc, char * argv[])
{
  assert(0);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

调用:

g++ -E assert_test.cpp -o assert_test.ii
Run Code Online (Sandbox Code Playgroud)

返回assert_test.ii:

# 1 "assert_test.cpp"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 30 "/usr/include/stdc-predef.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/predefs.h" 1 3 4
# 31 "/usr/include/stdc-predef.h" 2 3 4
# 1 "<command-line>" 2
# 1 "assert_test.cpp"
# 1 "/usr/include/assert.h" 1 3 4
# 36 "/usr/include/assert.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 371 "/usr/include/features.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 1 3 4
# 385 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4
# 386 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 2 3 4
# 372 "/usr/include/features.h" 2 3 4
# 395 "/usr/include/features.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 1 3 4
# 10 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs-64.h" 1 3 4
# 11 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 2 3 4
# 396 "/usr/include/features.h" 2 3 4
# 37 "/usr/include/assert.h" 2 3 4
# 67 "/usr/include/assert.h" 3 4
extern "C" {


extern void __assert_fail (const char *__assertion, const char *__file,
      unsigned int __line, const char *__function)
     throw () __attribute__ ((__noreturn__));


extern void __assert_perror_fail (int __errnum, const char *__file,
      unsigned int __line, const char *__function)
     throw () __attribute__ ((__noreturn__));




extern void __assert (const char *__assertion, const char *__file, int __line)
     throw () __attribute__ ((__noreturn__));


}
# 2 "assert_test.cpp" 2

int main(int argc, char * argv[])
{
  ((0) ? static_cast<void> (0) : __assert_fail ("0", "assert_test.cpp", 5, __PRETTY_FUNCTION__));
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

所以,至少在我的系统上:

assert(0);
Run Code Online (Sandbox Code Playgroud)

扩展到以下内容:

((0) ? static_cast<void> (0) : __assert_fail ("0", "assert_test.cpp", 5, __PRETTY_FUNCTION__));
Run Code Online (Sandbox Code Playgroud)

where __assert_fail是外部定义的函数(通常包含在其中libc); 因此,要回答您的问题,您可以使用您喜欢的文本替换(sed/awk/perl)实用程序并扩展assert(xyz);((xyz) ? static_cast<void> (xyz) : __assert_fail ("xyz", "<file_name>", 5, __PRETTY_FUNCTION__));