简体   繁体   English

预处理程序如何处理宏?

[英]How are macros handled by preprocessor?

I am reading Efficient c++ (older version) and have some doubts. 我正在阅读Efficient c ++(旧版本),并且有一些疑问。 Here, for example, it says: 例如,在这里说:

When you do something like this 当你做这样的事情

 #define ASPECT_RATIO 1.653 

the symbolic name ASPECT_RATIO may never be seen by the compilers; 编译器可能永远不会看到符号名ASPECT_RATIO; it may be removed by the preprocessors before the source code ever gets compiled. 在编译源代码之前,预处理器可能会删除它。 As a results the ASPECT_RATIO may never get entered to SYMBOLIC_TABLE. 结果,ASPECT_RATIO可能永远不会输入到SYMBOLIC_TABLE。 It an be confusing if you get an error during compilation involving the constant, because the error message may refer to 1.653 and not ASPECT_RATIO 如果您在编译过程中遇到涉及常量的错误,这将令人困惑,因为错误消息可能引用的是1.653,而不是ASPECT_RATIO

I don't understand this paragraph.How can anything be removed the preprocessor, just like that. 我不明白这一段,怎么能去除预处理器呢? what could be the reasons and how feasible are they in real world. 在现实世界中可能是什么原因以及可行性如何?

Thanks 谢谢

It's simply a global search and replace of "ASPECT_RATIO" with "1.653" in the file before passing it to the compiler 这只是全局搜索,然后在将文件传递给编译器之前将“ ASPECT_RATIO”替换为文件中的“ 1.653”

That's why macros are so dangerous. 这就是宏如此危险的原因。 If you have #define max 123 and a variable int max = 100 the compiler will get int 123 = 100 and you will get a confusing error message 如果您具有#define max 123和一个变量int max = 100则编译器将获得int 123 = 100并且您将收到一个令人困惑的错误消息

I don't understand this paragraph under inverted quotes.How can anything be removed the preprocessor, just like that. 我不理解该段落在反引号下的样子,如何才能删除预处理器? what could be the reasons and how feasible are they in real world. 在现实世界中可能是什么原因以及可行性如何?

Basically what it describes is exactly how C and C++ pre-processor works. 基本上,它所描述的正是C和C ++预处理器的工作方式。 The reason is to replace macros/constants (that are made using the #define directive) with their actual values, instead of repeating the same values over and over again. 原因是将宏/常量(使用#define指令创建)替换为其实际值,而不是一遍又一遍地重复相同的值。 In C++ it is considered a bad style using C-style macros, but they're supported for C compatibility. 在C ++中,使用C样式宏被认为是不好的样式,但是C兼容性支持它们。

The preprocessor, as the name suggests, runs prior to the actual compilation, and is basically changing the source code as directed through the pre-processor directives (those starting with # ). 顾名思义,预处理器在实际编译之前运行,并且基本上是按照预处理器指令(以#开头的指令)的指示更改源代码。 This also includes replacement of the macros with their values, the inclusion of the header files as directed by the #include directive, etc etc. 这还包括用其值替换宏,按照#include指令的指示包含头文件等。

This is used in order to avoid code repetitions, magic numbers, to share interfaces (header files) and many other useful things. 这是为了避免代码重复,幻数,共享接口(头文件)和许多其他有用的东西。

The pre-processor will replace all instances of the token ASPECT_RATIO that appear in the code with the actual token 1.653 ... thus the compiler will never see the token ASPECT_RATIO . 预处理器将用实际的令牌1.653替换代码中出现的令牌ASPECT_RATIO所有实例...因此编译器将永远不会看到令牌ASPECT_RATIO By the time it compiles the code, it only sees the literal token 1.653 that was substituted in by the pre-processor. 到编译代码时,它只能看到由预处理器替换的文字标记1.653

Basically the "problem" you will encounter with this approach is that ASPECT_RATIO will not be seen as a symbol by the compiler, thus in a debugger, etc., you can't query the value ASPECT_RATIO as-if it were a variable. 基本上,使用这种方法会遇到的“问题”是编译器不会将ASPECT_RATIO视为符号,因此在调试器等中,您无法查询值ASPECT_RATIO,因为它是变量。 It's not a value that will have a memory address like a static const int may have (I say "may", because an optimizing compiler may decide to act like the pre-processor, and optimize-out the need for an explicit memory address to store the constant value, instead simply substituting the literal value where-ever it appears in the code). 它不是一个具有像static const int可能具有的内存地址的值(我说“可能”,因为优化的编译器可能会决定像预处理程序一样工作,并优化对显式内存地址的需求以达到存储常量值,而不是简单地用文字值替换代码中出现的任何值)。 In a larger function macro it also won't have an instruction address like actual C/C++ function will have, thus you can't set break-points inside a function macro. 在更大的函数宏中,它也不会像实际的C / C ++函数那样具有指令地址,因此您不能在函数宏中设置断点。 But in a more general sense I'm not sure I would call this a "problem" unless you were intending to use the macro as a debug-symbol, and/or set debugging break-points inside your macro. 但是从更一般的意义上讲,除非您打算将宏用作调试符号和/或在宏中设置调试断点,否则我不确定是否将其称为“问题”。 Otherwise the macro is doing its job. 否则,宏将执行其工作。

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

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