generic-print icon indicating copy to clipboard operation
generic-print copied to clipboard

It's not compatible with the Microsoft C compiler

Open StephenWassell opened this issue 3 years ago • 4 comments

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'

StephenWassell avatar Feb 24 '21 10:02 StephenWassell

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.

exebook avatar Feb 24 '21 14:02 exebook

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.

quantumsheep avatar Feb 25 '21 17:02 quantumsheep

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.

stefanos82 avatar Feb 26 '21 01:02 stefanos82

I think this repo could become completely C standard compliant through usage of _Generic from C11. Pretty much every major compiler nowadays support C11.

TotallyNotChase avatar May 27 '21 08:05 TotallyNotChase