【问题标题】:Controlling the executions of CPP Preprocessor控制 CPP 预处理器的执行
【发布时间】:2019-09-04 06:34:48
【问题描述】:

我正在使用标准 CPP 来预处理任何 C/CPP 文件。 我正在使用以下命令进行预处理:

cpp -idirafter <path_to_header_files> -imacros <sourcefile> <source_file> > <destination_file> 

上面的命令正在用头文件中定义的相应实现替换所有宏。

如果我想要一些包含特定字符串(例如,ASSERT)的特定宏不应该被 cpp 预处理器替换。即,如果某些头文件中定义的名称为 TC_ASSERT_EQ 或 TC_ASSERT_NEQ 的宏不应该被预处理器替换。

有什么方法可以控制吗?

【问题讨论】:

  • 确定宏没有定义?如果它们是在您无法控制的头文件中定义的,这可能会很困难。
  • 先用一些没用过的名字替换掉再替换回来?
  • 如果您创建一个“编译时定义”并使用 -D 将其传递给编译器而不是预编译器会怎样。可以说gcc -DPERMIT_ASSERTS。然后用这个你可以屏蔽掉所有你想保护的宏定义,在头文件和源文件中都使用#if defined作为测试。
  • 在运行之前使用搜索和替换 - 这样 ASSERT 变为 ASSERT__donotsub 等 - 然后在完成后替换回来(如果你有半长列表,你可以使用正则表达式)。这对您来说是一个可行的解决方案吗?
  • 你试过#undef吗?

标签: c++ gcc macros c-preprocessor preprocessor-directive


【解决方案1】:

您可以使用预定义的宏来解决此问题。您可以使用 -D 参数将不同的定义传递给 cpp 和 gcc/g++

例如,您的断言标头可能类似于 my_assert.h:

#ifndef __my_assert_h__
#define __my_assert_h__

#if defined  ASSERT_DEBUG
 #define my_assert(expr) my_assert(expr) /* please dont touch my assertions */
#else
 #define my_assert(expr) ((void)0U)      /* Your assertion macro here */
#endif /* ASSERT_xxx */

#endif /* #ifndef __my_assert_h__ */

您的源文件可以和以前一样。例如test.c:

#include "my_assert.h"
#include <stdio.h>

void foo (int p) {
   my_assert(p==1);
   puts("Tralala\n");
}

int main (void) {
   foo(1);
   return 0;
}

通过上述技巧,您可以运行 cpp -DASSERT_DEBUG test.c

虽然编译仍然像以前一样工作。 gcc test.c

【讨论】:

  • 听起来不错,但我无法控制更改头文件或 .c 文件。我只能按原样使用它们进行预处理。 @hoo2
  • 源文件不受影响。您可以制作本地副本(或 ex 的存储库分支)并创建断言头包装器。或类似的东西。根据我们掌握的信息,我无法准确地告诉你。但逻辑表明你必须改变一些东西。
【解决方案2】:

我已使用 #pragmatoxic TC_ASSERT_EQ 语句在不进行预处理的情况下通过该行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-12
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多