简体   繁体   English

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

[英]Function-Local Static Const variable Initialization semantics

The questions are in bold, for those that cannot be bothered reading a question in depth. 这些问题以粗体显示,因为那些无法深入阅读问题的人。

This is a followup to this question. 这是问题的后续措施。 It is to do with the initialization semantics of static variables in functions. 这与函数中静态变量的初始化语义有关。 Static variables should be initialized once, and their internal state might be altered later - as I ( currently ) do in the linked question. 静态变量应该被初始化一次,它们的内部状态可能会在以后改变-就像我( 当前 )在链接的问题中所做的那样。 However, the code in question does not require the feature to change the state of the variable later. 但是,所讨论的代码不需要该功能稍后更改变量的状态。

Let me clarrify my position, since I don't require the string object's internal state to change. 让我澄清一下立场,因为我不需要更改字符串对象的内部状态。 The code is for a trait class for meta programming, and as such would would benifit from a const char * const ptr -- thus Ideally a local cost static const variable is needed. 该代码用于元编程的特征类,因此可以从const char * const ptr中受益-因此,理想情况下,需要使用本地成本静态const变量。 My educated guess is that in this case the string in question will be optimally placed in memory by the link-loader, and that the code is more secure and maps to the intended semantics. 我的有根据的猜测是,在这种情况下,所讨论的字符串将由链接加载程序最佳地放置在内存中,并且代码更安全并且可以映射到预期的语义。

This leads to the semantics of such a variable "The C++ Programming language Third Edition -- Stroustrup" does not have anything (that I could find) to say about this matter. 这导致了这样一个变量的语义:“ C ++编程语言第三版-Stroustrup”对此没有任何要说的东西(我可以找到)。 All that is said is that the variable is initialized once when the flow of control of the thread first reaches the code. 就是说,当线程的控制流首先到达代码时,变量将被初始化一次。 This leads me to ponder if the following code would be sensible, and if not what are the intended semantics ?. 这使我思考以下代码是否合理,如果不是,那么预期的语义是什么?

#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;
}

The following compiles on GCC and prints "yahoo" twice. 以下代码在GCC上编译,并两次打印“ yahoo”。 Which is what I want -- However it might not be standards compliant (which is why I post this question). 这就是我想要的-但是可能不符合标准(这就是我发布此问题的原因)。 It might be more elegant to have two functions, "SetString" and "String" where the latter forwards to the first. 拥有两个函数“ SetString”和“ String”可能会更优雅,后者会转发到第一个函数。 If it is standards compliant does someone know of a templates implementation in boost (or elsewhere) ? 如果符合标准,那么有人知道boost(或其他地方)中的模板实现吗?

edit: 11-may-2010 编辑:2010年5月11日

I am using the following macro to generate the above mentioned getter/setters in my classes that encode compile time information. 我正在使用以下宏在我的类中生成上述的getter / setter,它们对编译时间信息进行编码。

#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);                                          \
  } 

These macros are placed inside a class declaration. 这些宏放置在类声明中。 For example: 例如:

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

Hopefully this will be useful to others. 希望这对其他人有用。

Let's look into part 6.7 §4 (Declaration statement) of the C++ standard. 让我们看一下C ++标准的6.7§4部分(声明语句)。

An implementation is permitted to perform early initialization of other local objects with static storage duration under the same conditions that an implementation is permitted to statically initialize an object with static storage duration in namespace scope. 在相同的条件下,允许实现以静态存储持续时间对其他本地对象执行早期初始化,而在相同条件下,允许实现在名称空间范围内以静态存储持续时间对对象进行静态初始化。 Otherwise such an object is initialized the first time control passes through its declaration; 否则,将在控件第一次通过其声明时初始化此类对象。 such an object is considered initialized upon the completion of its initialization. 这样的对象在其初始化完成时被视为已初始化。

So we have two cases: 因此,我们有两种情况:

  1. Either we now before we enter the function with a static local x , what value x will have. 在我们使用静态局部x输入函数之前,现在要么x会有什么值。 Then the compiler is allowed to initialize the value as early as possible (even at compile time). 然后,允许编译器尽早初始化值(即使在编译时)。
  2. We don't now the value of x initialize it only the first time we enter our function. 现在,我们仅在第一次进入函数时才将x的值初始化。

So yes what gcc does is not only what you want, this behavior is also standard compliant. 因此,是的,gcc所做的不仅是您想要的,而且此行为也符合标准。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM