C++ 不带替换C+的预处理器宏+;

C++ 不带替换C+的预处理器宏+;,c++,macros,C++,Macros,根据cplusplus.com,定义宏的语法为: #define identifier replacement 然而,我有时偶然发现一个宏定义,它不包含替换项。例如,在afxwin.h中,有以下预处理器定义: #define afx_msg // intentional placeholder 我的问题是: 当使用没有替换的预处理器定义时,在编译时会发生什么?它只是被忽略了吗?例如,行afx_msg void OnAddButton()变成无效OnAddButton() 使用

根据cplusplus.com,定义宏的语法为:

#define identifier replacement
然而,我有时偶然发现一个宏定义,它不包含替换项。例如,在afxwin.h中,有以下预处理器定义:

#define afx_msg         // intentional placeholder
我的问题是:

  • 当使用没有替换的预处理器定义时,在编译时会发生什么?它只是被忽略了吗?例如,行
    afx_msg void OnAddButton()变成
    无效OnAddButton()
  • 使用预处理器而不进行替换的目的是什么?这仅仅是为了让代码更清晰吗
  • 预处理器对其进行处理,将其删除并替换为空
  • 可能有多种原因,包括可读性、可移植性、自定义编译器功能等
  • 仅定义
    bla

    你可以和我一起使用

    #ifdef bla
    ...
    place some code here
    ...
    #endif
    
    典型的用例是
    #define DEBUG
    ,以在调试模式下启用特殊的代码部分

    从“外部”设置这些内容的另一种方法是:

    它还设置定义的宏调试

    每个头文件都应该有如下内容:

    #ifndef THIS_HEADER_INCLUDE_GUARD
    #define THIS_HEADER_INCLUDE_GUARD
    ...
    rest of header file
    ...
    #endif
    
    这只是为了(递归地)多次读取而保护头文件

    可以使用特定于实现的
    #pragma一次性执行一些操作

    “Nothing”(无文本)是宏的有效替换文本。它将被预处理器简单地删除(更准确地说,被零替换)

    有很多原因可以解释为什么你会使用这样的东西。一种是简单地使用
    #ifdef
    中的宏和类似的构造函数

    另一种是条件编译。一个典型的用例是公共API和DLL导出。在Windows上,需要将函数标记为从DLL导出(生成DLL时)或从DLL导入(针对DLL链接时)。在ELF系统上,不需要这样的声明。因此,在公共库标题中经常会看到这样的代码:

    #ifdef _WIN32
      #ifdef BUILDING_MYLIB
         #define MYLIB_API __declspec(dllexport)
      #else
         #define MYLIB_API __declspec(dllimport)
      #endif
    #else
      #define MYLIB_API
    #endif
    
    void MYLIB_API myApiFunction();
    

    另一个原因可能是代码处理工具。也许您有一个工具,可以解析源代码,提取带有特定标记的函数列表。您可以将这样的标记定义为空宏。

    当您尝试它时,您发现了什么?您可以将
    #define
    看作是编译之前应用的一个简单的搜索和替换函数。只需尝试搜索afx_msg,然后将其替换为空。
    #ifndef THIS_HEADER_INCLUDE_GUARD
    #define THIS_HEADER_INCLUDE_GUARD
    ...
    rest of header file
    ...
    #endif
    
    #ifdef _WIN32
      #ifdef BUILDING_MYLIB
         #define MYLIB_API __declspec(dllexport)
      #else
         #define MYLIB_API __declspec(dllimport)
      #endif
    #else
      #define MYLIB_API
    #endif
    
    void MYLIB_API myApiFunction();