开发者

Invalid integer constant expression

In this code:

// CompileTimeWarnings.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <type_traits>
using namespace std;
#define __STR1__(x) #x

#define __LOC__ __FILE__ "("__STR1__(__LINE__)") : warning : "

// collisions.cpp

template<class T, class T1>
struct mismatch
{
    //enum {value = is_signed<T>::value && is_signed<T1>::value};
    static const bool value; //= is_signed<T>::value && is_signed<T1>::value;
};

template<class T, class T1>
bool mismatch<T,T1>::value = is_signed<T>::value && is_signed<T1>::value;

template<class T>
struct Int
{
};

template<class T, class T1>
int operator+(Int<T> t, Int<T1> t1)
{
#if int(mismatch<T,T1>::value)
#pragma message(__LOC__"Need to do 3D collision testing")
#endif
    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
Int<int> a;
Int<signed> b;
b + a;
    return 0;
}

I'm getting following err msg:

C1017: Invalid integer constant expression.

Why? And how to solve it?

Edited

#include "stdafx.h"
#include <type_traits>
#include <iostream>

using namespace std;

template<class T>
struct Int
{
};

template<class T, class T1>
struct Mismatch
{
    static const bool value = (!is_signed<T>::value && is_signed<T1>::value) || 
                                (is_signed<T>::value && !is_signed<T1>::value);
};



template<bool b> struct Need_to_do_3D_collision_testing
{ 
    static void f()
    { static const char value=256; }
};

template<> struct Need_to_do_3D_collision_testing<true>
{
    static void f() { } 
};

template<class T, class T1> int operator+(Int<T> t, Int<T1> t1) 
{
Need_to_do_3D_collision_testing<!Mismatch<T,T1>::value>::f();
return 0;
} 






int _tmain(int argc, _TCHAR* argv[])
{
    Int<char> a;
    Int<unsigned char> b;
    b + a;
    return 0;
}

I'm getting following warnings:

Warning 1 warning C4305: 'initializing' : truncation from 'int' to 'const char'

Warning 2 warning C4309: 'initializing' : truncation of constant value

but not the warning with struct name. So it doesn't work for me as it should.

Edit_2 Warning level /wall - highest

Warning 1 warning C4820: '_wfinddata64i32_t' : '4' bytes padding added after data member '_wfinddata64i32_t::attrib'

Warning 2 warning C4820: '_wfinddata64i32_t' : '4' bytes padding added after data member '_wfinddata64i32_t::name'

Warning 3 warning C4820: '_wfinddata64_t' : '4' bytes padding added after data member '_wfinddata64_t::attrib'

Warning 4 warning C4820: '_stat32' : '2' bytes padding added after data member '_stat32::st_gid'

Warning 5 warning C4820: 'stat' : '2' bytes padding added after data member 'stat::st_gid'

Warning 6 warning C4820: '_stat32i64' : '2' bytes padding added after data member '_stat32i64::st_gid'

Warning 7 warnin开发者_运维百科g C4820: '_stat32i64' : '4' bytes padding added after data member '_stat32i64::st_rdev' Warning 8 warning C4820: '_stat32i64' : '4' bytes padding added after data member '_stat32i64::st_ctime'

Warning 9 warning C4820: '_stat64i32' : '2' bytes padding added after data member '_stat64i32::st_gid'

Warning 10 warning C4820: '_stat64' : '2' bytes padding added after data member '_stat64::st_gid'

Warning 11 warning C4820: '_stat64' : '4' bytes padding added after data member '_stat64::st_rdev' Warning 12 warning C4986: 'operator new[]': exception specification does not match previous declaration

Warning 13 warning C4986: 'operator delete[]': exception specification does not match previous declaration

Warning 14 warning C4820: 'type_info' : '3' bytes padding added after data member 'type_info::_M_d_name' Warning 15 warning C4305: 'initializing' : truncation from 'int' to 'const char' Warning 16 warning C4309: 'initializing' : truncation of constant value

Warning 17 warning C4710: 'std::_Exception_ptr std::_Exception_ptr::_Current_exception(void)' : function not inlined

Warning 18 warning C4710: 'std::string std::locale::name(void) const' : function not inlined

Warning 19 warning C4710: 'std::locale std::ios_base::getloc(void) const' : function not inlined

Warning 20 warning C4710: 'std::string std::numpunct<_Elem>::do_grouping(void) const' : function not inlined

Warning 21 warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::do_falsename(void) const' : function not inlined

Warning 22 warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::do_truename(void) const' : function not inlined

Warning 23 warning C4710: 'std::string std::numpunct<_Elem>::do_grouping(void) const' : function not inlined

Warning 24 warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::do_falsename(void) const' : function not inlined

Warning 25 warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::do_truename(void) const' : function not inlined

Warning 26 warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::falsename(void) const' : function not inlined

Warning 27 warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::truename(void) const' : function not inlined

Warning 28 warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::falsename(void) const' : function not inlined

Warning 29 warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::truename(void) const' : function not inlined

Warning 30 warning C4710: 'std::string std::numpunct<_Elem>::grouping(void) const' : function not inlined

Warning 31 warning C4710: 'std::string std::numpunct<_Elem>::grouping(void) const' : function not inlined


#if int(mismatch<T,T1>::value) 

Preprocessing directives are evaluated before the source is parsed. In this #if directive, the compiler has no idea what a mismatch<T,T1>::value is.


template<class T, class T1>
struct mismatch
{
    static const bool value; //= is_signed<T>::value && is_signed<T1>::value;
};

Beside what James said, why did you comment is_signed<T>::value ..? Uncomment that. It should work!


Solution (C++03):

template<bool b> struct static_assert;
template<> struct static_assert<true>{};

template<class T, class T1>
int operator+(Int<T> t, Int<T1> t1)
{
    static_assert<!mismatch<T,T1>::value> Need_to_do_3D_collision_testing;
    return 0;
}

If T and T1 mismatch, then you would see the string Need_to_do_3D_collision_testing in the compilation error!


Solution (C++0x):

template<class T, class T1>
int operator+(Int<T> t, Int<T1> t1)
{
    static_assert(!mismatch<T,T1>::value, "Need to do 3D collision testing");
    return 0;
}

Solution that generates warning instead of error:

template<bool b> struct Need_to_do_3D_collision_testing 
{ 
     static void f() { static const char value=256; }
};
template<> struct Need_to_do_3D_collision_testing<true>
{
     static void f() { }
};

template<class T, class T1>
int operator+(Int<T> t, Int<T1> t1)
{
    Need_to_do_3D_collision_testing<!mismatch<T,T1>::value>::f();
    return 0;
}

Now, if T and T1 mismatch, then you would see the string Need_to_do_3D_collision_testing in the compilation warning!

Similar techniques is used to print factorial at compile time here:

Calculating and printing factorial at compile time in C++

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜