Clang抱怨POD类实际上是非POD

时间:2013-09-14 22:20:21

标签: c++ c++11 clang llvm variadic-functions

更新:我在这里修改了代码,以便您可以直接插入并尝试编译。

Clang 3.4.1(LLVM 3.4)抱怨我的类在可变参数函数中使用时不是POD类型(据我可以说是最肯定的)。 G ++编译没有问题。

即使按照C ++ 03的标准,这个类也是POD:

  • 它仅包含PODS作为成员
  • 没有用户定义的析构函数
  • 没有用户定义的副本分配运算符
  • 没有指向成员类型的非静态成员

而C ++ 11对“POD”的规则是放松的,那么这里发生了什么?

关于代码:这是矢量的模板类(如矢量图形中所示),可变参数函数仅用于使用一些任意数据填充数组。

我的类头文件:

template<typename TYPE>
class Vec3t;

typedef Vec3t<float> Vec3f;

template<typename TYPE>
class Vec3t {
public:
    Vec3t<TYPE>( void ){}
    Vec3t<TYPE>( const TYPE nx, const TYPE ny, const TYPE nz ){}

    Vec3t<TYPE> operator-(void) const{}

    Vec3t<TYPE> operator*( const Vec3t<TYPE> &other ) const{}
    Vec3t<TYPE> operator*( const TYPE val ) const{}
    Vec3t<TYPE>& operator*=( const Vec3t<TYPE> &other ){}
    Vec3t<TYPE>& operator*=( const TYPE val ){}

    Vec3t<TYPE> operator+( const Vec3t<TYPE> &other ) const{}
    Vec3t<TYPE> operator+( const TYPE val ) const{}
    Vec3t<TYPE>& operator+=( const Vec3t<TYPE> &other ){}
    Vec3t<TYPE>& operator+=( const TYPE val ){}

    Vec3t<TYPE> operator-( const Vec3t<TYPE> &other ) const{}
    Vec3t<TYPE> operator-( const TYPE val ) const{}
    Vec3t<TYPE>& operator-=( const Vec3t<TYPE> &other ){}
    Vec3t<TYPE>& operator-=( const TYPE val ){}

    Vec3t<TYPE> operator/( const Vec3t<TYPE> &other ) const{}
    Vec3t<TYPE> operator/( const TYPE val ) const{}
    Vec3t<TYPE>& operator/=( const TYPE val ){}
    Vec3t<TYPE>& operator/=( const Vec3t<TYPE> &other ){}

    bool operator==( const Vec3t<TYPE> &b ) const {}
    bool operator==( const TYPE b ) const {}
    bool operator!=( const Vec3t<TYPE> &b ) const {}
    bool operator!=( const TYPE b ) const {}

    Vec3t<TYPE>& Set( const TYPE a, const TYPE b, const TYPE c ){}
    Vec3t<TYPE>& Set( const TYPE a, const TYPE b ){}

    void Cross( const Vec3t<TYPE> &other, Vec3t<TYPE> &out ) const{}

    TYPE Dot( const Vec3t<TYPE> &other ) const{}

    Vec3t<TYPE> PerpCCW_ZAxis( void ){}
    Vec3t<TYPE> PerpCW_ZAxis( void ){}

    float Len( void ) const{}
    void Zero( void ){}

    static void Cross( const Vec3t<TYPE> &other, const Vec3t<TYPE> &u, Vec3t<TYPE> &out ){}

    Vec3f Normalize( void ){}
    Vec3f Rotation( TYPE angle ){}
    float DegreesBetween( const Vec3f &other ){}
    float RadiansBetween( const Vec3f &other ){}
    Vec3f Rotate( float angle, const bool inRadians = false ){}
    static float Len( const Vec3f &other ){}

public:
    TYPE        x,y,z;
};

template< typename TYPE >
void FillArray( const std::size_t count, TYPE* var, ... ) {
    va_list vargs;
    va_start( vargs, var );

    for ( std::size_t i=0; i<count; i++ ) {
        var[i] = va_arg( vargs, TYPE ); // ** THIS IS THE LINE CLANG ERRS ON ** //
    }

    va_end( vargs );
}

我的可变参数函数头文件:

#include <cstdarg>

template< typename TYPE >
void FillArray( const std::size_t count, TYPE* var, ... ) {
    va_list vargs;
    va_start( vargs, var );

    for ( std::size_t i=0; i<count; i++ ) {
        var[i] = va_arg( vargs, TYPE ); // ** THIS IS THE LINE CLANG ERRS ON ** //
    }

    va_end( vargs );
}

Clang的错误:     错误:'va_arg'的第二个参数是非POD类型'Vec3t'[-Wnon-pod-varargs]

使用这些导致Clang错误的示例程序:     #include“fillarray.h”

int main ( void ) {
    Vec3t<float> v[2];
    FillArray< Vec3t<float> >( 2, v, 0.4f, 0.5f);
}

编译:      clang ++ x.cpp -I / usr / include / i386-linux-gnu / c ++ / 4.8 -std = gnu ++ 11

1 个答案:

答案 0 :(得分:6)

§12.1/ 7:

  

如果默认构造函数不是用户提供的,那么它是微不足道的......

     

否则,默认构造函数是非平凡

根据定义,您声明的默认构造函数是非平凡的。

§9/ 3:

  

普通类是一个具有普通默认构造函数(12.1)并且可以轻易复制的类。

由于默认构造函数不重要,因此该类并不重要。

§9/ 10:

  

POD结构是一个非联合类,它既是一个普通的类又是一个标准布局类......

由于课程不是微不足道的,因此不符合POD的要求。为了使它成为POD,你必须摆脱默认的构造函数。