std::numeric_limits<T>::is_signed generates warning in function template compiled Release - by Steve Huston

Status : 

  By Design<br /><br />
		The product team believes this item works according to its intended design.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.

Sign in
to vote
ID 777327 Comments
Status Closed Workarounds
Type Bug Repros 0
Opened 1/23/2013 4:18:12 PM
Access Restriction Public


In all of Visual Studio 2012, 2010 and 2008 I experience this problem. The following code compiles and runs correctly when compiled in Debug mode. When compiled in Release mode it runs correctly but generates a compile warning. Our project's guidelines do not allow code with warnings to be used.

#include <limits>
#include <iostream>

typedef unsigned int     uint32_t;
typedef int              int32_t;
typedef unsigned __int64 uint64_t;

template<class T> T convert()
  T r = 4;
  if (std::numeric_limits<T>::is_signed) {
    return -r;                    
  } else {
    if (r==0) return 0;
  return r;

int main(int, char *[])
  std::cout << "unsigned int: " <<  std::numeric_limits<unsigned int>::is_signed << std::endl;
  std::cout << "uint32_t: " <<  std::numeric_limits<uint32_t>::is_signed << std::endl;
  std::cout << "unsigned __int64: " <<  std::numeric_limits<unsigned __int64>::is_signed << std::endl;
  std::cout << "uint64_t: " <<  std::numeric_limits<uint64_t>::is_signed << std::endl;

  std::cout << "uint32_t 4 is " << convert<uint32_t>() << std::endl;
  std::cout << "int32_t 4 is " << convert<int32_t>() << std::endl;

  return 0;
Sign in to post a comment.
Posted by Stephan [MSFT] on 2/6/2013 at 7:57 PM

Thanks for reporting this issue. I've resolved it as By Design because the compiler and Standard Library implementation are working correctly here.

When you instantiate convert<uint32_t>(), the compiler sees a test that will be executed at runtime, followed by unary minus being applied to an unsigned integer. Although it warns that the conditional expression is constant (at /W4), it also warns about the unary minus, despite the fact that that code will never be executed at runtime.

If you want your code to compile cleanly without suppressing warnings, you need to perform this test at compiletime. There are many ways to do so, but the easiest way (which we prefer in the STL's implementation) is "tag dispatch":

C:\Temp>type meow.cpp
#include <stdint.h>
#include <iostream>
#include <type_traits>
using namespace std;

template <typename T> T convert_helper(T t, true_type) {
    return -t;

template <typename T> T convert_helper(T t, false_type) {
    return t;

template <typename T> T convert() {
    T t = 4;

    return convert_helper(t, is_signed<T>());

int main() {
    cout << "convert<int32_t>(): " << convert<int32_t>() << endl;
    cout << "convert<uint32_t>(): " << convert<uint32_t>() << endl;

C:\Temp>cl /EHsc /nologo /W4 /MTd meow.cpp

convert<int32_t>(): -4
convert<uint32_t>(): 4

What's happening here is that is_signed<T> is a struct template that derives from either a true_type struct or false_type struct (in reality they are typedefs, but thinking of them as plain old structs is correct here). In my example, convert() says is_signed<T>() to construct a temporary object of this type. I could also have said is_signed<T> dummy; followed by return convert_helper(t, dummy); although that would be more verbose. Overload resolution then selects either convert_helper(T, true_type) or convert_helper(T, false_type). (We are passing an object of derived type by value. Doing this "slices" it, but we don't care - we're doing this for overload resolution only, and we don't care about the dummy object itself. convert_helper() doesn't even bother to name this parameter.) The key part is that only the desired overload of convert_helper() is instantiated. For unsigned types, the expression "-t" is never compiled, because that's in an overload that isn't selected.

Note: Connect doesn't notify me about comments. If you have any further questions, please E-mail me.

Stephan T. Lavavej
Senior Developer - Visual C++ Libraries
Posted by Microsoft on 1/23/2013 at 10:20 PM
Thank you for submitting feedback on Visual Studio and .NET Framework. Your issue has been routed to the appropriate VS development team for investigation. We will contact you if we require any additional information.
Posted by Macy [MSFT] on 1/23/2013 at 4:50 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(