- 主题:static typename EnvType env_storage_; 静态对象居然被优化掉
编译器是VS2019最新版。
EnvType是通过模板参数传递进来的类型,
在这个模板类的函数中定义一个静态对象,用于单例。改自leveldb的代码(它的单例实现不是static对象,是placement new,对内存泄漏检查是个干扰,故改之):
https://github.com/google/leveldb/blob/main/util/env_windows.cc
template <typename EnvType>
class SingletonEnv {
public:
SingletonEnv() {
}
~SingletonEnv() = default;
SingletonEnv(const SingletonEnv&) = delete;
SingletonEnv& operator=(const SingletonEnv&) = delete;
Env* env() {
static typename EnvType env_storage_;
return reinterpret_cast<Env*>(&env_storage_);
}
这句:static typename EnvType env_storage_;
发现这个静态对象env_storage_在debug版本中最开始时不对,rebuild后没问题。
在release版本中静态对象的构造被优化掉了,貌似直接返回了env_storage_的固定地址。
上一层的那个静态对象的构造也被优化掉了,如下:
Env* Env::Default() {
static WindowsDefaultEnv env_container;
return env_container.env();
}
Env* Env::Default()在release版的实现就是:
mov rax, XXXX // 返回一个固定地址
ret
这显然不符合预期。
改成 static EnvType env_storage_; 后正常。
--
FROM 222.130.137.*
原本的代码为何要加typename?
--
FROM 122.224.174.*
感觉这个写法不满足这个里面的任意一项:
https://en.cppreference.com/w/cpp/keyword/typename
(最接近的是第三项,但是这个写法应该不属于qualified type name)
【 在 z16166 的大作中提到: 】
: 编译器是VS2019最新版。
: EnvType是通过模板参数传递进来的类型,
: 在这个模板类的函数中定义一个静态对象,用于单例。改自leveldb的代码(它的单例实现不是static对象,是placement new,对内存泄漏检查是个干扰,故改之):
: ...................
--
FROM 182.150.115.*
随手加的,因为是个模板参数类型。实际上类声明的一开始就有,属于加重复了。
template <typename EnvType>
class SingletonEnv {
但是这个结局有点出乎意料
【 在 ziqin 的大作中提到: 】
: 原本的代码为何要加typename?
--
FROM 222.130.137.*
满足第二条吧,声明变量时用。
leveldb自己的代码里也有类似的,比如声明env_storage_变量:
typename std::aligned_storage<sizeof(EnvType), alignof(EnvType)>::type env_storage_;
我只是在前面加了个static限定符
【 在 haha103 的大作中提到: 】
: 感觉这个写法不满足这个里面的任意一项:
:
https://en.cppreference.com/w/cpp/keyword/typename: (最接近的是第三项,但是这个写法应该不属于qualified type name)
--
FROM 222.130.137.*
第二条是:dependent qualified name
你这个既不是dependent也不是qualified name撒
你的下面这个例子就是dependent的typename xxxx::type
【 在 z16166 的大作中提到: 】
: 满足第二条吧,声明变量时用。
: leveldb自己的代码里也有类似的,比如声明env_storage_变量:
: typename std::aligned_storage<sizeof(EnvType), alignof(EnvType)>::type env_storage_;
: ...................
--
修改:haha103 FROM 182.150.115.*
FROM 182.150.115.*
那是不是应该报错
debug/release都能pass
【 在 haha103 的大作中提到: 】
: 第二条是:dependent qualified name
: 你这个既不是dependent也不是qualified name撒
: 你的下面这个例子就是dependent的typename xxxx::type
--
FROM 222.130.137.*
gcc真报错
expected primary-expression before 'static'
【 在 z16166 的大作中提到: 】
: 那是不是应该报错
: debug/release都能pass
--
修改:haha103 FROM 182.150.115.*
FROM 182.150.115.*
我弄了个github repo,看来可以把这个repo提个issue给MS
【 在 haha103 的大作中提到: 】
: gcc真报错
--
FROM 222.130.137.*
这样写就可以
template <typename EnvType>
class SingletonEnv {
public:
....
typedef EnvType tt;
Env* env() {
static typename SingletonEnv::tt env_storage_;
return reinterpret_cast<Env*>(&env_storage_);
}
};
【 在 z16166 的大作中提到: 】
: 我弄了个github repo,看来可以把这个repo提个issue给MS
--
修改:haha103 FROM 182.150.115.*
FROM 182.150.115.*