Констекспр подразумевает inline?
Рассмотрим следующую встроенную функцию:
// 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
функция, компилятор будет пытаться inline
функция как будто inline
спецификатор был введен в его декларацию?
Гарантирует ли это стандарт C++11?
1 ответ
Да ([dcl.constexpr], §7.1.5/2 в стандарте C++11): "Функции constexpr и конструкторы constexpr неявно встроены (7.1.2)".
Обратите внимание, однако, что inline
На самом деле спецификатор практически не влияет (если таковой имеется) на вероятность того, что компилятор развернет встроенную функцию или нет. Это, однако, влияет на одно правило определения, и с этой точки зрения компилятор должен следовать тем же правилам для constexpr
функционировать как inline
функция.
Я должен также добавить, что независимо от constexpr
подразумевающий inline
, правила для constexpr
функции требуют, чтобы они были достаточно простыми, чтобы они часто были хорошими кандидатами для встроенного расширения (первичное исключение - те, которые являются рекурсивными).
constexpr
не подразумевает inline
для переменных (встроенные переменные C++17)
Пока constexpr
подразумевает inline
для функций он не имеет такого эффекта для переменных, учитывая встроенные переменные C++17.
Например, если вы возьмете минимальный пример, который я разместил на: Как работают встроенные переменные? и удалите inline
оставив всего constexpr
, тогда переменная получает несколько адресов, что является главным, чего избегают встроенные переменные.
Минимальный пример того, что constexpr
подразумевает inline
для функций
Как уже упоминалось по адресу: /questions/27899579/konstekspr-podrazumevaet-inline/27899599#27899599 основной эффект inline
не для встроенного, а для разрешения нескольких определений функции, стандартная цитата: Как заголовочный файл C++ может включать реализацию?
Мы можем наблюдать это, играя на следующем примере:
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();
}
Скомпилируйте и запустите:
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
также подразумевает inline
,
GCC реализует это, помечая символы как слабые в объектных файлах ELF: Как заголовочный файл C++ может включать реализацию?
Протестировано в GCC 8.3.0.