【问题标题】:Type overloading macro类型重载宏
【发布时间】:2011-04-12 10:13:19
【问题描述】:

我有一堆 printf 调试辅助宏,不必指定类型会很酷,有没有什么可以做的事情来允许在 c 中进行宏重载(如果它在 gcc 中可用,则可以是 gcc 特定的4.3)。我想也许是 typeof,但显然这不起作用。

示例宏(我也有一些 ascii 终端颜色的东西,我不记得了)

#ifdef _DEBUG
#define DPRINT_INT(x) printf("int %s is equal to %i at line %i",#x,x,__LINE__);
.
.
.
#else
#define DPRINT_INT(x)
.
.
.
#endif

【问题讨论】:

  • 你能举一个你的宏的例子吗?

标签: c macros overloading tostring printf-debugging


【解决方案1】:

试试这个;它使用 gcc 的 __builtin 方法,并尽其所能自动为您确定类型,并提供一个简单的 DEBUG 宏,您不必指定类型。当然,你可以比较 typeof(x) 和 float 等。

#define DEBUG(x)                                                 \
  ({                                                             \
    if (__builtin_types_compatible_p (typeof (x), int))          \
        fprintf(stderr,"%d\n",x);                                \
    else if (__builtin_types_compatible_p (typeof (x), char))    \
        fprintf(stderr,"%c\n",x);                                \
    else if (__builtin_types_compatible_p (typeof (x), char[]))  \
        fprintf(stderr,"%s\n",x);                                \
    else                                                         \
        fprintf(stderr,"unknown type\n");                        \

  })

【讨论】:

  • 是的,这看起来很完美。谢谢,想知道为什么更多人不使用它(运行时开销)?
  • 因为它仅限于 GCC,而且人们可能还希望使用其他编译器编译代码。
  • 运行时开销是无用的 - 无论如何它是用于调试构建,所以这将在常规生产构建期间#define'd。它可能没有被广泛使用,因为它是 gcc 特定的
  • 现在我看到了它,我开始想象如何使用它来做一些安全的类型重载,即使在常规代码中也不需要长名称。至于特定于 gcc 的许多 unix 软件,这些天可能有些特定于 gcc(尽管由于 llvm 可能会发生变化)。
  • 一些,当然,但不是全部,这就是为什么它不会被广泛使用的原因。
【解决方案2】:

下面的宏怎么样?它仍然需要您选择打印格式,但您不必重新定义所有可能的情况,它也适用于 MSVC:

#define DPRINT(t,v) printf("The variable '%s' is equal to '%" ## #t ## "' on line %d.\n",#v,v, __LINE__)

使用它:

int var = 5;
const char *str = "test";
DPRINT(i,var);
DPRINT(s,str);

【讨论】:

  • 谢谢,但我试图避免这种事情。
【解决方案3】:

我想你可以试试下面的代码:

#define DPRINT(fmt) do{ \
            my_printf fmt ; \
        } while(0)

my_printf( const char* szFormat, ... )
{
    char szDbgText[100];

    va_start(args, szFormat);
    vsnprintf(&szDbgText,99,szFormat,args);
    va_end(args);

    fprintf( stderr, "%s", szDbgText );
}
// usage
func( )
{
    int a = 5;
    char *ptr = "hello";

    DPRINT( ("a = %d, ptr = %s\n", a, ptr) );
}

注意:这里的 DPRINT 用法需要双括号。

【讨论】:

  • 你可以让你的宏得到...。这样,您可以避免使用双括号。
猜你喜欢
  • 2012-08-12
  • 1970-01-01
  • 2012-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多