__attribute__((format(printf, 1, 2))) for MSVC? - c++

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

Related

Assert is seen as C style cast in Visual Studio

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

Hint for branch prediction in assertions

I have a custom ASSERT(...) macro which I use in a C++ application.
#include <stdlib.h>
#include <iostream>
/// ASSERT(expr) checks if expr is true. If not, error details are logged
/// and the process is exited with a non-zero code.
#ifdef INCLUDE_ASSERTIONS
#define ASSERT(expr) \
if (!(expr)) { \
char buf[4096]; \
snprintf (buf, 4096, "Assertion failed in \"%s\", line %d\n%s\n", \
__FILE__, __LINE__, #expr); \
std::cerr << buf; \
::abort(); \
} \
else // This 'else' exists to catch the user's following semicolon
#else
#define ASSERT(expr)
#endif
Recently I was reading some Linux kernel module code and came across the existence of likely(...) and unlikely(...) macros. These provide a hint to the CPU that a given branch is more likely, and that the pipeline should optimise for that path.
Assertions are, by definition, expected to evaluate to true (i.e. likely).
Can I provide a similar hint in my ASSERT macro? What's the underlying mechanism here?
Obviously I will measure for any difference in performance, but in theory should it make any difference?
I only run my code on Linux, but would be interested to know if there's a cross platform way of doing this too. I'm also using gcc, but would like to support clang as well.
The performance gain is not likely to be significant, but this is how those linux kernel macros are defined:
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
So, you could modify your condition like this (assuming that expr is expected to be true and therefore !(expr) is expected to be false):
if (__builtin_expect(!(expr), 0)) {
Or you could define the same macros as the kernel and use them for better readability.
This is gcc builtin, so not portable of course.
This suggests that clang also supports the builtin. Othrwise, you can use the above macros and conditionally define them like #define likely(x) (x) on compilers that don't support the builtin.
In your case, the prediction is going to be good (either that or you're aborting), so there shouldn't be a risk of pessimisation, but if you do consider using the builtin more widely, here's a word of advice from gcc documentation:
In general, you should prefer to use actual profile feedback for this (-fprofile-arcs), as programmers are notoriously bad at predicting how their programs actually perform.
For many CPUs, likely and unlikely (or anything else for that matter) don't provide a branch hint to the CPU (only to the compiler, which may use it to optimize differently, similar to profile guided optimization) for the simple reason that there is no way to do it.
For example, branch hints are defined for x86 since P4. Before that they had no effect, but it's even worse, they have no effect on anything except P4. So they're useless (but waste space and bandwidth), and as far as I know GCC does not emit them.
ARM doesn't (yet?) have branch hints either. PPC, IA64 and SPARC do have hinted branches, I don't know whether GCC uses likely and unlikely for them though, but at least it could.
There is no need for any additional annotation. The compiler already knows about abort being called very rarely (at most once per program execution), and so the compiler will consider the branch containing abort as the unlikely branch anyway. You can verify this by looking at the declaration of abort. In glibc it is declared as
extern void abort (void) __THROW __attribute__ ((__noreturn__));
and in Visual Studio 2013:
_CRTIMP __declspec(noreturn) void __cdecl abort(void);

Is there a static_assert replacement which satisfies the C99 standard?

I have been trying to implement a method similar to static_assert which is defined in the C++11 standard. The main problem is how does the C++ compiler write the text message being passed to static_assert as a const char*? I can get the compiler to write a message like A_is_not_POD. This is what I have:
#define MY_STATIC_ASSERT(condition, name) \
typedef char name[(condition) ? 1 : -1];
But it would be quite nice to get the compiler to write something like "Error: A is not POD." Any suggestions?
Not sure i understand question, but C11 have _Static_assert(condition, errmessage). In C99 this functionality was missing but, depending on compiler, it could be possible to emulate. E.g. for gcc (unfortulately clang doesn't support attribute(error))
#define MY_STATIC_ASSERT(cnd, descr) ({ \
extern int __attribute__ ((error("static assert failed: (" #cnd ") (" #descr ")"))) \
compile_time_check(void); \
((cnd) ? 0 : compile_time_check()), 0; \
})
In the c99 standard there is no "official" way to perform a static assertion in your C++ compiler.
"The main problem is how does the C++ compiler write the text message being passed to static_assert as a const char*?"
The C++ compiler detects an error in the code and prints out an appropriate error message based on a standard list of messages it has for each error that is known it can encounter. In c99, the compiler doesn't know what a "static assert error" is, so you need to cause some other error.
However, because creating static asserts with a c99 compiler is kind of a hack, it is not capable of printing out a nice error message exactly how you want.
For your example,
#define MY_STATIC_ASSERT(condition, name) \
typedef char name[(condition) ? 1 : -1];
MY_STATIC_ASSERT(false, my_error_msg)
will trigger the "error: size of array ‘my_error_msg’ is negative" message in the gcc compiler (and should a similar message in other compilers, you hope!). Giving the array an error message for the name was a way to print out your own info. There are various other techniques/hacks you can do on purpose such as bad templates, enums link
Note: you can provide custom compiler messages prior to C++11 using pre-processor macros such as #error or #pragma. However pre-process time is not the same as compile-time! The the pre-processor has a limited ability to evaluate many expressions and keywords such as "if", "sizeof", "return" and so on have no meaning to the pre-processor, only the compiler. link with some overview

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.

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.