2012-12-14 72 views
2
gcc (GCC) 4.7.2 
c89 

你好,函数宏与宏

我一直在寻找一个测试套件,我注意到这个函数宏声明如下:

#define MU_SUITE_START() char *msg = NULL 

然而,没有任何真正的区别在做只是这个:

#define MU_SUITE_START char *msg = NULL 

宏只是做文本替换,所以我不认为有将是任何性能问题。

使用CPP,我得到以下结果,因此这里没有什么特别。

函数宏

char *msg = __null; 

马尔科

char *msg = __null; 

只是一个侧面说明:是不是值得声明函数样的马可,不输入参数提供? 在这里我不传递任何参数 即

#define PRINT_MSG() printf("This is the message\n") 

为什么用函数宏打扰,如果没有输入参数,是不是这更好的?

#define PRINT_MSG printf("This is the message\n") 

非常感谢您的任何建议,

+4

部分是可读性。如果它要表现得像一个函数,为什么不使它看起来像一个呢? – Mysticial

+0

如果你要有一个类似于函数的宏,那么*请*将它包装在一个'do-while(false)'中,所以我不能这样做:'unsigned MU_SUITE_START()+ 10000;'实际上等待,在这里不起作用。更好的建议:不要使用宏。 – Pubby

回答

5

有对象类和函数宏之间的一个区别:

#define OBJECT  char *msg1 = NULL 
#define FUNCTION() char *msg2 = NULL 

void somefunc(void) 
{ 
    int OBJECT = 5; 
    int FUNCTION = 10; 
    ... 
} 

OBJECT声明由宏替换(所以代码不会编译),但对FUNCTION的引用不是宏调用,因为它后面没有左括号。

这是很少重要。但是,当它是真的很重要。

一个更典型的情况可能是,可以实现为宏的功能。为了讨论的缘故(因为它是很容易理解,而不是因为它是一个很好的例子):

extern int isdigit(int c); 
#define isdigit(c) ((c) >= '0' && (c) <= '9') 

,并在实现文件:

int (isdigit)(int c) 
{ 
    assert((c >= 0 && c <= UCHAR_MAX) || c == EOF); 
    return isdigit(c); 
} 

忽略这样的小细节也不怎么isdigit()很可能会实现,并isdigit()宏实现不允许评估其参数不止一次了,你不应该重新定义的东西都是在标准C库函数定义不是宏,因为扩展名isdigit后面跟着(,但函数内部的宏被扩展了。至少该函数在宏,这几乎保证了相同的行为的条款执行。它

+1

我忽略了一些东西,还是你对'OBJECT'和'FUNCTION'的定义完全一样? – Mysticial

+0

我错过了一对括号......谢谢! –