对于那些无法深入阅读问题的人来说,问题是粗体的。
这是this问题的后续问题。它与函数中静态变量的初始化语义有关。静态变量应初始化一次,其内部状态可能会在以后更改 - 正如我(当前)在链接问题中所做的那样。但是,有问题的代码不需要该功能稍后更改变量的状态。
让我澄清一下我的立场,因为我不需要改变字符串对象的内部状态。该代码用于元编程的特征类,因此可以从const char * const ptr获益 - 因此理想情况下需要本地成本静态const变量。我有根据的猜测是,在这种情况下,所讨论的字符串将通过链接加载器最佳地放置在内存中,并且代码更安全并映射到预期的语义。
这导致了这样一个变量的语义“C ++编程语言第三版 - Stroustrup”没有任何东西(我可以找到)来说明这个问题。所有这一切都是当线程的控制流首先到达代码时,变量被初始化一次。 这让我思考,如果以下代码是明智的,如果不是,那么预期的语义是什么?
#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日
我正在使用以下宏在我的类中生成上面提到的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); \
}
这些宏放在类声明中。例如:
template<class tag>
class ConfigInstance{
public:
MACRO_STATIC_SETTING_PTR(sqllite3_filename, char *)
};
希望这对其他人有用。
答案 0 :(得分:4)
让我们看看C ++标准的第6.7§4节(宣言声明)。
允许实现执行其他的早期初始化 在相同条件下具有静态存储持续时间的本地对象 允许实现静态初始化对象 在命名空间作用域中使用静态存储 否则,在第一次控制通过时初始化这样的对象 通过宣言;这样的对象被认为是初始化的 完成初始化。
所以我们有两个案例:
x
输入函数之前,x
将具有什么值。然后允许编译器尽早初始化该值(即使在编译时)。x
的值仅在我们第一次输入函数时初始化它。所以,是的,gcc所做的不仅仅是你想要的,这种行为也符合标准。