我有一些code
#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)
我需要指向x
中DEBUG_PRINT
的指针,该指针可能是变量或表达式。为了支持表达式,我将它分配给一个临时表,然后取出它的地址。对于有限的一组类型,我可以使用__typeof__
模拟_Generic
,但是用户需要在2个位置为自定义类型添加行。有没有其他方法可以做到这一点?我只能支持最新的Microsoft C编译器。
答案 0 :(得分:1)
这取决于您编写代码的方式。如果您实际使用的是Visual Studio的C模式(即/Tc
或编译带有.c
扩展名的文件,这意味着/Tc
),并且您无法使用C ++模式(例如代码在标题中),那么你运气不好,因为MSVC不支持C11(因此你甚至不能使用_Generic
来模拟它。)
但是,如果您正在使用C ++模式进行编译(或者您可以享受这种奢侈),那么您可以利用decltype
作为@MooingDuck建议(在最新版本的Visual Studio中,例如2017):
#include <stdio.h>
#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/g/sdWAv7
答案 1 :(得分:-6)
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
这简单..;)