简体   繁体   English

预处理器宏没有替换C ++

[英]Preprocessor macro without replacement C++

According to cplusplus.com, the syntax to define a macro is: 根据cplusplus.com,定义宏的语法是:

#define identifier replacement

However, I sometimes stumble upon a macro definition which doesn't contain a replacement. 但是,我有时会偶然发现一个不包含替换的宏定义。 For example in afxwin.h, there is the following preprocessor definition: 例如,在afxwin.h中,有以下预处理器定义:

#define afx_msg         // intentional placeholder

My questions: 我的问题:

  1. What happens at compile-time when a preprocessor definition that doesn't have a replacement is used? 当使用没有替换的预处理器定义时,在编译时会发生什么? Is it simply ignored? 它被忽略了吗? For example, does the line afx_msg void OnAddButton(); 例如,行afx_msg void OnAddButton();是否为afx_msg void OnAddButton(); become void OnAddButton(); 变为void OnAddButton(); ?
  2. What is the purpose of using preprocessor without replacement? 在没有替换的情况下使用预处理器的目的是什么? Is it simply to make code more clear? 是否只是为了使代码更清晰?

"Nothing" (no text) is a valid replacement text for a macro. “Nothing”(无文本)是宏的有效替换文本。 It will simply be removed (more precisely, replaced by nothing) by the preprocessor. 它将被预处理器简单地删除(更确切地说,由任何东西替换)。

There are multiple reasons why you'd use something like this. 你使用这样的东西有很多原因。 One is to simply use the macro in #ifdef and similar constructrs. 一种是简单地在#ifdef和类似的构造函数中使用宏。

Another is conditional compilation. 另一种是条件编译。 A typical use case is public APIs and DLL exports. 典型的用例是公共API和DLL导出。 On Windows, you need to mark a function as exported from a DLL (when building the DLL) or as imported from a DLL (when linking against the DLL). 在Windows上,您需要将函数标记为从DLL(构建DLL时)或从DLL导入时(在链接DLL时)导出的函数。 On ELF systems, no such declarations are necessary. 在ELF系统上,不需要这样的声明。 Therefore, you'll often see code like this in public library headers: 因此,您经常会在公共库头文件中看到这样的代码:

#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();

Yet another reason could be code processing tools. 另一个原因可能是代码处理工具。 Perhaps you have a tool which parses source code, extracting a list of functions with a certain marker. 也许你有一个解析源代码的工具,用一个标记提取一个函数列表。 You can define such a marker as an empty macro. 您可以将此标记定义为空宏。

#define bla

simply defines bla . 简单地定义bla

you can use it with 你可以用它

#ifdef bla
...
place some code here
...
#endif

a typical use case is #define DEBUG to enable special code parts in debugging mode. 一个典型的用例是#define DEBUG用于在调试模式下启用特殊代码部分。

Another way to set such things from "outside" is: 从“外部”设置此类事物的另一种方法是:

 g++ -DDEBUG x.cpp

which also sets the macro DEBUG defined. 这也设置了定义的宏DEBUG。

And every header file should have something like: 每个头文件应该有类似的东西:

#ifndef THIS_HEADER_INCLUDE_GUARD
#define THIS_HEADER_INCLUDE_GUARD
...
rest of header file
...
#endif

This simply protects your header file for (recursivly) read more the once. 这只是保护你的头文件(recursivly)读取更多一次。

Some can be done with implementation specific #pragma once . 有些可以通过特定于实现的#pragma once

  1. the preprocessor processes it, removing it and replacing it with nothing 预处理器处理它,删除它并替换它什么都没有
  2. could be a variety of reasons, including readability, portability, custom compiler features, etc. 可能有多种原因,包括可读性,可移植性,自定义编译器功能等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM