C++ 函数局部静态常量变量初始化语义

C++ 函数局部静态常量变量初始化语义,c++,metaprogramming,micro-optimization,generic-programming,C++,Metaprogramming,Micro Optimization,Generic Programming,这些问题是粗体的,对于那些不愿意深入阅读问题的人来说 这是问题的后续部分。这与函数中静态变量的初始化语义有关。静态变量应该初始化一次,并且它们的内部状态可能会在以后更改—就像我(当前)在链接问题中所做的那样。但是,所讨论的代码不需要该特性在以后更改变量的状态 让我明确我的位置,因为我不需要改变字符串对象的内部状态。代码用于元编程的trait类,因此将受益于const char*const ptr——因此理想情况下需要一个局部成本静态const变量。我有根据地猜测,在这种情况下,链接加载器会将所讨

这些问题是粗体的,对于那些不愿意深入阅读问题的人来说

这是问题的后续部分。这与函数中静态变量的初始化语义有关。静态变量应该初始化一次,并且它们的内部状态可能会在以后更改—就像我(当前)在链接问题中所做的那样。但是,所讨论的代码不需要该特性在以后更改变量的状态

让我明确我的位置,因为我不需要改变字符串对象的内部状态。代码用于元编程的trait类,因此将受益于const char*const ptr——因此理想情况下需要一个局部成本静态const变量。我有根据地猜测,在这种情况下,链接加载器会将所讨论的字符串最佳地放置在内存中,并且代码更安全,并映射到预期的语义

<>这导致这样一个变量的语义“C++编程语言第三版——StruouStrup”没有任何东西(我可以找到)来谈论这件事。所要说的是,当线程的控制流第一次到达代码时,变量被初始化一次这让我思考以下代码是否合理,如果不合理,预期的语义是什么?

#include <iostream>
const char * const GetString(const char * x_in)
{
    static const char * const x = x_in;
    return x;
}

int main()
{
  const char * const temp = GetString("yahoo");
  std::cout << temp << std::endl;
  const char * const temp2 = GetString("yahoo2");
  std::cout << temp2 << std::endl;
}
这些宏放在类声明中。例如:

template<class tag>
class ConfigInstance{
public:
  MACRO_STATIC_SETTING_PTR(sqllite3_filename, char *)
};
模板
类配置实例{
公众:
宏\u静态\u设置\u PTR(sqllite3\u文件名,char*)
};

希望这对其他人有用 允许一个实现执行其他应用程序的早期初始化 在相同条件下具有静态存储持续时间的本地对象 允许实现静态初始化对象 命名空间范围中的静态存储持续时间。 否则,当控件第一次通过时,将初始化此类对象 通过其宣言;这样的对象被认为是初始化的 完成其初始化

因此,我们有两种情况:

  • 现在,在使用静态本地
    x
    输入函数之前,我们需要知道
    x
    将具有什么值。然后允许编译器尽早(甚至在编译时)初始化该值
  • 我们现在不需要在第一次输入函数时初始化
    x
    的值

  • 因此,是的,gcc所做的不仅是您想要的,这种行为也是符合标准的。

    const char*const GetString
    中,第二个常量没有意义,因为限定符仅适用于l值。第一个常量表示指针指向只读内存,而第二个常量使指针本身保持常量(const作用于它旁边左边的元素,除非它是第一个标记,然后作用于右边的元素).
    char*GetString
    将生成指向常量内存的变量指针,而
    char*const GetString
    将生成指向可写内存的常量指针。在您的示例中,可能是输入错误,但输出两次temp将始终得到相同的结果。@Rudi:您描述的是针对L值的,而不是针对函数返回类型的。一个好的编译器将就此向您发出警告。@JRL Arrgh!我在脑海中混淆了x和GetString。值得注意的是,当编译器选择选项2(第一次进入函数时初始化
    x
    )时,函数不是线程安全的。
    template<class tag>
    class ConfigInstance{
    public:
      MACRO_STATIC_SETTING_PTR(sqllite3_filename, char *)
    };