【发布时间】:2015-11-18 13:04:01
【问题描述】:
我已经设法编译和运行 c++ 代码,即使它不应该这样做。
下面的 sn-p 不应该编译:
template<typename T, size_t SIZE>
struct Vector {
Vector(std::initializer_list<T> data) {
std::copy(data.begin(), data.end(), this->data);
}
Vector(T(&data)[SIZE]) {
std::copy(data, data + SIZE, this->data);
}
protected:
#pragma pack(push, 1) //stores the alignment of aggregate types and sets it to 1 byte
union {
struct {
T x, y, z, w;
};
T data[SIZE];
};
#pragma pack(pop) //restore old data alignment
};
template<typename T>
struct Vector2 : public Vector<T, 2> {
using Vector<T, 2>::Vector<T, 2>;
Vector2(T x = 0, T y = 0) :
Vector({ x, y }){}
Vector2(const Vector& vec) :
Vector(vec) {}
using Vector::x;
using Vector::y;
};
int main() {
double floats[2]{ 2, 3 };
Vector2<double> v{ floats };
Vector<double, 2> c{ 5., 6. };
std::cout << "v.x = " << v.x;
//Is oke, v.x is visible here because of the public using statement
std::cout << " c.x = " << c.x << "\n";
//Is not oke, c is not a Vector2<double>. It is a Vector<double, 2> so its member x is protected and thus not visible from here.
}
输出: v.x = 2 c.x = 5
所以这个程序不仅成功地编译和链接,而且还运行和打印敏感数据。
我尝试将c 的类型更改为Vector<double, 3>,但这并没有改变任何东西。此外,成员 z 和 w 也是可见的,就像 x 和 y 一样。但是,data 不可见(例如,std::cout << c.data[0]; 不会按预期编译)。
在这种情况下,Intellisense 比编译器更智能,因为它成功地检测到错误并进行投诉。
我正在使用 Visual Studio 2013。
PS:
附带问题:我在相同的代码 sn-p 中发现了编译器的另一个怪癖。如果我更改以下行:
using Vector<T, 2>::Vector<T, 2>;
到:
using Vector<T, 2>::Vector;
我得到这个编译器错误:error C2886: 'Vector<T,0x02>' : symbol cannot be used in a member using-declaration
如果我将其更改为:
using Vector::Vector;
编译器与以下内容一起崩溃:fatal error C1001: An internal error has occurred in the compiler. see reference to class template instantiation 'Vector2<T>' being compiled。
这(例如它崩溃的事实)可能只是编译器中的一个错误,但如果有人知道,我仍然想知道为什么该行的两种替代形式都不能编译。
【问题讨论】:
标签: c++ c++11 visual-studio-2013 unions anonymous-inner-class