【问题标题】:member defined in anonymous struct in protected anonymous union is still publicly visible在受保护的匿名联合中的匿名结构中定义的成员仍然是公开可见的
【发布时间】: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&lt;double, 3&gt;,但这并没有改变任何东西。此外,成员 zw 也是可见的,就像 xy 一样。但是,data 不可见(例如,std::cout &lt;&lt; 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&lt;T,0x02&gt;' : 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&lt;T&gt;' being compiled

这(例如它崩溃的事实)可能只是编译器中的一个错误,但如果有人知道,我仍然想知道为什么该行的两种替代形式都不能编译。

【问题讨论】:

    标签: c++ c++11 visual-studio-2013 unions anonymous-inner-class


    【解决方案1】:

    我必须进行一些更改才能让代码在 clang 上完全编译。似乎 Visual c++ 非常宽松,允许非法(或者我应该说是非标准)语法。

    这是更正后的程序:

    #include <iostream>
    #include <algorithm>
    
    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;
    
        Vector2(T x = 0, T y = 0) :
        Vector<T, 2>({ x, y }){}
    
        Vector2(const Vector2& vec) :
        Vector<T, 2>(vec) {}
    
        using Vector<T, 2>::x;
        using Vector<T, 2>::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.
    }
    

    这是修改后的(预期的)错误:

    ./vec.cpp:66:33: error: 'x' is a protected member of 'Vector<double, 2>'
        std::cout << " c.x = " << c.x << "\n";
                                    ^
    ./vec.cpp:37:15: note: declared protected here
                T x, y, z, w;
                  ^
    1 error generated.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-21
      • 1970-01-01
      • 1970-01-01
      • 2019-10-21
      • 1970-01-01
      • 2019-06-01
      相关资源
      最近更新 更多