Linux内核中常用的C语言技巧

1.语句表达式

例如常用的宏定义
#define max(a,b) ((a)>(b)?(a):(b))
相信上面的代码大家都用到过吧,但是上述代码会引发安全问题,a和b的值会被计算两次,比如就是a传入i++,b传入j++的时候。
例如下面的代码:

#include<iostream>
#define max(a,b) ( (a) >(b) ? (a) : (b) )
using namespace std;
int main()
{
	int i = 0, j = 0;
	cout << max(i++,j++) << endl;
	cout << "i= " << i << "    " << "j= " << j << endl;
	return 0;
}

在vs2019中运行的结果为1,运行后i的值为1,j的值为2.这明显不是我们所希望看到的。

但是如果我们知道变量a与b的类型的话,我们可以这样写这个宏

#define maxint(a,b)\
	({int _a=(a),_b=(b);_a>_b?_a:_b;})

这样写就不会出现上述问题,但是我们就比如知道a与b的类型,那有没有更好的方法实现这个宏呢,答案当然是有的,我们可以使用typeof类转换宏。
typeof是GNU C语言的一个扩充手法,可以用来构造新的类型,通常和语句表达式一起使用。

<include / linux / kernel.h>
#define min(x,y) ({					\
	typeof(x) _min1 = (x);			\
	typeof(y) _min2 = (y);			\
	(void) (&_min1 == &_min2);		\
	_min1 < _min2 ? _min1 : _min2;})

这就是一个泛型宏。使用了GCC的扩展支持命令typeof() 。一共四行代码,其他都很明了,唯独第三行让人有点摸不着头脑。我第一反应这是为了防止编译器优化代码结构而添加的语句。但是回头想了一下,没有想出理由来。也就没在意了。 今天一个很突然的机会才反应过来这么做的原因:为防止不同类型变量进行比较。

int main(int ac, char** av)

{

           char i = 100;

           long j = 1000;

           long k = min(i, j);

           return 0;

}

编译上述代码时编译器会给出警告:comparison of distinct pointer types lacks a cast 如果去掉(void) (&_min1 == &_min2) 这行,再编译是不会给出警告的。 这群写内核人太TMD牛X了。

那么为什么(void) (&_min1 == &_min2); 会使编译器报出警告呢?这就是指针的类型的问题:

比如:

int main ()
{

    int *p1;
    char *p2;

    int a = 10;
    char b = 20;

    p1 = &a;
    p2 = &b;

  
    p1 == p2;
    return 0;
}

编译上述代码时编译器会给出警告:comparison of distinct pointer types lacks a cast 。“==”是比较的意思。也就是指针的类型不同是不能相互比较的。因为指针p1它指向含有4个字节连续的首地址,而指针p2 它指向含有1个字节的地址。

零长数组

家里电脑不好用,下次再发

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值