为msvc或替代解决方法模拟__typeof__的最佳方法是什么?

我有一些代码

#define DEBUG_PRINT(x,...) \ do \ {\ _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wunused-value\"") \ __typeof__((0,x)) _x = x; \ _Pragma("GCC diagnostic pop") \ DEBUG_PRINT_PTR((#x), &_x, __VA_ARGS__);\ } while(0) //The repetition of debug_print_printf_specifier is to avoid repetition for custom types. #define DEBUG_PRINT_PTR(xstr, xp,...) \ _Generic((*xp), \ const char *: debug_print_printf_specifier(xstr, (void *)xp, TYPE_PTR_TO_PRINTF_SPECIFIER(xp), __FILE__, __LINE__, _my_func__, debug_print_options_apply_group_options(&((debug_print_options){__VA_ARGS__}))),\ char *: debug_print_printf_specifier(xstr, (void *)xp, TYPE_PTR_TO_PRINTF_SPECIFIER(xp), __FILE__, __LINE__, _my_func__, debug_print_options_apply_group_options(&((debug_print_options){__VA_ARGS__}))),\ int: debug_print_printf_specifier(xstr, (void *)xp, TYPE_PTR_TO_PRINTF_SPECIFIER(xp), __FILE__, __LINE__, _my_func__, debug_print_options_apply_group_options(&((debug_print_options){__VA_ARGS__}))),\ float: debug_print_printf_specifier(xstr, (void *)xp, TYPE_PTR_TO_PRINTF_SPECIFIER(xp), __FILE__, __LINE__, _my_func__, debug_print_options_apply_group_options(&((debug_print_options){__VA_ARGS__}))),\ double: debug_print_printf_specifier(xstr, (void *)xp, TYPE_PTR_TO_PRINTF_SPECIFIER(xp), __FILE__, __LINE__, _my_func__, debug_print_options_apply_group_options(&((debug_print_options){__VA_ARGS__}))),\ char: debug_print_printf_specifier(xstr, (void *)xp, TYPE_PTR_TO_PRINTF_SPECIFIER(xp), __FILE__, __LINE__, _my_func__, debug_print_options_apply_group_options(&((debug_print_options){__VA_ARGS__}))),\ int16_t: debug_print_printf_specifier(xstr, (void *)xp, TYPE_PTR_TO_PRINTF_SPECIFIER(xp), __FILE__, __LINE__, _my_func__, debug_print_options_apply_group_options(&((debug_print_options){__VA_ARGS__}))),\ uint16_t: debug_print_printf_specifier(xstr, (void *)xp, TYPE_PTR_TO_PRINTF_SPECIFIER(xp), __FILE__, __LINE__, _my_func__, debug_print_options_apply_group_options(&((debug_print_options){__VA_ARGS__}))),\ uint32_t: debug_print_printf_specifier(xstr, (void *)xp, TYPE_PTR_TO_PRINTF_SPECIFIER(xp), __FILE__, __LINE__, _my_func__, debug_print_options_apply_group_options(&((debug_print_options){__VA_ARGS__}))),\ int64_t: debug_print_printf_specifier(xstr, (void *)xp, TYPE_PTR_TO_PRINTF_SPECIFIER(xp), __FILE__, __LINE__, _my_func__, debug_print_options_apply_group_options(&((debug_print_options){__VA_ARGS__}))),\ uint64_t: debug_print_printf_specifier(xstr, (void *)xp, TYPE_PTR_TO_PRINTF_SPECIFIER(xp), __FILE__, __LINE__, _my_func__, debug_print_options_apply_group_options(&((debug_print_options){__VA_ARGS__}))),\ default: DEBUG_PRINT_CUSTOM_TYPE(xstr, xp, __VA_ARGS__)) #define DEBUG_PRINT_CUSTOM_TYPE(xstr, xp,...) \ debug_print_custom_to_debug_string(xstr, xp, &((dsc_func_ptr){GET_CREATE_DEBUG_STRING_FUNC(xp)}), __FILE__, __LINE__, _my_func__,\ debug_print_options_apply_group_options(&((debug_print_options){__VA_ARGS__}))) #define GET_CREATE_DEBUG_STRING_FUNC(x) _Generic((x), \ debug_print_options *: debug_print_options_to_debug_string, \ debug_print_group_options *: debug_print_group_options_to_debug_string, \ default: print_not_valid_type_for_debug_print) 

我需要一个指向DEBUG_PRINTx的指针,它可以是变量或表达式。 为了支持表达式,我将它分配给临时表,然后取出它的地址。 对于有限的一组类型,我可以使用_Generic模拟__typeof__但是用户需要在2个位置为自定义类型添加行。 有没有其他方法可以做到这一点? 我只能支持最新的Microsoft C编译器。

这取决于您编写代码的方式。 如果你实际上使用的是Visual Studio的C模式(即/Tc或编译带.c扩展名的文件,这意味着/Tc ),并且你不能使用C ++模式(例如代码在标题中),那么你是运气不好,因为MSVC不支持C11(因此你甚至不能使用_Generic来模拟它)。

但是,如果您正在使用C ++模式进行编译(或者您可以采用这种奢侈品),那么您可以利用decltype作为@MooingDuck建议(在最新版本的Visual Studio中,例如2017):

 #include  #ifdef __cplusplus # define TEMPORARY(x) decltype((x)) _x = (x); #else # define TEMPORARY(x) __typeof__((x)) _x = (x); #endif #define DEBUG_PRINT(x) \ do { \ TEMPORARY(x); \ printf("%s = %p\n", #x, &_x); \ } while(0) void f() { int y = 100; DEBUG_PRINT(123); DEBUG_PRINT(y + 123); } 

看一下gcc 7.3( -std=c99 -Wall -Wextra )和MSVC 2017( /std:c++14 /W4 )的生成代码,它们看起来都很好并且等价: https : //godbolt.org/克/ sdWAv7

 char: debug_print_printf_specifier("x"//z.str, (void *)xp, \ TYPE_PTR_TO_PRINTF_SPECIFIER(xp), __FILE__, __LINE__, _my_func__, \ debug_print_options_apply_group_options(&((debug_print_options{__VA_ARGS__}))),\ z=ptr.x //just create a ptr z for x... :D 

就那么简单 .. ;)