constexpr是否意味着内联?

时间:2013-01-18 01:48:16

标签: c++ c++11 inline standards-compliance constexpr

考虑以下内联函数:

// Inline specifier version
#include<iostream>
#include<cstdlib>

inline int f(const int x);

inline int f(const int x)
{
    return 2*x;
}

int main(int argc, char* argv[])
{
    return f(std::atoi(argv[1]));
}

和constexpr等效版本:

// Constexpr specifier version
#include<iostream>
#include<cstdlib>

constexpr int f(const int x);

constexpr int f(const int x)
{
    return 2*x;
}

int main(int argc, char* argv[])
{
    return f(std::atoi(argv[1]));
}

我的问题是:constexpr说明符是否意味着inline说明符,如果将非常量参数传递给constexpr函数,编译器将尝试{ {1}}函数就像inline说明符放在声明中一样?

C ++ 11标准是否保证?

2 个答案:

答案 0 :(得分:113)

是([dcl.constexpr],C ++ 11标准中的§7.1.5/ 2):“constexpr函数和constexpr构造函数是隐式内联的(7.1.2)。”

但请注意,inline说明符对编译器是否可能内联扩展函数的影响确实非常很少(如果有)。但是,它会影响一个定义规则,从这个角度来看,编译器必须遵循constexpr函数的相同规则作为inline函数。

我还应该补充一点,无论constexpr隐含inline,C ++ 11中constexpr函数的规则要求它们足够简单,以至于它们通常是内联的良好候选者扩展(主要的例外是递归的)。然而,从那时起,规则逐渐变得松散,因此constexpr可以应用于更大,更复杂的功能。

答案 1 :(得分:8)

interval: null并不暗示constexpr用于非静态变量(C ++ 17内联变量)

考虑到C ++ 17内联变量,尽管inline对于功能确实暗示constexpr,但对非静态变量没有影响。

例如,如果您以我在How do inline variables work?上发布的最小示例为例,并删除inline,仅保留inline,则该变量将获得多个地址,这是主要的内联变量避免。

constexpr静态变量是隐式静态的。

constexpr暗示功能的constexpr的最小示例

https://stackoverflow.com/a/14391320/895245所述,inline的主要作用不是内联而是允许对函数进行多个定义,标准引号位于How can a C++ header file include implementation?

我们可以通过以下示例进行观察:

main.cpp

inline

notmain.hpp

#include <cassert>

#include "notmain.hpp"

int main() {
    assert(shared_func() == notmain_func());
}

notmain.cpp

#ifndef NOTMAIN_HPP
#define NOTMAIN_HPP

inline int shared_func() { return 42; }
int notmain_func();

#endif

编译并运行:

#include "notmain.hpp"

int notmain_func() {
    return shared_func();
}

如果我们从g++ -c -ggdb3 -O0 -Wall -Wextra -std=c++11 -pedantic-errors -o 'notmain.o' 'notmain.cpp' g++ -c -ggdb3 -O0 -Wall -Wextra -std=c++11 -pedantic-errors -o 'main.o' 'main.cpp' g++ -ggdb3 -O0 -Wall -Wextra -std=c++11 -pedantic-errors -o 'main.out' notmain.o main.o ./main.out 中删除inline,则链接将失败,并显示以下信息:

shared_func

因为标头包含在多个multiple definition of `shared_func()' 文件中。

但是如果我们将.cpp替换为inline,它将再次起作用,因为constexpr也意味着constexpr

GCC通过在ELF目标文件上将符号标记为弱符号来实现:How can a C++ header file include implementation?

在GCC 8.3.0中进行了测试。

相关问题