宏的几种特殊用法

1. 屏蔽“未使用参数”警告

在OceanBase中ob_define.h中就使用了这种宏,将传入的数据强制转化为void型。

   #ifndef UNUSED
    #define UNUSED(v) ((void)(v))
    #endif

这种宏主要是为了屏蔽“未使用参数”的警告,如下面这个函数用两个参数,但是一个都不用的话,某些编译器就会报出警告:认为p和mod_id都没有使用。所有我们使用UNUSE宏,这样两个参数都被使用了,但是实际上没有做任何有效的动作,以此来屏蔽“未使用参数”警告。

 virtual void mod_free(void* p, const int32_t mod_id = 0)
 {
    UNUSED(p);
    UNUSED(mod_id);
 }

2. 指定字节对齐

在缺省情况下,编译器为每一个变量或是数据单元按其自然对界条件分配空间。一般地,可以通过下面的方法来改变缺省的对界条件:
1) 使用伪指令#pragma pack (n),编译器将按照n个字节对齐。
2) 使用伪指令#pragma pack (),取消自定义字节对齐方式。
另外,还有如下的一种方式:
3) __attribute__((aligned (n))),让所作用的结构成员对齐在n字节自然边界上。如果结构中有成员的长度大于n,则按照最大成员的长度来对齐。
4) __attribute__ ((packed)),取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐。
以上的n = 1, 2, 4, 8, 16... 第一种方式较为常见。

#define CACHE_ALIGNED __attribute__((aligned(CACHE_ALIGN_SIZE)))

3. 可变参数宏

我们指定,有些函数的参数是可变的,例如printf函数,指定第一个为格式化字符串以后,后面可以跟个数不定的参数,同样,宏也可以指定多个参数。有两种方法可以做到。
一是使用args...##args,二是使用...__VA_ARGS__。下面是两种方式定义的两个宏,这两个宏都能在printf字符串前,先输出一个字符串,达到相同的效果。

#define P_Debug(format,args...) \
{\
    printf("[DeBug]");\
    printf(format,##args);\
}while(false)
#define P_Release(format,...) \do{\
    printf("[Release]");\
    printf(format,__VA_ARGS__);\
}while(false)

使用的时候为:

P_Debug("%s:%d\n","good",100);
P_Release("%s:%d\n","good",100);

4. ###,#@的区别

假设定义3个宏,

#define A(x) T_##x
#define B(x) #@x
#define C(x) #x

则下面展开后为
A(1)------>T_1
B(1)------>'1'
C(1)------>"1"



欢迎光临我的网站----蝴蝶忽然的博客园----人既无名的专栏
如果阅读本文过程中有任何问题,请联系作者,转载请注明出处!

时间: 2024-08-19 11:05:26

宏的几种特殊用法的相关文章

C#数据库操作的三种经典用法

由于最近和数据库打交道,需要用C#和SQL Server 2005进行操作,就把近段时间内的最常用的操作做个总结.本人也是第一次用C#操作数据库,所以这三种典型用法对初学者还是挺有帮助的. 以下是我在visual studio 2005上写的一个类(连的是SQL Server 2005),已经过测试通过.里面有3个方法比较典型,源码如下: using System; using System.Collections.Generic; using System.Text; using System

Java枚举的七种常见用法总结(必看)_java

用法一:常量 在JDK1.5之前,我们定义常量都是:publicstaticfianl.....现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. Java代码 public enum Color { RED, GREEN, BLANK, YELLOW } 用法二:switch JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强. Java代码 enum Signal { GREEN, YELLOW,

java两种单例模式用法分析_java

本文实例讲述了java两种单例模式用法.分享给大家供大家参考,具体如下: 按照加载方式的不同,单例模式有两种实现: private:只能在同一个类中使用 static:该类是类方法,不能调用实例方法./类全局变量 final:方法或成员变量不能被修饰 1.饿汉式 public class EagerSigleton{ private static final EagerSigleton instance=new EagerSigleton(); private EagerSigleton(){}

PHP中for循环语句的几种“变态”用法

循环|语句     for语句可以说是PHP(同时也是多种语言)的循环控制部份最基本的一个语句了,for语句的执行规律和基础用法在这里就不多说,可以参见PHP手册for语句部分.PHP手册中对它的语法定义如下: for (expr1; expr2; expr3)statement 下面说说for语句几种有用的变型. 1.无限循环 首先是人尽皆知的无限循环(亦可称"死循环").由于空表达式null在语法上是有效的,所以我们可以把for语句的三个表达式留空,这样就会产生不断执行for嵌套语

sumif函数的几种常见用法

  一.SUMIF函数的一个怪异用途 Excel表格中的SUMIF函数在条件求和时经常使用,一般习惯于于根据某一列计算另一列的数字之和. 例1:假设置A列是部门,B列是姓名,C列是工资,可以用下面的公式算出所有财务部员工的工资总和: =SUM(A1:A100,"财务部",C1:C100) 今天说的不是这个正规用法,而是给大家介绍一种看上去和SUMIF毫无关系的例子. 如下图中,是一些不规则的数据,只关注填充颜色的区域,现在要计算所有A下面数字之和,看上去这个题没有好的思路,其实这个题恰

python中星号变量的几种特殊用法_python

一.什么是星号变量 最初,星号变量是用在函数的参数传递上的,在下面的实例中,单个星号代表这个位置接收任意多个非关键字参数,在函数的*b位置上将其转化成元组,而双星号代表这个位置接收任意多个关键字参数,在**b位置上将其转化成字典: #!/usr/bin/env python #coding=utf-8 #-------- def one(a,*b): """a是一个普通传入参数,*b是一个非关键字星号参数""" print(b) one(1,2,

维基解密揭秘CIA五种恶意软件用法

维基解密已发布美国中央情报局(CIA)大量数据,最近的一批,揭露了CIA是怎么用其5种不同恶意软件,针对毫无防备的用户的. 这些恶意软件分别为:HammerLoss.Regin.HTTPBrowser.NfLog和Gamker.发布的文档中还揭示,CIA与雷神黑鸟科技公司签约,雇其作为CIA旗下远程开发部门 (RDB)的承包商. 来自朱利安·阿桑奇的揭秘噩梦尚未结束,Vault 7 之后最新披露的文档,又揭开了CIA令人震惊的目标攻击和渗透能力.本次公布的数据,包含来自专家的5份报告,详细描述了

Inurl命令的几种高级用法总结

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 作为站长而言,经常需要收集一些特定程序开发的网站以作为推广和借鉴经验的资源,利用搜索引擎的inurl命令可以让我们更快的找到我们需要的资源.这个命令对新手而言可能还比较陌生,我们可以到百度的高级搜索页面http://www.baidu.com/gaoji/advanced.html看一下,可以看到我们在搜索的时候选中只在网站url里搜索,并把

RabbitMQ:四种ExChange用法

RabbitMQ发送消息时,都是先把消息发送给ExChange(交换机),然后再分发给有相应RoutingKey(路由)关系的Queue(队列). ExChange和Queue之前是多对多的关系. RabbitMQ 3.0之后创建ExChange时,有四种类型可选"fanout.direct.topic.headers". 一.fanout 当向一个fanout发送一个消息时,RoutingKey的设置不起作用. 消息会被发送给同一个交换机下的所有队列,每个队列接收到的消息是一样的: