小编anx*_*eux的帖子

晚期默认模板参数声明中的clang ++错误

下面的代码用g ++编译好,但不能用clang ++(3.6)编译:

// Forward declaration:
template <class S, class T>
struct Base;

template <class T>
struct BaseFriend {
    friend struct Base<int, T>;
};

// Actual declaration:
template <class S, class T = int>
struct Base {
    void foo() {}
};

struct DerivedFriend : BaseFriend<int> {};

struct Derived : Base<int> {
    void foo(int) {
        Base<int>::foo();
    }
};
Run Code Online (Sandbox Code Playgroud)

Derived::foo定义中出错:

error: too few template arguments for class template 'Base'
    Base<int>::foo();
    ^
test.cpp:3:8: note: template is declared here
struct Base;
       ^
Run Code Online (Sandbox Code Playgroud)

经过一些小修复后,错误消失了,例如: …

c++ templates clang++

7
推荐指数
1
解决办法
384
查看次数

C++编译器如何优化错误的分层向下转换以导致真正的未定义行为

请考虑以下示例:

class Base {
public:
    int data_;
};

class Derived : public Base {
public:
    void fun() { ::std::cout << "Hi, I'm " << this << ::std::endl; }
};

int main() {
    Base base;
    Derived *derived = static_cast<Derived*>(&base); // Undefined behavior!

    derived->fun(); 

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

根据C++标准,函数调用显然是未定义的行为.但是在所有可用的机器和编译器(VC2005/2008,RH Linux和SunOS上的gcc)上,它按预期工作(打印"嗨!").有谁知道配置此代码可以正常工作?或者可能是具有相同想法的更复杂的例子(注意,Derived不应该携带任何额外的数据)?

更新:

从标准5.2.9/8:

类型"指针CV1 B",其中B是一个类类型的右值,可以转换为类型"指针CV2 d",的右值,其中d是从乙派生的类(第10节),如果一个有效的标准从"指针d"转换到"指针到B"的存在(4.10),CV2是相同cvqualification为或者更大cvqualification比,CV1,和B不是虚拟基类d的空指针值(4.10)转换为目标类型的空指针值.如果类型是"指针CV1 B"点右值进行B实际上是类型d的对象的子对象,将所得指针指向类型D.的包围对象否则,铸造的结果是不确定的.

还有一个9.3.1(感谢@Agent_L):

如果为非X类型的对象或从X派生的类型调用类X的非静态成员函数,则行为未定义.

谢谢,迈克.

c++ compiler-optimization undefined-behavior

3
推荐指数
2
解决办法
303
查看次数