Являются ли функции constexpr неявно статичными? - PullRequest
6 голосов
/ 16 мая 2019

Если я определю функцию в моем program.cpp:

constexpr bool isThree(const int number)
{
  return number == 3;
}

это чем-то отличается от объявления его статическим?

static constexpr bool isThree(const int number)
{
  return number == 3;
}

Кажется, что они должны быть эквивалентны, поскольку constexpr означает, что функция встроена и поэтому не используется совместно для блоков компиляции.

Являются ли constexpr глобальные функции неявно статичными?

Ответы [ 2 ]

9 голосов
/ 16 мая 2019

constexpr функции неявно inline.

inline - это функция связывания.Функция inline с определениями в разных единицах компиляции не является ошибкой;если их определения различаются, ваша программа неправильно сформирована, диагностика не требуется, но если они имеют одно и то же определение, то все версии, кроме одной, отбрасываются, и эта версия используется.

static для не-методафункция, также является функцией связывания.Определение static не передается за пределы его модуля компиляции;модуль компиляции не «объявляет», что у него есть определение для isThree.

static для функции метода, не имеющей ничего общего со связыванием.В этом случае это просто означает, что this неявно передается функции.Метод с / без this, который он не работает, имеет отличия, но в основном они не связаны с тем, что constexpr.Обратите внимание, что, по крайней мере, метод constexpr, который не использует this, все еще может быть оценен на постоянной основе.Некоторые версии делают constexpr методы неявно const; не имеет значения.

&isThree в одном модуле компиляции и &isThree в другом могут (и обычно изменяются), когда static (за исключением агрессивного ICF, что являетсявопрос для другого вопроса).Когда inline, они могут не изменяться.

inline функции совместно используются единицами компиляции.Их полное определение также часто видимо во всех осведомленных об этом единицах компиляции, поэтому оно упрощает компиляцию (в отличие от ключевого слова) вашего кода.static нет.constexpr функции неявно inline, но неявно static.

Обратите внимание, что constexpr функции могут иногда оцениваться в контексте времени выполнения.При оценке в контексте времени компиляции их inline против static или состояние связи действительно не имеют значения.

constexpr означает и другие вещи, но вы хотели знать разницу между двумя разнымиconstexpr декларации, и ни одно из этих значений не меняется.

3 голосов
/ 16 мая 2019

constexpr функции не являются неявно статическими.Они имеют ту же связь, что и не constexpr функции:

// external linkage
constexpr int f1(int x) { /* ... */ }

// internal linkage
static constexpr int f2(int x) { /* ... */ }

// internal linkage
namespace {
constexpr int f3(int x) { /* ... */ }
}

// no linkage
void enclosing() {
    struct S {
        constexpr int f4(int x) { /* ... */ }        
    };
}

Когда функция constexpr имеет внешнюю связь, она имеет один и тот же адрес во всех единицах перевода.Когда он имеет внутреннюю связь, в каждой единице перевода есть разные копии, и эти копии имеют разные адреса.Однако я считаю, что результат вызова функции constexpr не должен зависеть от того, имеет ли она внутреннюю или внешнюю связь (поскольку функции constexpr могут не содержать статических переменных).

...