Assert is seen as C style cast in Visual Studio - c++

Here is the error and a glimpse of the code One of my courses demands me to use Warning Level 4 and to treat warnings as errors in Visual Studio. Beside that, we also need to activate Cpp Core Guidelines. However, since I activated these options I've been haunted by warning error C26493 (don't use C style casts). Apparently, they consider my "assert" tests as C style casts. I haven't seen any other student having this problem. Can somebody help me fix this thing?

Assert is a macro that expands (in visual studio) to:
#define assert(expression) (void)( \
(!!(expression)) || \
(_wassert(_CRT_WIDE(#expression), _CRT_WIDE(__FILE__), (unsigned)(__LINE__)), 0) \
)
As you can see, there is a C-style case to void.

All students should see the warning, not just you. If you want to avoid this warning, use an implementation of ASSERT using C++-style casts.
Any standard ASSERT macro I've been working with expands to a C-style cast to void but a gcc c++ mode: https://github.com/lattera/glibc/blob/master/assert/assert.h
Here is an example of my custom implementation using C++ casts. This is also using a global variable in debug mode to be able to disable assertions while debugging.
extern MYUTILS_DLLINTERFACE bool g_MYASSERT_enabled;
extern bool MYUTILS_DLLINTERFACE _is_MYASSERT_enabled();
#ifdef _DEBUG
# define __MYASSERT(x) (static_cast<void>(!_is_MYASSERT_enabled() || (_ASSERTE(x), 0)))
#else
# define __MYASSERT(x) (static_cast<void>(0))
#endif

Related

What is visual studio equivalent of GCC attribute unused [duplicate]

I am trying to write a macro to use suppress unused variable warnings when the user wants them (e.g. in derived classes when you have not implemented the whole class yet). I know that I can remove the variable name... but to make it clear I would prefer a macro).
So far I have this:
#ifdef WIN32
#define UNUSED(x) x
#else
#define x __attribute__((unused))
#endif
Used like:
void test_fn(int UNUSED(test_var)) {...}
I saw this post: suppressing-is-never-used-and-is-never-assigned-to-warnings-in-c-sharp, but it gave me a result that I can't really use (multiline #pragmas).
So my question is, is there a MSVS equivalent of the __attribute__((unused))? - i.e. on the same line?
Note: this question does not answer how to do what I am asking: how-do-i-best-silence-a-warning-about-unused-variables since it does not cover how to use it within the function prototype in a way that works with both MSVS and gcc.
If a variable or function-argument is potentially unused, gcc's __attribute__((unused)) is designed to suppress any warning about it.
Now, if you want something portable, there are multiple choices:
If you don't use it,
and it's a function-argument, just don't name it.
otherwise, simply don't create it.
If it might be used under some circumstances, simply use it once definitely by casting to void:
(void)potentially_unused;
Yes, the second option is not in the prototype, but one has to make allowances.
Upgrade to C++17 and use [[maybe_unused]].
If your usage is only
void test_fn(int UNUSED(test_var)) {...}
I know that I can remove the variable name... but to make it clear I would prefer a macro).
So remove variable name through MACRO:
You can go with
#define UNUSED(x) /*Empty*/

What's a portable way to implement no-op statement in C++?

One in a while there's a need for a no-op statement in C++. For example when implementing assert() which is disabled in non-debug configuration (also see this question):
#ifdef _DEBUG
#define assert(x) if( !x ) { \
ThrowExcepion(__FILE__, __LINE__);\
} else {\
//noop here \
}
#else
#define assert(x) //noop here
#endif
So far I'm under impression that the right way is to use (void)0; for a no-op:
(void)0;
however I suspect that it might trigger warnings on some compilers - something like C4555: expression has no effect; expected expression with side-effect Visual C++ warning that is not emitted for this particular case but is emitted when there's no cast to void.
Is it universally portable? Is there a better way?
The simplest no-op is just having no code at all:
#define noop
Then user code will have:
if (condition) noop; else do_something();
The alternative that you mention is also a no-op: (void)0;, but if you are going to use that inside a macro, you should leave the ; aside for the caller to add:
#define noop (void)0
if (condition) noop; else do_something();
(If ; was part of the macro, then there would be an extra ; there)
I suspect that it might trigger warnings on some compilers
Unlikely, since ((void)0) is what the standard assert macro expands to when NDEBUG is defined. So any compiler that issues warnings for it will issue warnings whenever code that contains asserts is compiled for release. I expect that would be considered a bug by the users.
I suppose a compiler could avoid that problem by warning for your proposal (void)0 while treating only ((void)0) specially. So you might be better off using ((void)0), but I doubt it.
In general, casting something to void, with or without the extra enclosing parens, idiomatically means "ignore this". For example in C code that casts function parameters to void in order to suppress warnings for unused variables. So on that score too, a compiler that warned would be rather unpopular, since suppressing one warning would just give you another one.
Note that in C++, standard headers are permitted to include each other. Therefore, if you are using any standard header, assert might have been defined by that. So your code is non-portable on that account. If you're talking "universally portable", you normally should treat any macro defined in any standard header as a reserved identifier. You could undefine it, but using a different name for your own assertions would be more sensible. I know it's only an example, but I don't see why you'd ever want to define assert in a "universally portable" way, since all C++ implementations already have it, and it doesn't do what you're defining it to do here.
How about do { } while(0)? Yes it adds code, but I'm sure most compilers today are capable of optimizing it away.
; is considered as standard no-op. Note that it is possible that the compiler will not generate any code from it.
I think the objective here, and the reason not to define the macro to nothing, is to require the user to add a ;. For that purpose, anywhere a statement is legal, (void)0 (or ((void)0), or other variations thereupon) is fine.
I found this question because I needed to do the same thing at global scope, where a plain old statement is illegal. Fortunately, C++11 gives us an alternative: static_assert(true, "NO OP"). This can be used anywhere, and accomplishes my objective of requiring a ; after the macro. (In my case, the macro is a tag for a code generation tool that parses the source file, so when compiling the code as C++, it will always be a NO-OP.)
I'm rather late to the party on this one but I needed the same for a loop() in an Arduino project where all processing is done in timer interrupt service routines (ISR). Found the inline assembler code worked for me without defining a function:
void loop(){
__asm__("nop\n\t"); // Do nothing.
}
I recommend using:
static_cast<void> (0)
And what about:
#define NOP() ({(void)0;})
or just
#define NOP() ({;})
AFAIK, it is universally portable.
#define MYDEFINE()
will do as well.
Another option may be something like this:
void noop(...) {}
#define MYDEFINE() noop()
However, I'd stick to (void)0 or use intrinsics like __noop
inline void noop( ) {}
Self-documenting
this code will not omitted by optimization
static void nop_func() { }
typedef void (*nop_func_t)();
static nop_func_t nop = &nop_func;
for (...)
{
nop();
}
There are many ways, and here is the comparison I've made to some of them in MSVS2019 cpp compiler.
__asm {
nop
}
Transaltes to nop operation in disassembly which takes 1 machine cycle.
do {} while (0); generates some instructions which generates some more cycles.
Simple ; generates nothing.

Universally compiler independent way of implementing an UNUSED macro in C/C++

When implementing stubs etc. you want to avoid "unused variable" warnings. I've come across a few alternatives of UNUSED() macros over the years, but never one which either is proven to work for "all" compilers, or one which by standard is air tight.
Or are we stuck with #ifdef blocks for each build platform?
EDIT: Due to a number of answers with non c-compliant alternatives, I'd like to clarify that I'm looking for a definition which is valid for both C and C++, all flavours etc.
According to this answer by user GMan the typical way is to cast to void:
#define UNUSED(x) (void)(x)
but if x is marked as volatile that would enforce reading from the variable and thus have a side effect and so the actual way to almost guarantee a no-op and suppress the compiler warning is the following:
// use expression as sub-expression,
// then make type of full expression int, discard result
#define UNUSED(x) (void)(sizeof((x), 0))
In C++, just comment out the names.
void MyFunction(int /* name_of_arg1 */, float /* name_of_arg2*/)
{
...
}
The universal way is not to turn on warnings options that spam warnings for clearly-correct code. Any "unused variable" warning option that includes function arguments in its analysis is simply wrong and should be left off. Don't litter your code with ugliness to quiet broken compilers.
You might also try sending a bug report to the compiler maintainer/vendor.

__attribute__((format(printf, 1, 2))) for MSVC?

With GCC, I can specify __attribute__((format(printf, 1, 2))) , telling the compiler that this function takes vararg parameters that are printf format specifiers.
This is very helpful in the cases where I wrap e.g. the vsprintf function family. I can have
extern void log_error(const char *format, ...) __attribute__((format(printf, 1, 2)));
And whenever I call this function, gcc will check that the types and number of arguments conform to the given format specifiers as it would for printf, and issue a warning if not.
Does the Microsoft C/C++ compiler have anything similar ?
Using SAL Annotations you can use _Printf_format_string_ (as of VS2k8 or VS2k10) or __format_string (for VS2k5):
#undef FORMAT_STRING
#if _MSC_VER >= 1400
# include <sal.h>
# if _MSC_VER > 1400
# define FORMAT_STRING(p) _Printf_format_string_ p
# else
# define FORMAT_STRING(p) __format_string p
# endif /* FORMAT_STRING */
#else
# define FORMAT_STRING(p) p
#endif /* _MSC_VER */
/* use /analyze or _USE_ATTRIBUTES_FOR_SAL for checking */
extern void log_error(FORMAT_STRING(const char* format), ...);
As previously mentioned by #RustyX printf format checking is now supported by default as of VC2015. That is without a /analyze static analysis pass. Regrettably there is not yet a mechanism for marking user-defined wrapper functions.
This suggest the obvious workaround of calling printf. That is defining a macro which invokes both the user-defined function as well as the printf itself. The latter on a dead path to be optimized out.
This has the added benefit of achieving some level of portability to other compilers.
int printf_wrapper_(const char *format, ...);
#define printf_wrapper(...) \
(printf || printf(__VA_ARGS__), printf_wrapper_(__VA_ARGS__))
The drawback is that VC2015 performs some rudimentary dead-code elimination prior to the format check, testing only the remaining live code.
Thus sizeof or constant conditional expressions will fail. As a rule of thumb if a debug build emits run-time code then you will get the warning, though later passes in release builds may still kill the call.
Alas this makes it something of a moving target liable to change in future compiler versions. Albeit a relatively benign one.
While GCC checks format specifiers when -Wformat is enabled, VC++ has no such checking, even for standard functions so there is no equivalent to this __attribute__ because there is no equivalent to -Wformat.
I think Microsoft's emphasis on C++ (evidenced by maintaining ISO compliance for C++ while only supporting C89) may be in part the reason why VC++ does not have format specifier checking; in C++ using <iostream> format specifiers are unnecessary.
There is an interesting article on the subject on Code Project:
"Using C++ Templates for Startup Validation"
by Alexander Gorobets
http://www.codeproject.com/KB/cpp/ValidateprintfFunction.aspx
I've modified it so that I have a macro PRINTF_VALIDATE(format, ...) that logs all format errors at program statup (there's no need to actually execute the code). It produces something like this:
test.cpp(147) : error : 'printf' format character 'f' at position 1 does not match parameter type INT
test.cpp(147) : error : 'printf' too many arguments (3 instead of 2)
One can use it for example like this:
#define LOG(fmt, ...) do { PRINTF_VALIDATE(fmt, __VA_ARGS__); WriteLog(fmt, __VA_ARGS__); } while(0)
This is not as useful as compiler support, but it works on Visual Studio 2005...
Workaround for MSVS, GCC and clang:
"If you’re using a macro to call your printf-like functions, you can use a helper-macro to get compile time format checks like this:
#define CHECK_FORMAT(...) \
do { \
char const dummy = sizeof(printf(__VA_ARGS__)); \
(void)dummy; \
} while (false)
#define MY_FMT(...) \
do { \
CHECK_FORMAT(__VA_ARGS__); \
MyFormatFunc(__FILE__, __LINE__, __VA_ARGS__); \
} while (false)
https://godbolt.org/z/38PaG5fx6
The printf call in the sizeof isn’t evaluated so it doesn’t generate code, but current versions of MSVC, GCC and Clang will still do the format-string check so you get the warning. The local dummy variable is also optimized away with -O2."
Source

is there a way to write macros with a variable argument list in visual C++?

As far as I know, in gcc you can write something like:
#define DBGPRINT(fmt...) printf(fmt);
Is there a way to do that in VC++?
Yes but only since VC++ 2005. The syntax for your example would be:
#define DBGPRINT(fmt, ...) printf(fmt, __VA_ARGS__)
A full reference is here.
Yes, you can do this in Visual Studio C++ in versions 2005 and beyond (not sure about VS 2003). Take a look at VA_ARGS. You can basically do something like this:
#define DBGPRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
and the variable arguments to the macro will get passed to the function provided as '...' args, where you can then us va_args to parse them out.
There can be weird behavior with VA_ARGS and the use of macros. Because VA_ARGS is variable, that means that there can be 0 arguments. That might leave you with trailing commas where you didn't intend.
If you do not want to use non-standard extensions, you've to provide extra brackets:
#define DBGPRINT(args) printf(args);
DBGPRINT(("%s\n", "Hello World"));
What you're looking for are called [variadic macros](http://msdn.microsoft.com/en-us/library/ms177415(VS.80).aspx).
Summary of the link: yes, from VC++ 2005 on up.
If you don't actually need any of the features of macros (__FILE__, __LINE__, token-pasting, etc.) you may want to consider writing a variadic function using stdargs.h. Instead of calling printf(), a variadic function can call vprintf() in order to pass along variable argument lists.
For MSVC 7.1 (.NET 2003), this works:
#if defined(DETAILED_DEBUG)
#define DBGPRINT fprintf
#else
__forceinline void __DBGPRINT(...){}
#define DBGPRINT __DBGPRINT
#endif
The following should work. (See link to Variadic macros)
(Example below shows a fixed and variable arguments.)
# define DBGPRINTF(fmt,...) \
do { \
printf(fmt, __VA_ARGS__); \
} while(0)
Search for "VA_ARGS" and va_list in MSDN!
Almost. It's uglier than that though (and you probably don't want a trailing semi-colon in the macro itself:
#define DBGPRINT(DBGPRINT_ARGS) printf DBGPRINT_ARGS // note: do not use '(' & ')'
To use it:
DBGPRINT(("%s\n", "Hello World"));
(was missing a pair of parens).
Not sure why all the negatives, the original question didn't state a version of VC++, and variadic macros aren't supported by all compilers.