C++ 头文件中的constexpr const char*

C++ 头文件中的constexpr const char*,c++,c++11,C++,C++11,是否有理由不在头文件中使用“constexpr const char* 一位同事的观点是,包括此头文件在内的每个翻译单元都会有一份副本 我的理解是,由于它的编译时常数,没有分配内存,就内存使用而言,它更像一个“#define”宏。 这是消息来源 TestConstExpr.h #include <string.h> namespace TestConstExpr { constexpr const char* TIME_FORMAT = "yyyy-MM-dd h

是否有理由不在头文件中使用“constexpr const char*

一位同事的观点是,包括此头文件在内的每个翻译单元都会有一份副本

我的理解是,由于它的编译时常数,没有分配内存,就内存使用而言,它更像一个“#define”宏。 这是消息来源

TestConstExpr.h

  #include <string.h>
  namespace TestConstExpr
  {
    constexpr const char* TIME_FORMAT = "yyyy-MM-dd hh:mm:ss";
    constexpr const int TIME_FORMAT_SIZE = strlen(TIME_FORMAT) + 1;

    class TestClass
    {
        char arr[TIME_FORMAT_SIZE];
    }
  }
#包括
命名空间TestConstExpr
{
constexpr const char*TIME_FORMAT=“yyyy-MM-dd hh:MM:ss”;
constexpr const int TIME_FORMAT_SIZE=strlen(TIME_FORMAT)+1;
类TestClass
{
char arr[时间\格式\大小];
}
}
一位同事的观点是,包括此头文件在内的每个翻译单元都会有一份副本

你的同事在技术上是正确的。但这并不重要,因为当单元链接在一起时,多余的副本会被丢弃

尽管如此,当涉及到动态链接时,我已经看到一些关于这一点的评论,但在一些不符合标准的系统上不一定如此


这并不像你想象的那样。它提供指针的大小,而不是指针字符串的大小

您尝试的修复也不起作用,因为strlen不是一个常量表达式

您可以通过使用对字符串文字的引用来修复这些问题:

static constexpr auto& TIME_FORMAT = "yyyy-MM-dd hh:mm:ss";
constexpr const int TIME_FORMAT_SIZE = sizeof(TIME_FORMAT);

字符常量*
?当然不是,对常量数组或getter函数的引用——还有很多。你的理解也不正确。内存的分配方式与源文件中的分配方式完全相同。我建议您使用bloaty mcbloatface进行尝试-将这些头编译成多个TU,然后将它们与-O2链接在一起,查看字符串是否重复!如果该头包含在多个cpp文件中,则使用字符串文字将引发多个定义错误。'TestConstExpr::TIME_FORMAT'@NaveenGara的多个定义似乎出于某种原因,该变量在默认情况下具有外部链接,尽管它是constexpr。您可以使用
static
关键字显式使用内部链接。
constexpr const int TIME_FORMAT_SIZE = strlen(TIME_FORMAT) + 1;
static constexpr auto& TIME_FORMAT = "yyyy-MM-dd hh:mm:ss";
constexpr const int TIME_FORMAT_SIZE = sizeof(TIME_FORMAT);