关于宏函数的定义

以前一直以为宏的定义挺简单的,没有写过长的宏函数,最常用的是MAX()的定义,今天写一个宏函数的时候,相对于MAX()来说,稍微有点长,然后踩了一个小坑。

一开始将宏函数定义的时候,为了书写方便,将一个函数写成了几行,但是没有用连接符号连接起来,类似于下面

1 #define CHECK(ret) ({
2                  int ret;
3                  ...
4 })

GCC总是提示ret不在范围内。想了半天没有明白怎么回事。

然后我发现了一个问题。

我的VIM定义宏函数时,#define那一行是显示的蓝色,但是我的 int ret,以及下面的都是普通的白色,然后我查看了我以前的代码,发现我的宏定义VIM显示的都是蓝色。

我马上想到的是我的下面定义的 int ret往下都没有包括进宏里面,这个宏,定义的是 CHECK(ret)  ==  ({ ; 下面空出来的都是在main函数以外,这个当然会报错了,然后我用了连接符号,代码如下

1 #define CHECK(ret) ({  2                 int ret;
3 })

OK!!!

VIM中代码全是蓝色了,这样就识别了整个宏了。

细细想一下,宏的定义是怎么结束的,宏的结尾是没有分号的,那么推断宏是通过回车来结束的,也就是整个一行都是宏,所以当宏很长时,就要用到连接符来连接了。

这样这个推断也由上面的错误证明了。

这个坑不大,但是它也从侧面说明了,写程序,是个细心的活儿。这种小问题,以后就不要再犯了吧!

还有一点,连接符后面是不能有空格的,GCC会出现警告:

warning: backslash and newline separated by space

来自IBM网站上的解释是:

Solution: The backslash (\) character is used as the continuation character to continue #define statements and strings to the next line. GCC expects the backslash character to be the very last character on the line. This warning indicates that there is a space after the backslash. Delete the space and any other characters that come after the backslash.

时间: 2024-10-17 08:03:33

关于宏函数的定义的相关文章

宏函数定义继承类

//: ORDER.CPP -- Order of constructor calls // with inheritance #include <iostream.h> #define inherit(derived, base) class derived : public base { public: derived() { cout << #derived << endl; } }; class X {}; inherit(A, X) inherit(B, A)

#define定义宏函数 的正确使用

如何使用宏来定义一个自定义函数呢?首先我们来看下面这段代码 #define SQUARE(x) x*x int main() { int a = 5; printf("SQUARE(a): %d\n",SQUARE(a)); //这个值为25 printf("SQUARE(a+1): %d\n", SQUARE(a + 1)); //第一反应是打印36,其实打印的是11 } 运行结果:为什么会出现这样的结果呢?原因是编译器在处理SQUARE(a+1)的时候,处理成了

C/C++函数重复定义、头文件重复包含、互相包含问题

1.避免头文件重复包含 // test.h 此段宏的意思是如果定义了宏变量TEST_H_则不再定义它 #ifndef TEST_H_ #define TEST_H_ //头文件内容 #endif 或者 // test.h 告诉预编译器只包含一次 #pragma once 2.避免重复定义 不要将函数定义放置在头文件里面,正确的做法是头文件放置函数声明,源文件放置函数定义.因为源文件是分别编译的,假如头文件放置了函数定义,包含该头文件的每一个源文件都会定义相应的函数,从而导致重复定义.但是几种情况

C语言宏函数参数的连接

#include<stdio.h> #define Calculate_Max(A,B) A>B?A:B #define Calculate_Min(A,B) A<B?A:B #define Calculate(A,B,NAME) Calculate_##NAME(A,B) int main(void) {         printf("%d\n",Calculate(5,8,Max));         return 0; } 使用宏函数或者宏函数时,注意如

深入理解PHP内核(六)函数的定义、传参及返回值

一.函数的定义 用户函数的定义从function 关键字开始,如下 function foo($var) { echo $var; } 1.词法分析 在Zend/zend_language_scanner.l中我们找到如下所示的代码: <ST_IN_SCRIPTING>"function" { return T_FUNCTION; } 它所表示的含义是function将会生成T_FUNCTION标记.在获取这个标记后,我们开始语法分析. 2.语法分析 在Zend/zend_

1013-----C语言----------几个va_宏函数的使用

最近在看APUE附带的源码时,看到它的错误处理文件中用到了可变参数列表(如下),正好最近老是看到这几个函数在眼前晃悠,所以就做个了断吧.哈哈. #include "apue.h" #include <errno.h> /* for definition of errno */ #include <stdarg.h> /* ISO C variable aruments */ static void err_doit(int, int, const char *,

可读性很强的C语言的函数指针定义

通常C/C++程序里面要用到大量的指针,其语法非常难以阅读.比如下面的vp指针类型: #include <iostream> using namespace std; typedef void (*vp) (float&,float&); void foo(float &a,float &b) { a = a + b; } int main() { // float a=1; float b=2; vp t=&foo; t(a,b); cout <

宏函数的写法

宏函数有执行较快,但占用代码长度较大,且不易调试的特点 对于运算型的宏函数,可以写成 #define f(a,b) ((a)+(b)) 宏函数中所有的参数都应该加小括号保证a,b先运算完毕,宏函数的最外面应该再加一层小括号保证宏函数整体运算 对于复杂的,需要调用其他函数的宏函数,则应该使用大括号把他们包在一起,避免如if之类的语句,只执行到第一句. #define F(a,b) { \ f(a); g(b); } 其中反斜线是为了满足宏函数定义在一行内的要求. 但这边又出现另外一个问题,对于一些

IOS学习之路-- 指针&amp;宏函数

如果*p被()包住,说明指针变量p将来指向的是函数 //声明一个指针变量 //int (*p)(int, int) = sum; int (*p)(int, int); p = sum; // 如果*p被()包住,说明指针变量p将来指向的是函数 // 最左边的void说明p指向的函数没有返回值 // 最右边的()说明p指向的函数没有形参 void (*p)(); // 函数名test就是test函数的地址 // 将test函数的地址赋值给了指针变量p // 指针变量p成功指向了test函数 p