如果从if()块中调用它,则会发出#define问题

时间:2012-10-13 01:11:07

标签: c c-preprocessor

我有功能:foo()

我想写一个#define来放置foo()(我想是一个垫片)的'infront'来将调试添加到foo()的前面。 所以#define看起来应该这样:

   #define foo(dev) {                         \
      printk("%s: get %lx\n", (dev)->name);   \
      foo_orig(dev);                          \
   }

然后我将foo()重命名为foo_orig()

如果在{isolation'中调用foo()函数,则可以正常工作:

   foo(dev);

但是,如果它在if()内被调用,那么它就是编译问题......

   if (something() && foo(dev)) {
     ..

我有没有解释过这个问题?对此有解决方案吗?

问题是我真的需要垫片作为定义,因为我需要代码存在于调用函数而不是foo()。 [原因是因为出于调试原因我需要将EIP转储出调用函数(即我需要知道谁在调用foo()]。

7 个答案:

答案 0 :(得分:2)

AMAIK逗号运算符应该起作用:

#define foo(dev) (printk("%s: get %lx\n", (dev)->name), foo_orig(dev))

答案 1 :(得分:1)

我假设您正在使用GCC,那么这应该有所帮助:

#define foo(dev) ({                           \
      printk("%s: get %lx\n", (dev)->name);   \
      foo_orig(dev);                          \
   })

关键点是花括号周围的括号。

GCC: Statements and Declarations in Expressions

答案 2 :(得分:1)

问题在于#define的工作原理。

在预处理阶段,编译器将用定义的文本替换foo的任何出现。所以,你的代码看起来像这样:

  // call to foo() -> valid
  printk("%s: get %lx\n", (dev)->name);
  foo_orig(dev);    

  // within a parenthesis - invalid 
  if (something() && printk("%s: get %lx\n", (dev)->name);
          foo_orig(dev);) {

一种解决方案是使用真正的函数进行调试,比如

foo_dbg(type *dev) {
   printk("%s: get %lx\n", (dev)->name);
   return foo_orig(dev);
}
#ifdef DEBUG
   #define foo(dev) foo_dbg(dev)
#else
   #define foo(dev) foo_orig(dev)
#endif

答案 3 :(得分:0)

#define就像在进行搜索和替换。所以你的'if'语句在编译时变成了以下内容:

if (something() && { print(....); foo_orig(dev);}) {
}

这应该解释编译器错误。

答案 4 :(得分:0)

使用逗号运算符:

#define foo(dev) (printk(blah, blah), foo_orig(dev))

使用C99,您可以使用内联函数

static inline rtype foo (type *dev) { printk(blah, blah); return foo_orig(dev); }

答案 5 :(得分:0)

也许用逗号;替换#define中的分号,,然后移除大括号/括号{}

或者,在if语句中,将foo(dev)替换为(foo)(dev)

答案 6 :(得分:-1)

  

原因是b / c我出于调试原因需要将EIP转储出调用函数(即我需要知道谁在调用foo()

好吧,你可以写一些程序集来查找堆栈上的返回地址;但实际上,大多数编译器已经内置了解决这一需求的问题;请参阅here了解GCC(对于Clang来说是相同的),here用于VC ++(在英特尔编译器上也是如此)。

只需在真实foo内编写垫片,然后使用_ReturnAddress() / __builtin_return_address(0)获取函数的返回地址(即启动call指令后的一条指令功能)。