【问题标题】:Why #define a empty macro?为什么#define 一个空宏?
【发布时间】:2016-08-17 12:06:00
【问题描述】:

为什么有时我会看到

#define __Empty_macro__

在 C 中?它的用途是什么?例如:

#ifndef _BUILDIN_H_
#define _BUILDIN_H_

//codes never used _BUILDIN_H_ ...

#endif /* _BUILDIN_H_ */

例如,here is the source code of a shell

【问题讨论】:

  • Why are #ifndef and #define used in c++ header files 的可能重复项编辑:问题最初也被标记为 c++。据我所知,问题的答案对于 c++ 和 c 是相同的,并且已经在副本中回答了。
  • 好吧,我称之为未定义的行为
  • @user3528438,你根据什么来称呼那些未定义的行为?
  • @StoryTeller 下划线

标签: c


【解决方案1】:

CC++ 编程语言中,#include 保护,有时称为macro guard,是一种特殊构造,用于在处理包含指令时避免double inclusion 的问题。向头文件添加#include 保护是使该文件具有幂等性的一种方法。例如,假设您想在 child.h 文件中包含 grandfather.hfather.h 头文件。

文件“grandfather.h”

#ifndef GRANDFATHER_H
#define GRANDFATHER_H

struct foo {
   int member;
};

#endif /* GRANDFATHER_H */

文件“father.h”

#include "grandfather.h"

文件“child.c”

#include "grandfather.h"
#include "father.h"

这里,第一次包含 "grandfather.h" 会导致定义宏 GRANDFATHER_H。然后,当“child.c”第二次包含“grandfather.h”时(因为father.h 也包含grandfather.h)通过包含father.h#ifndef 测试返回 false,并且预处理器跳到 #文件grandfather.h 的endif,从而避免了struct foo 的第二个定义。程序编译正确。

【讨论】:

    【解决方案2】:

    使用它们有不同的原因。 例如,如果只需要包含某个库一次。你可以定义一个宏。然后检查是否已定义该宏,以便跳过包含。以此类推。

    这里有一个解释:inclusion guard

    【讨论】:

      【解决方案3】:

      因为“空宏”仍然存在,可以使用#ifdef#ifndef 检查它们是否存在。

      通常,此行为用于防止包含同一标头的多个副本(也称为“包含守卫”,这就是您的示例)。但是,它也可以用于有条件地包含程序的某些部分。

      有时,像 NDEBUG_DEBUG 这样的宏仅仅被定义就可以改变程序输出,例如包含更昂贵的运行时检查,这在最终产品中是不受欢迎的,但有助于在开发过程中跟踪错误。

      自定义“空”定义可以类似地用于在程序构建中包含或排除某些二进制功能。这可能是出于性能(删除日志记录)、安全性(删除程序的敏感部分)、业务原因(某些功能可能需要更昂贵的程序版本)等等。

      【讨论】:

      • 当没有有意义的扩展时,它们还提供了方便的回退。例如,当尝试为您的标头定义可移植的 DLL_EXPORT 规范时。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-25
      • 2019-08-09
      • 2010-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多