C++ 在全局变量上使用新位置时是否有任何错误?
我在玩一个想法,我可以在全局范围内有变量,但是。请注意,正在运行一个新的放置。但是,我想知道这个代码有哪些未定义或不正确的地方C++ 在全局变量上使用新位置时是否有任何错误?,c++,C++,我在玩一个想法,我可以在全局范围内有变量,但是。请注意,正在运行一个新的放置。但是,我想知道这个代码有哪些未定义或不正确的地方 #include <new> #include <cstdio> #include <typeinfo> //#define AlignAs alignas(T) #define AlignAs template<class T>struct BlockOf { AlignAs char t[sizeof(T)
#include <new>
#include <cstdio>
#include <typeinfo>
//#define AlignAs alignas(T)
#define AlignAs
template<class T>struct BlockOf {
AlignAs char t[sizeof(T)];
operator T&() { return reinterpret_cast<T&>(*this); }
~BlockOf(){((T*)&t)->~T(); }
};
struct B{
virtual void v(){}
~B() { printf("B\n"); }
};
struct A: B{
A(){printf("a\n");}
int regularDots;
void v() { printf("A virtual\n"); }
};
BlockOf<A> _a;
A&a=_a;
void init(){
new(&a) A;
}
int main() {
init();
A aa;
a.regularDots=9;
printf("%s %s %d %d\n",
typeid(a).name(),
typeid(aa).name(),
typeid(a).hash_code()==typeid(aa).hash_code(),
sizeof(a) == sizeof(aa)
);
B *b = &a;
b->v();
}
#包括
#包括
#包括
//#将AlignAs定义为AlignAs(T)
#定义AlignAs
模板结构块{
AlignAs char t[sizeof(t)];
运算符T&({返回重新解释_cast(*this);}
~BlockOf(){((T*)&T)->~T();}
};
结构B{
虚拟void v(){}
~B(){printf(“B\n”);}
};
结构A:B{
A(){printf(“A\n”);}
int正则点;
void v(){printf(“虚拟的\n”);}
};
阻塞a;
A&A=_A;
void init(){
新(a)a ;;
}
int main(){
init();
A aa;
a、 正常点=9;
printf(“%s%s%d%d\n”,
typeid(a).name(),
typeid(aa).name(),
typeid(a).hash_-code()==typeid(aa).hash_-code(),
sizeof(a)=sizeof(aa)
);
B*B=&a;
b->v();
}
这不清楚
operator T&() { return *reinterpret_cast<T*>(this); }
运算符T&({return*重新解释_cast(this);}
改用
operator T&() { return reinterpret_cast<T&>(t[0]); }
运算符T&({return reinterpret_cast(T[0]);}
我认为这个
必须指向第一个成员,但对我来说,明确使用数组似乎更安全
为了回答您的主要问题,3.8p8包含了关于重用属于静态存储持续时间变量的内存的限制,并且由于原始类型有一个简单的析构函数,您应该可以 如果程序使用静态(3.7.1)、线程(3.7.2)或自动(3.7.3)存储持续时间结束
T
类型对象的生存期,并且如果T
具有非平凡析构函数,
当隐式析构函数调用发生时,程序必须确保原始类型的对象占用相同的存储位置;否则,程序的行为是未定义的
这还不清楚
operator T&() { return *reinterpret_cast<T*>(this); }
运算符T&({return*重新解释_cast(this);}
改用
operator T&() { return reinterpret_cast<T&>(t[0]); }
运算符T&({return reinterpret_cast(T[0]);}
我认为这个
必须指向第一个成员,但对我来说,明确使用数组似乎更安全
为了回答您的主要问题,3.8p8包含了关于重用属于静态存储持续时间变量的内存的限制,并且由于原始类型有一个简单的析构函数,您应该可以 如果程序使用静态(3.7.1)、线程(3.7.2)或自动(3.7.3)存储持续时间结束
T
类型对象的生存期,并且如果T
具有非平凡析构函数,
当隐式析构函数调用发生时,程序必须确保原始类型的对象占用相同的存储位置;否则,程序的行为是未定义的
这还不算太糟,您上一个问题中的代码刚刚开始访问成员,并没有构造对象。@BenVoigt:yep。这是一个疏忽。我不打算访问成员。我的意思是,由于语法不使用(oops),我明白你想做什么了。您正在尝试使用正向声明类型的全局变量。您希望将初始值设定项和存储粘贴到其他文件中,同时将全局引用放在其他文件中,这样您就不必包含定义。@acidzombie24:我看到的代码越多,我越认为您应该使用
boost::optional
(1)没有alignas
(2)BlockOf
调用析构函数的编译器中的对齐错误,即使内容已被析构函数。这是未定义的行为。(3) ~B
应该是虚拟的,尽管您的代码中没有出现潜在的未定义行为。这并不是很糟糕,您上一个问题中的代码只是开始访问成员,并没有构造对象。@BenVoigt:yep。这是一个疏忽。我不打算访问成员。我的意思是,由于语法不使用(oops),我明白你想做什么了。您正在尝试使用正向声明类型的全局变量。您希望将初始值设定项和存储粘贴到其他文件中,同时将全局引用放在其他文件中,这样您就不必包含定义。@acidzombie24:我看到的代码越多,我越认为您应该使用boost::optional
(1)没有alignas
(2)BlockOf
调用析构函数的编译器中的对齐错误,即使内容已被析构函数。这是未定义的行为。(3) ~B
应该是虚拟的,尽管您的代码中没有出现潜在的未定义行为。听起来只要我也调用了一个内置析构函数,我就可以使用它了?@acidzombie24:如果您想调用析构函数,您必须自己做。只有你知道析构函数是否有用,没有理由不调用它。我编辑了我的代码。铸造t[0]是否与此*有任何不同?我看不出有什么原因safer@acidzombie24:您对t
应用了对齐限制。这应该会影响整个对象的对齐,但在我看来,使用t
显然是正确的。听起来只要我同时调用一个内置析构函数,我就可以使用它了?@acidzombie24:如果你想调用析构函数,你必须自己做。只有你知道析构函数是否有用,没有理由不调用它。我编辑了我的代码。铸造t[0]是否与此*有任何不同?我看不出有什么原因safer@acidzombie24:您对t
应用了对齐限制。这应该会影响整个对象的对齐,但是使用t
显然是不正确的。