generic-print
generic-print copied to clipboard
It's not compatible with the Microsoft C compiler
Just a quick test so you can update the readme:
C:\git\generic-print>cl demo.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.26.28806 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
demo.c
C:\git\generic-print\print.h(166): error C2010: '.': unexpected in macro parameter list
demo.c(5): error C2059: syntax error: 'type'
demo.c(11): error C2059: syntax error: 'type'
demo.c(16): error C2059: syntax error: 'type'
demo.c(21): error C2059: syntax error: 'type'
Already stated this unfortunate fact in the README. Meanwhile anybody knows how to do something like __builtin_choose_expr(__builtin_types_compatible_p(typeof(x), int)....
with Microsoft C compiler aka cl.exe
? Their documentation makes me feel immediately lost.
Seems like __builtin_choose_expr
is available at least since MSVC 19.0.
For __builtin_types_compatible_p
we could use _Generic
like so:
#define __builtin_types_compatible_p(T1, T2) _Generic(T1{}, T2: 1, default: 0)
This solution would need a special case for pointer types.
Or directly:
#define __print_type_expr(x) _Generic(x, \
double: 'd', \
float: 'd', \
char: 'c', \
// And so on...
default: '?'
)
The second option is, in my opinion, better looking, along with the advantage of not requiring a special case for pointers (I think?).
_Generic
is only available in very recent versions of MSVC though.
Even though I'm not a Microsoft guy, let alone a Visual C++ compiler user, I can see from https://en.wikipedia.org/wiki/C99#Implementations that they have partially implemented the standard which means such feature (typeof
) is not implemented as an extension much like GCC or Clang; but the good thing is that it's being currently discussed as part of committee to make it a standard keyword.
Time will tell though...
For now my suggestion would be to check the version of the MSVC++ and test it which C++ version it supports.
If it supports C++11, then use decltype
in place of typeof
, which by the way I'm repeating myself once again, is a GCC / Clang extension widely used either in the form of __typeof__()
or __typeof()
; it is not a standard language keyword.
Here's a template to use with your macro:
/*
** Since you want to use typeof and GCC and Clang
** support it as an extension, try something like
**
** #if defined(__GNUC__) || defined(__clang__)
** ...
** #endif
*/
#ifdef __clang__
/*code specific to clang compiler*/
#elif __GNUC__
/*code for GNU C compiler */
#elif _MSC_VER
/*usually has the version number in _MSC_VER*/
/*code specific to MSVC compiler*/
#elif __BORLANDC__
/*code specific to borland compilers*/
#elif __MINGW32__
/*code specific to mingw compilers*/
#endif
Also please bear in mind that __builtin_
prefixed functions are used as compiler builtin extensions in GCC and as language extensions in Clang.
I think this repo could become completely C standard compliant through usage of _Generic
from C11. Pretty much every major compiler nowadays support C11.