Констекспр подразумевает 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.

Другие вопросы по тегам