Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 宏是否保证不超过头部?_C++_C - Fatal编程技术网

C++ 宏是否保证不超过头部?

C++ 宏是否保证不超过头部?,c++,c,C++,C,作为一名程序员,我被教导更喜欢关键字inline,而不是小函数的宏定义。我知道内联更安全,因为宏定义不进行类型检查,但是我被告知内联只是编译器实际替换代码的请求,而编译器不必接受该请求,所以我想知道宏请求也是这样还是保证没有超限时间 宏是编译时的东西。在编译后的代码中,它们从不以宏的形式出现。如果你定义如下 #define MyVar 5 您在代码中执行以下操作: double y = MyVar*MyVar; 这一模一样: double y = 5*5; 编译时,MyVar宏将替换为您定

作为一名程序员,我被教导更喜欢关键字inline,而不是小函数的宏定义。我知道内联更安全,因为宏定义不进行类型检查,但是我被告知内联只是编译器实际替换代码的请求,而编译器不必接受该请求,所以我想知道宏请求也是这样还是保证没有超限时间

宏是编译时的东西。在编译后的代码中,它们从不以宏的形式出现。如果你定义如下

#define MyVar 5
您在代码中执行以下操作:

double y = MyVar*MyVar;
这一模一样:

double y = 5*5;

编译时,
MyVar
宏将替换为您定义的值。运行时绝对没有开销。

宏是编译时的东西。在编译后的代码中,它们从不以宏的形式出现。如果你定义如下

#define MyVar 5
您在代码中执行以下操作:

double y = MyVar*MyVar;
这一模一样:

double y = 5*5;

编译时,
MyVar
宏将替换为您定义的值。运行时绝对没有开销。

宏是在编译步骤之前执行的文本替换-它们不能像函数调用那样具有“运行时开销”。尽管如此,这并不是使用宏而不是函数的好理由,因为编译器将自动内联函数,即使没有启用优化的
inline
关键字。此外,使用链接时间优化
-flto
将允许在TU之间进行内联。

宏是在编译步骤之前执行的文本替换-它们不能像函数调用那样具有“运行时开销”。尽管如此,这并不是使用宏而不是函数的好理由,因为编译器将自动内联函数,即使没有启用优化的
inline
关键字。此外,使用链接时间优化
-flto
将允许TU之间的内联。

宏是预处理器功能

预处理器以纯文本的方式修改程序,如果单独运行预处理器,您实际上可以看到它的结果

使用gcc,您可以使用
gcc-E
cpp
来实现这一点。 我在调试宏时经常这样做

示例main.c:

#include <stdio.h>

#define MC_repeat(X)  \
    for(int _i=0;_i<(X);_i++)

#define rt return

#define MC_xputs(X) if(0>puts(X)) rt -1;


int main()
{
    MC_repeat(5) 
        MC_xputs("hello world");
    rt 0;
}
当您编译这样的源代码时,就好像您先运行预处理器,然后通过管道将结果传递给编译器一样有效

gcc实际上不是这样做的(因此您可以得到更好的错误消息),但您可以强制它:

#actually pipes preprocessor output to the compiler proper
gcc -E main.c | gcc -x cpp-output

宏是一种预处理器功能

预处理器以纯文本的方式修改程序,如果单独运行预处理器,您实际上可以看到它的结果

使用gcc,您可以使用
gcc-E
cpp
来实现这一点。 我在调试宏时经常这样做

示例main.c:

#include <stdio.h>

#define MC_repeat(X)  \
    for(int _i=0;_i<(X);_i++)

#define rt return

#define MC_xputs(X) if(0>puts(X)) rt -1;


int main()
{
    MC_repeat(5) 
        MC_xputs("hello world");
    rt 0;
}
当您编译这样的源代码时,就好像您先运行预处理器,然后通过管道将结果传递给编译器一样有效

gcc实际上不是这样做的(因此您可以得到更好的错误消息),但您可以强制它:

#actually pipes preprocessor output to the compiler proper
gcc -E main.c | gcc -x cpp-output


根据C++规范,编译器需要生成与所有宏都一样的代码,宏在预处理器编译期间保证在内联中展开。然而,这并不意味着“没有开销”。较大的代码可能是较慢的代码。这就是为什么编译器决定忽略您的内联请求。你不必为此担心。让编译器处理它。这是C还是C++?你从一、二十年前就知道了。编译器不关心代码>内联< /代码>。编译器会忽略您的请求,并执行自己的内联优化计算。另一方面,链接器将始终尊重。编译器需要生成与所有的宏一样的代码,就像C++规范中首先扩展的一样。宏保证在预处理器编译期间内联。然而,这并不意味着“没有开销”。较大的代码可能是较慢的代码。这就是为什么编译器决定忽略您的内联请求。你不必为此担心。让编译器处理它。这是C还是C++?你从一、二十年前就知道了。编译器不关心代码>内联< /代码>。编译器会忽略您的请求,并执行自己的内联优化计算。另一方面,链接器将始终尊重.s/compile-time/preprocessor。@巴里:预处理器是编译器的一部分。@KeithThompson是同一二进制文件的一部分,但预处理步骤发生在实际编译步骤之前。@Barry:它可能是也可能不是同一二进制文件的一部分,具体取决于实现(例如,gcc使用单独的预处理器)。但语言没有这样的区别。5.1.1.2定义了8个翻译阶段;预处理器对应于前5个左右的.s/compile time/preprocessor。@巴里:预处理器是编译器的一部分。@KeithThompson是同一个二进制文件的一部分,但预处理步骤发生在实际编译步骤之前。@Barry:可能是,也可能是可能不是同一个二进制文件的一部分,具体取决于实现(例如,gcc使用一个单独的预处理器)。但语言没有这样的区别。5.1.1.2定义了8个翻译阶段;预处理器对应于前5个左右。“纯文本”不准确。预处理器确实执行一些解析。如果您将
MC\u repeat(5)
(MC\u repeat)(5)
交换,预处理器将不再替换
MC\u repeat
符号。“纯文本”不准确。预处理器确实执行一些解析。如果您将
MC\u repeat(5)
(MC\u repeat)交换(5) 
,预处理器将不再替换
MC\u repeat
符号。