-1

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 warning 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

There is nothing we can do
  • 23,727
  • 30
  • 106
  • 194
  • 5
    @There: You've asked how many questions on SO, and you still haven't learned how to post a complete error message? Shame. on. you. – Ben Voigt Feb 18 '11 at 20:44
  • 2
    Well defining macros using double underscore is going to come back and kick you in the arse one day. Why do you feel the need to use [double underscore](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier/228797#228797)? – Martin York Feb 18 '11 at 20:49
  • @Martin it is just copied and pasted from Microsoft website http://support.microsoft.com/kb/155196 – There is nothing we can do Feb 18 '11 at 20:55
  • 1
    Also note the extra __STR1__ => __STR2__ (that you have dropped) is required to make the # work correctly for quoting purposes. – Martin York Feb 18 '11 at 21:15
  • 1
    Microsoft is allowed to do it. Because they build the compiler and the OS, the double underscore is actually reserved for their usage (in system and compiler header files). You doing it potentially breaks the underlying header files and leads to UB – Martin York Feb 18 '11 at 21:26
  • "`(!is_signed::value && is_signed::value) || (is_signed::value && !is_signed::value)`" or just `!!is_signed::value != !!is_signed::value` (The double negative is only necessary is the value isn't guaranteed to be true or false. You may omit it otherwise.) – curiousguy Jun 08 '18 at 00:32

2 Answers2

6
#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.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • 1
    If your compiler has `static_assert` (I do not remember whether VS 2010 does), you can use that for the fail-on-condition part. Otherwise, Boost has `BOOST_STATIC_ASSERT`. – Jeremiah Willcock Feb 18 '11 at 20:41
  • @Jeremiah: Kind of. The OP's code generates a compile-time message, not an error. – James McNellis Feb 18 '11 at 20:43
  • @James is there any way to use macro in order to evaluate this expression? – There is nothing we can do Feb 18 '11 at 20:44
  • @James to your comment - exactly, it has to be a message not error. And what the OP abbreviation means? – There is nothing we can do Feb 18 '11 at 20:44
  • @There: No, you can't use a macro for this. `T` is a template parameter, and template instantiation doesn't occur until long after preprocessing is complete. Whether your compiler provides a way to generate non-error compilation messages after preprocessing, I don't know. As @Jeremiah says, you can use `static_assert` to assert that the condition is true (and cause compilation to fail if it is not). Visual C++ 2010 does support `static_assert`. "OP" stands for "original post" or "original poster," referring either to the question itself or the asker of the question, depending on the context. – James McNellis Feb 18 '11 at 20:46
  • Not only that, but the `#if` directive is processed while the template is created, not expanded, so even if that were a valid expression it wouldn't do what was desired. – Mark Ransom Feb 18 '11 at 20:51
0
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++

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • @Nawaz yes it does work I just wanted to do it outside of class. Don't ask why ;) – There is nothing we can do Feb 18 '11 at 20:46
  • @James: you naughty:P. anyway fixed. :D – Nawaz Feb 18 '11 at 21:01
  • @There is nothing we can do : ... then you can overflow as shown in this solution : http://stackoverflow.com/questions/4977715/calculating-and-printing-factorial-at-compile-time-in-c/4977816#4977816 – Nawaz Feb 18 '11 at 21:08
  • @There is nothing we can do: ... see the last part of solution! – Nawaz Feb 18 '11 at 21:13
  • @There is nothing we can do: Please provide me more information. 1) which solution did you use? 2) What happens if you use it? Does it give error? 3) If it doesn't give error, the compiler doesn't print `Need_to_do_3D_collision_testing` as **warning**? 4) How exactly you use it? – Nawaz Feb 19 '11 at 17:10
  • @Nawaz 1) I've used solution which I've included under __Edited__ in my original post. 2) If I use it I'm getting errors listed in beforementioned edit, no it doesn't give any error. 4)You can just copy and paste of what I've edited to my OP. That's the way I've used it. Thanks. – There is nothing we can do Feb 19 '11 at 17:25
  • @There is nothing we can do: If your program already gives error, how can you say that this solution doesn't work? Please remove errors from your program, first. By the way, mismatch::value can be either true or false. If it's true, then my solution would give Warning, or else if would not. See this : http://www.ideone.com/GjsKX ... it gives warning, I'm passing `false`, as I negate the value of mismatch! – Nawaz Feb 19 '11 at 17:41
  • @Nawaz why are you saying that my program gives an error?! It compiles with warning messages as listed in my __Edited__ addition to my OP, but the warning messages have nothing to do with my names chosen by me! Could you please check my __Edited__ OP and take it from there? – There is nothing we can do Feb 19 '11 at 17:45
  • @There is nothing we can do: Alright. So those warning coming from my code? or your code? See the line number and tell me. If my solution, then please tell me which compiler are you using? – Nawaz Feb 19 '11 at 17:48
  • @Nawaz they (the warnings) are coming from my code which is included under __Edited__ in my original post. There (in this code) are fragments literally copied and paste from your solution. I'm using VS2010 sp1. – There is nothing we can do Feb 19 '11 at 18:44
  • @Nawaz this line is listed in warning window: static void f() { static const char value=256; } – There is nothing we can do Feb 19 '11 at 18:49
  • @There is nothing we can do : Please see this code at ideone: http://www.ideone.com/GjsKX ... it's working. So defnitely there is some problem with your code, or with the warning level your compiler is using. – Nawaz Feb 19 '11 at 18:52
  • @Nawaz I copied the code from place you've included in your last comment, I've set warning level to highest possible and still in VS I'm not getting the result expected. I've listed all warnings I'm getting from your code in my OP. – There is nothing we can do Feb 19 '11 at 19:13
  • @There is nothing we can do : Are you calling `operator+` in your code? Try using `Need_to_do_3D_collision_testing<!mismatch::value>::f();` in main() to check if it works or not. – Nawaz Feb 19 '11 at 19:18
  • @Nawaz I've copied your code from http://www.ideone.com/GjsKX and run it. I've said it in my last comment to you. No operator + is being called. It is your code. – There is nothing we can do Feb 19 '11 at 19:23
  • @There is nothing we can do : If you're not calling `operator+` then you would not see warning in compilation! – Nawaz Feb 19 '11 at 19:27
  • @Nawaz are you calling operator+ in your code from http://www.ideone.com/GjsKX? No. Are you getting warnings? Yes. So what is it that made you post last comment? – There is nothing we can do Feb 19 '11 at 19:31
  • @There is nothing we can do: in my example, at ideone `Need_to_do_3D_collision_testing::f();` is inside main. And main is getting called. that's why you're able to see the warning. – Nawaz Feb 19 '11 at 19:33
  • @There is nothing we can do: READ THIS >> your `operator+` is a function template, if you don't call it, then the compiler doesn't instantiate it, that means whatever you write inside this function doesn't bother compiler, hence compiler doesn't give any warning. Did you understand it? – Nawaz Feb 19 '11 at 19:35
  • @Nawaz and I've copied YOUR example and run it. And I do not see those warnings you're talking about. – There is nothing we can do Feb 19 '11 at 19:36
  • @There is nothing we can do : See the difference between this (http://www.ideone.com/ljD82) and this (http://www.ideone.com/77948) ... as I said, function template or class template doesn't get instantiated by the compiler if you don't use it in your program. So if it doesn't get instantiated, then how can compiler give any warning? – Nawaz Feb 19 '11 at 19:39
  • @There is nothing we can do: Are you reading me? I said IF YOU DONT CALL FUNCTION TEMPLATE, then THE FUNCTION TEMPLATE DOES NOT GET INSTANTIATED IN THE FIRST PLACE. IF IT DOES NOT GET INSTANTIATED, then THE COMPILER DOES BOTHER WITH THE CODE INSIDE THE FUNCTION, HENCE IT DOES NOT GIVE ANY WARNING! – Nawaz Feb 19 '11 at 19:41
  • Is this code suppose to give warnings: using namespace std; template struct Need_to_do_3D_collision_testing { static void f() { static const char value=256; } }; template<> struct Need_to_do_3D_collision_testing { static void f() { } }; int main() { Need_to_do_3D_collision_testing::f(); return 0; } – There is nothing we can do Feb 19 '11 at 19:56
  • @There is nothing we can do : Yes. Does it not give warning here at ideone : http://www.ideone.com/GjsKX ? – Nawaz Feb 19 '11 at 19:59
  • @Nawaz that's what I'm trying to tell you for the last four comments. I'm running THIS code and I'm NOT getting those messages. Are you reading me? – There is nothing we can do Feb 19 '11 at 20:00
  • @There is nothing we can do : In Visual Studio, those warning show up in output tab, not in error-list tab. See the tab in which you usually see such message *"Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped"*... in the same tab, you will see lots of message while building; some of them will show up this warning we're talking about. – Nawaz Feb 19 '11 at 20:05
  • @Nawaz but the whole point of it is to have the warnings in warning tab isn't it? – There is nothing we can do Feb 19 '11 at 20:09
  • @There is nothing we can do: The whole point is that the good compilers will list the warnings in warning tab. But one cannot trust MSVC++ compiler. It shows detail warning, and errors in output tab, but one line with few words in warning tab. Very bad! – Nawaz Feb 19 '11 at 20:20
  • I strongly disagree that that behavior is "very bad." The Error List pane is very useful because it provides a summary of the errors and for most common errors it provides sufficient information to solve the problem without diving into the output from the compiler. The Error List is synchronized with both the editor and the Output pane, so selecting an error brings you both to the detailed output from the compiler and to the place at which the error was detected. The error list would be pretty useless if it included the entirety of 50 line template instantiation errors inline in the pane. – James McNellis Feb 19 '11 at 20:45
  • @James: Hmm... I tend to agree with you. :-) – Nawaz Feb 19 '11 at 20:46
  • @Nawaz so basically there is no way to do it in VS? – There is nothing we can do Feb 19 '11 at 22:56
  • @James but we are not talking here about errors. Warnings are of consideration here and they aren't properly logged to warning tab. – There is nothing we can do Feb 20 '11 at 09:19
  • @There: There is no "warning tab." The first line of any compiler error, warning, or message is reported in the Error List pane. – James McNellis Feb 20 '11 at 22:06