如果你只有一个标识符,#define会怎么做

Jus*_*tin 3 c++ compiler-construction c-preprocessor

通常#define将用于定义常量或宏.但是,以下列方式使用#define是有效的代码.

#define MAX // does this do anything?
#define MAX 10 // I know how to treat this.
Run Code Online (Sandbox Code Playgroud)

因此,如果我#define MAX 10,我知道我的预处理器用10替换MAX的所有实例.如果某人自己使用#define MAX但没有后续替换值,则它是有效的.这实际上做了什么吗?

我的理由是我在c ++中为c编写编译器并且需要处理预处理器指令但是我无法确定在发生这种情况时是否需要有任何功能,或者我只是忽略了这一次我的预处理完成了.

我的第一直觉是,这将在我的符号表中创建一个没有名为MAX的值的符号,但同样可能它什么都不做.

作为一个问题的补充,这是一种我知道的糟糕形式,但我真的很好奇.实际代码中是否存在使用此类内容的情况?

谢谢,宾克斯

ala*_*ain 9

一个典型的例子是标题保护:

#ifndef MYHEADER
#define MYHEADER
...
#endif
Run Code Online (Sandbox Code Playgroud)

您可以测试是否使用#ifdef/ 定义了某些内容ifndef.


Jus*_*ica 7

它创建一个带有空白定义的符号,以后可以在其他预处理器操作中使用.有几件事可以用于:

1)分支.

考虑以下:

#define ARBITRARY_SYMBOL

// ...

#ifdef ARBITRARY_SYMBOL
    someCode();
#else   /* ARBITRARY_SYMBOL */
    someOtherCode();
#endif  /* ARBITRARY_SYMBOL */
Run Code Online (Sandbox Code Playgroud)

符号的存在可用于分支,有选择地为情况选择适当的代码.很好地利用这个是处理特定于平台的等效代码:

#if defined(_WIN32) || defined(_WIN64)
    windowsCode();
#elif defined(__unix__)
    unixCode();
#endif /* platform branching */
Run Code Online (Sandbox Code Playgroud)

根据情况,这也可用于伪代码输出.例如,如果您想要一个仅在调试时存在的函数,您可能会遇到以下情况:

#ifdef DEBUG
    return_type function(parameter_list) {
        function_body;
    }
#endif  /* DEBUG */
Run Code Online (Sandbox Code Playgroud)

1A)头部防护装置.

在上面的基础上,如果标题已经包含在跨越多个源文件的项目中,则标题保护是一种dummying out整个标题的方法.

#ifndef HEADER_GUARD
#define HEADER_GUARD

// Header...

#endif  /* HEADER_GUARD */
Run Code Online (Sandbox Code Playgroud)

2)贬低一个符号.

当与分支结合使用时,您还可以使用带有空白定义的定义来伪造符号.考虑以下:

#ifdef _WIN32
    #define STDCALL __stdcall
    #define CDECL __cdecl
    // etc.
#elif defined(__unix__)
    #define STDCALL
    #define CDECL
#endif  /* platform-specific */

// ...

void CDECL cdeclFunc(int, int, char, const std::string&, bool);
// Compiles as void __cdecl cdeclFunc(/* args */) on Windows.
// Compiles as void cdeclFunc(/* args */) on *nix.
Run Code Online (Sandbox Code Playgroud)

通过这样的操作,您可以编写与平台无关的代码,但可以在Windows平台上指定调用约定.[注意,标题windef.h这样做,定义CDECL,PASCAL以及WINAPI在不支持它们的平台为空白符号]这也可以在其他情况下使用,当你需要一个预处理符号只扩大到在一定条件下别的东西.

3)文档.

空白宏也可用于记录代码,因为预处理器可以将它们删除.微软喜欢这种方法,将其windef.h用于Windows功能原型中经常出现的符号INOUT符号.

也有可能还有其他用途,但这些是我能想到的唯一的用途.