代码之家  ›  专栏  ›  技术社区  ›  Hassan Syed

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

  •  2
  • Hassan Syed  · 技术社区  · 16 年前

    接下来是 this 问题。这与函数中静态变量的初始化语义有关。静态变量应该初始化一次,并且它们的内部状态可能会在以后更改-( 目前 )在相关的问题上做。但是,所讨论的代码不需要特性来更改变量的状态。

    让我仔细检查一下我的位置,因为我不需要更改string对象的内部状态。代码是针对元编程的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;
    }
    

    下面在GCC上编译并打印两次“yahoo”。这正是我想要的——但是它可能不符合标准(这就是我提出这个问题的原因)。有两个函数“SetString”和“String”可能更优雅,后者将转发到第一个函数。 如果它符合标准,有人知道boost(或其他地方)中的模板实现吗?

    编辑:2010年5月11日

    #define MACRO_STATIC_SETTING_PTR(name, type)                          \
      static const type const set_##name (const type const name##_in) {   \
        static const type const name = name##_in;                         \
        return name;                                                      \
      }                                                                   \
      static const type const name() {                                    \
        return set_##name(NULL);                                          \
      } 
    
    #define MACRO_STATIC_SETTING(name, type)                              \
      static const type set_##name (const type name##_in) {               \
        static const type name = name##_in;                               \
        return name;                                                      \
      }                                                                   \
      static const type name() {                                          \
        return set_##name(NULL);                                          \
      } 
    

    这些宏放在类声明中。例如:

    template<class tag>
    class ConfigInstance{
    public:
      MACRO_STATIC_SETTING_PTR(sqllite3_filename, char *)
    };
    

    希望这对其他人有用。

    1 回复  |  直到 9 年前
        1
  •  4
  •   ablaeul    16 年前

    让我们来看看C++标准的第6.7部分4(声明语句)。

    允许一个实现执行其他 允许实现静态初始化对象 否则,这样的对象在控件第一次通过时初始化

    所以我们有两个案子:

    1. 或者在我们使用静态局部变量进入函数之前 x 会有的。然后允许编译器尽早(甚至在编译时)初始化该值。
    2. 我们现在没有价值 只在我们第一次进入函数时初始化它。

    所以是的,gcc所做的不仅是你想要的,这种行为也符合标准。