Camille Goudeseune February 2016

assert(true) warns of signed/unsigned mismatch

Visual Studio 2008, debug build. This line of C++

assert(true);

causes the complaint

warning C4365: 'argument' : conversion from 'long' to 'unsigned int', signed/unsigned mismatch

The warning persists when replacing true with any (useful) boolean expression, even with 1ul.

FYI, the compiler's file assert.h is:

#define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
extern "C" _CRTIMP void __cdecl _wassert(_In_z_ const wchar_t * _Message, _In_z_ const wchar_t *_File, _In_ unsigned _Line);

How can this warning be cleanly suppressed, without suppressing all C4365's? Is it the fault of __LINE__??

Answers


Jesse Good February 2016

The bug report explains it very well:

This issue occurs because __LINE__ is of type long, and the assert macro passes __LINE__ as an argument to the _wassert function, which expects an unsigned int. When not compiling with /ZI, __LINE__ is a constant expression, so the compiler can statically determine that the conversion to unsigned int will result in the same value. When compiling with /ZI, __LINE__ is not a constant expression, so the compiler cannot statically determine that the conversion will result in the same value and it issues warning C4365.

It also gives a workaround:

As a workaround for this issue, I would recommend #undefing assert in your source code, and re-#define-ing it, using the same definition as in <assert.h>, but with a cast to suppress the warning.

Note that this bug seems to have been fixed starting from MSVC2015.

Post Status

Asked in February 2016
Viewed 3,303 times
Voted 4
Answered 1 times

Search




Leave an answer