Does constexpr imply inline?

丶灬走出姿态 提交于 2019-12-17 06:04:21

问题


Consider the following inlined function :

// 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]));
}

and the constexpr equivalent version :

// 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]));
}

My question is : does the constexpr specifier imply the inline specifier in the sense that if a non-constant argument is passed to a constexpr function, the compiler will try to inline the function as if the inline specifier was put in its declaration ?

Does the C++11 standard guarantee that ?


回答1:


Yes ([dcl.constexpr], §7.1.5/2 in the C++11 standard): "constexpr functions and constexpr constructors are implicitly inline (7.1.2)."

Note, however, that the inline specifier really has very little (if any) effect upon whether a compiler is likely to expand a function inline or not. It does, however, affect the one definition rule, and from that perspective, the compiler is required to follow the same rules for a constexpr function as an inline function.

I should also add that regardless of constexpr implying inline, the rules for constexpr functions in C++11 required them to be simple enough that they were often good candidates for inline expansion (the primary exception being those that are recursive). Since then, however, the rules have gotten progressively looser, so constexpr can be applied to substantially larger, more complex functions.




回答2:


constexpr does not imply inline for non-static variables (C++17 inline variables)

While constexpr does imply inline for functions, it does not have that effect for non-static variables, considering C++17 inline variables.

For example, if you take the minimal example I posted at: How do inline variables work? and remove the inline, leaving just constexpr, then the variable gets multiple addresses, which is the main thing inline variables avoid.

constexpr static variables are however implicitly static.

Minimal example that constexpr implies inline for functions

As mentioned at: https://stackoverflow.com/a/14391320/895245 the main effect of inline is not to inline but to allow multiple definitions of a function, standard quote at: How can a C++ header file include implementation?

We can observe that by playing with the following example:

main.cpp

#include <cassert>

#include "notmain.hpp"

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

notmain.hpp

#ifndef NOTMAIN_HPP
#define NOTMAIN_HPP

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

#endif

notmain.cpp

#include "notmain.hpp"

int notmain_func() {
    return shared_func();
}

Compile and run:

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

If we remove inline from shared_func, link would fail with:

multiple definition of `shared_func()'

because the header gets included into multiple .cpp files.

But if we replace inline with constexpr, then it works again, because constexpr also implies inline.

GCC implements that by marking the symbols as weak on the ELF object files: How can a C++ header file include implementation?

Tested in GCC 8.3.0.



来源:https://stackoverflow.com/questions/14391272/does-constexpr-imply-inline

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!