constexpr函数是隐式静态的吗?

时间:2019-05-16 15:39:13

标签: c++ c++11 constexpr static-functions

如果我在program.cpp中定义了一个函数:

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

与声明为静态有什么不同吗?

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

这似乎应该等效,因为constexpr表示该函数是内联的,因此不能在编译单元之间共享。

constexpr全局函数隐式静态吗?

2 个答案:

答案 0 :(得分:9)

vendor_id函数隐式为constexpr

inline是链接功能。在不同编译单元中具有定义的inline函数不是错误;如果它们的定义不同,则程序的格式不正确,无需诊断,但是如果它们的定义相同,则将丢弃一个版本,而使用该版本。

非方法功能上的

inline也是链接功能。 static定义不会在其编译单元外部共享;编译单元不会“宣告”它具有static的定义。

方法函数上的

isThree与链接无关。在这种情况下,这仅意味着static没有隐式传递给函数。带有/不带有this的方法不起作用有差异,但是它们与this无关。请注意,至少在中,不使用constexpr的{​​{1}}方法仍可以进行常量评估。某些版本的隐式地使用constexpr的方法this不会。

constexpr时(除非使用激进的ICF,这是一个不同的问题),一个编译单元中的

const和另一个编译器中的&isThree可以(通常这样做)变化。当&isThree时,它们可能没有变化。

static函数 在编译单元之间共享。它们的完整定义也经常在意识到这一点的所有编译单元中可见,因此,它使编译器“内联”(而不是关键字)更容易实现代码。 inline不是。 inline函数是隐式的static,但不是隐式的constexpr

请注意,有时可以在运行时上下文中评估inline函数。在编译时上下文中进行评估时,它们的staticconstexpr或链接状态实际上无关紧要。

inline也具有其他含义,但是您想知道两个不同的static声明之间的区别,而这些含义都没有改变。

答案 1 :(得分:3)

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函数可能不包含静态变量)。