【问题标题】:how exactly does the c preprocessor apply constants and macro substitutions?c 预处理器究竟如何应用常量和宏替换?
【发布时间】:2013-12-18 08:51:47
【问题描述】:

我对 GCC 附带的 c 预处理器感到非常困惑。考虑以下代码: //mleak_cpp.h

#ifndef _NO_LEAK_
#define malloc(x) __malloc_debug(__FILE__,__LINE__,x);

“_NO_LEAK_”常量实际上只是确保使用普通 malloc 的 __malloc_debug 的实现不会被处理并成为递归函数。

//mleak_cpp.cpp

//on top
#include <stdio.h>
#include <string.h>

#define _NO_LEAK_
#include <stdlib.h>
//...rest of the code
//which included __malloc_debug implementation that calls malloc()

这没问题,__malloc_debug 中的 malloc 留在原处,这就是我想要的。出于某种原因,将“stdlib.h”行放在“#define _NO_LEAK_”之上会导致段错误。检查预处理器输出后,显然 __malloc_debug 中的 malloc 调用已被宏替换。

那么导致这种行为的机制是什么?在此先感谢:)

【问题讨论】:

  • 看起来很奇怪。如果您使用的是 GCC,您可以通过“gcc -E”或“g++ -E”运行代码并查看该行上方或下方的&lt;stdlib&gt; 有何变化。
  • C 还是 C++?它们在预处理阶段非常相似,但我们不要将两者混为一谈。
  • 以下划线后跟大写字母 (_NO_LEAK_) 的名称和包含两个连续下划线的名称保留给实现(编译器及其库)。不要使用它们。
  • 这个问题似乎是题外话,因为它由于使用了自定义版本的 stdlib.h 而需要本地化
  • @bummi 我不认罪,因为我不知道是这样的

标签: c++ macros c-preprocessor


【解决方案1】:

预处理器实际上只是在编译阶段开始之前替换文本。仅此而已。

如果你想看看预处理器做了什么,那么你可以指示 gcc 只预处理文件然后在那个时间点停止。执行此操作的命令是:

g++ -E myfile.cpp

也许看到将#define _NO_LEAK_ 放在#include &lt;stdlib.h&gt; 之前与放在之后的代码的区别。

#ifndef _NO_LEAK_
#define malloc(x) __malloc_debug(__FILE__,__LINE__,x);

仅当未定义 _NO_LEAK 时,此代码的 sn-p 才会替换 malloc(x)

【讨论】:

  • 我就是这样做的,除了在 IDE 中。当“stdlib.h”高于“NO_LEAK 时,预处理器实际上会应用宏
  • @user3109672 你能搜索一下stdlib.h,看看里面有没有#define _NO_LEAK_这行吗?
  • 在那种情况下...嗯,我确实解释了常量的名称。如果更改名称有帮助,我会尝试。
【解决方案2】:

抱歉,你们浪费了你们的时间,但我已经找到了错误的原因。我工作的公司正在使用 stdlib.h 的自定义版本,最后包括 mleak_cpp.h,这就是导致这种行为的原因。因此,更改常量的名称或更改预处理器指令的顺序会有所不同。 谁会预见到这一点。

【讨论】:

    猜你喜欢
    • 2011-04-26
    • 1970-01-01
    • 1970-01-01
    • 2010-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-30
    相关资源
    最近更新 更多