27

我有一些代码

#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)

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

4

2 回答 2

2

如果您使用的是最新版本的 MSVC,它支持新的 C 标准,因此您可以_Generic在上面使用。

否则,对于旧版本,这取决于您如何编译代码。如果您实际上正在使用 Visual Studio 的 C 模式(即/Tc或编译带有.c扩展名的文件,这意味着/Tc不支持 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);
}

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

于 2018-04-29T02:18:32.423 回答
-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

simple as that .. ;)

于 2015-09-16T09:40:01.480 回答