linux里怎么查看linux 宏定义义

博客访问: 20295
博文数量: 10
博客积分: 146
博客等级: 入伍新兵
技术积分: 90
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: C/C++
写好C语言,漂亮的宏定义很重要,使用宏定义可以防止出错,提高可移植性,可读性,方便性 等等.下面列举一些***软件中常用得宏定义...... && 1,防止一个头文件被重复包含 #ifndef COMDEF_H #define COMDEF_H &&//头文件内容 #endif 2,重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植. typedef&&unsigned char&&&&&&&&&& /* Boolean value type. */ && typedef&&unsigned long int&&uint32;&&&&&&/* Unsigned 32 bit value */ typedef&&unsigned short&&&& uint16;&&&&&&/* Unsigned 16 bit value */ typedef&&unsigned char&&&&&&uint8;&&&&&& /* Unsigned 8&&bit value */ && typedef&&signed long int&&&&int32;&&&&&& /* Signed 32 bit value */ typedef&&signed short&&&&&& int16;&&&&&& /* Signed 16 bit value */ typedef&&signed char&&&&&&&&int8;&&&&&&&&/* Signed 8&&bit value */ && && //下面的不建议使用 typedef&&unsigned char&&&&&&&&&&&& /* Unsigned 8&&bit value type. */ typedef&&unsigned short&&&&&&&&&&&& /* Unsinged 16 bit value type. */ typedef&&unsigned long&&&&&&&&&&&&/* Unsigned 32 bit value type. */ && typedef&&unsigned char&&&& uint1;&&&&&&&&/* Unsigned 8&&bit value type. */ typedef&&unsigned short&&&&uint2;&&&&&&&&/* Unsigned 16 bit value type. */ typedef&&unsigned long&&&& uint4;&&&&&&&&/* Unsigned 32 bit value type. */ && typedef&&signed char&&&&&& int1;&&&&&&&& /* Signed 8&&bit value type. */ typedef&&signed short&&&&&&int2;&&&&&&&& /* Signed 16 bit value type. */ typedef&&long int&&&&&&&&&&int4;&&&&&&&& /* Signed 32 bit value type. */ && typedef&&signed long&&&&&& sint31;&&&&&& /* Signed 32 bit value */ typedef&&signed short&&&&&&sint15;&&&&&& /* Signed 16 bit value */ typedef&&signed char&&&&&& sint7;&&&&&&&&/* Signed 8&&bit value */ && 3,得到指定地址上的一个字节或字 #define&&MEM_B( x )&&( *( (byte *) (x) ) ) #define&&MEM_W( x )&&( *( (word *) (x) ) ) 4,求最大值和最小值 && #define&&MAX( x, y ) ( ((x) & (y)) ? (x) : (y) ) && #define&&MIN( x, y ) ( ((x) & (y)) ? (x) : (y) ) 5,得到一个field在结构体(struct)中的偏移量 #define FPOS( type, field ) \ /*lint -e545 */ ( (dword) &(( type *) 0)-& field ) /*lint +e545 */ 6,得到一个结构体中field所占用的字节数 #define FSIZ( type, field ) sizeof( ((type *) 0)-&field ) 7,按照LSB格式把两个字节转化为一个Word #define&&FLIPW( ray ) ( (((word) (ray)[0]) * 256) + (ray)[1] ) 8,按照LSB格式把一个Word转化为两个字节 #define&&FLOPW( ray, val ) \ &&(ray)[0] = ((val) / 256); \ &&(ray)[1] = ((val) & 0xFF) 9,得到一个变量的地址(word宽度) #define&&B_PTR( var )&&( (byte *) (void *) &(var) ) #define&&W_PTR( var )&&( (word *) (void *) &(var) ) 10,得到一个字的高位和低位字节 #define&&WORD_LO(xxx)&&((byte) ((word)(xxx) & 255)) #define&&WORD_HI(xxx)&&((byte) ((word)(xxx) && 8)) 11,返回一个比X大的最接近的8的倍数 #define RND8( x )&&&&&& ((((x) + 7) / 8 ) * 8 ) 12,将一个字母转换为大写 #define&&UPCASE( c ) ( ((c) &= 'a' && (c) = '0' && (c) = '0' && (c) = 'A' && (c) = 'a' && (c)&&(val)) ? (val)+1 : (val)) 16,返回数组元素的个数 #define&&ARR_SIZE( a )&&( sizeof( (a) ) / sizeof( (a[0]) ) ) 17,返回一个无符号数n尾的值MOD_BY_POWER_OF_TWO(X,n)=X%(2^n) #define MOD_BY_POWER_OF_TWO( val, mod_by ) \ &&&&&&&&&& ( (dword)(val) & (dword)((mod_by)-1) ) 18,对于IO空间映射在存储空间的结构,输入输出处理 &&#define inp(port)&&&&&&&& (*((volatile byte *) (port))) &&#define inpw(port)&&&&&&&&(*((volatile word *) (port))) &&#define inpdw(port)&&&&&& (*((volatile dword *)(port))) && &&#define outp(port, val)&& (*((volatile byte *) (port)) = ((byte) (val))) &&#define outpw(port, val)&&(*((volatile word *) (port)) = ((word) (val))) &&#define outpdw(port, val) (*((volatile dword *) (port)) = ((dword) (val))) [添加]&& 19,使用一些宏跟踪调试 A N S I标准说明了五个预定义的宏名.它们是: _ L I N E _ _ F I L E _ _ D A T E _ _ T I M E _ _ S T D C _ 如果编译不是标准的,则可能仅支持以上宏名中的几个,或根本不支持.记住编译程序 也许还提供其它预定义的宏名. _ L I N E _及_ F I L E _宏指令在有关# l i n e的部分中已讨论,这里讨论其余的宏名. _ D AT E _宏指令含有形式为月/日/年的串,表示源文件被翻译到代码时的日期. 源代码翻译到目标代码的时间作为串包含在_ T I M E _中.串形式为时:分:秒. 如果实现是标准的,则宏_ S T D C _含有十进制常量1.如果它含有任何其它数,则实现是 非标准的. 可以定义宏,例如: 当定义了_DEBUG,输出数据信息和所在文件所在行 #ifdef _DEBUG #define DEBUGMSG(msg,date) printf(msg);printf(“%d%d%d”,date,_LINE_,_FILE_) #else &&&&&&#define DEBUGMSG(msg,date)&& #endif && 20,宏定义防止使用是错误 用小括号包含. 例如:#define ADD(a,b) (a+b) 用do{}while(0)语句包含多语句防止错误 例如:#difne DO(a,b) a+b;\ &&&&&&&&&&&&&&&&&& a++; 应用时:if(….) &&&&&&&&&&DO(a,b); //产生错误 &&&&&&&&else &&&&&&&& 解决方法: #difne DO(a,b) do{a+b;\ &&&&&&&&&&&&&&&&&& a++;}while(0) ------------------------------------------------------------------------------------------------- 宏中"#"和"##"的用法 一、一般用法 我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起. 用法: #i nclude #i nclude
#define STR(s)&&&& #s #define CONS(a,b)&&int(a##e##b) int main() { &&&&printf(STR(vck));&&&&&&&&&& // 输出字符串"vck" &&&&printf("%d\n", CONS(2,3));&&// 2e3 输出:2000 &&&&return 0; } 二、当宏参数是另一个宏的时候 需要注意的是凡宏定义里有用'#'或'##'的地方宏参数是不会再展开. 1, 非'#'和'##'的情况 #define TOW&&&&&&(2) #define MUL(a,b) (a*b) printf("%d*%d=%d\n", TOW, TOW, MUL(TOW,TOW)); 这行的宏会被展开为: printf("%d*%d=%d\n", (2), (2), ((2)*(2))); MUL里的参数TOW会被展开为(2). 2, 当有'#'或'##'的时候 #define A&&&&&&&&&&(2) #define STR(s)&&&& #s #define CONS(a,b)&&int(a##e##b) printf("int max: %s\n",&&STR(INT_MAX));&&&&// INT_MAX #i nclude 这行会被展开为: printf("int max: %s\n", "INT_MAX"); printf("%s\n", CONS(A, A));&&&&&&&&&&&&&& // compile error&& 这一行则是: printf("%s\n", int(AeA)); INT_MAX和A都不会再被展开, 然而解决这个问题的方法很简单. 加多一层中间转换宏. 加这层宏的用意是把所有宏的参数在这层里全部展开, 那么在转换宏里的那一个宏(_STR)就能得到正确的宏参数. #define A&&&&&&&&&& (2) #define _STR(s)&&&& #s #define STR(s)&&&&&&_STR(s)&&&&&&&&&&// 转换宏 #define _CONS(a,b)&&int(a##e##b) #define CONS(a,b)&& _CONS(a,b)&&&&&& // 转换宏 printf("int max: %s\n", STR(INT_MAX));&&&&&&&&&&// INT_MAX,int型的最大值,为一个变量 #i nclude 输出为: int max: 0x7fffffff STR(INT_MAX) --&&&_STR(0x7fffffff) 然后再转换成字符串; printf("%d\n", CONS(A, A)); 输出为:200 CONS(A, A)&&--&&&_CONS((2), (2))&&--& int((2)e(2)) 三、'#'和'##'的一些应用特例 1、合并匿名变量名 #define&&___ANONYMOUS1(type, var, line)&&type&&var##line #define&&__ANONYMOUS0(type, line)&&___ANONYMOUS1(type, _anonymous, line) #define&&ANONYMOUS(type)&&__ANONYMOUS0(type, __LINE__) 例:ANONYMOUS(static int);&&即: static int _anonymous70;&&70表示该行行号; 第一层:ANONYMOUS(static int);&&--&&&__ANONYMOUS0(static int, __LINE__); 第二层:&&&&&&&&&&&&&&&&&&&&&&&&--&&&___ANONYMOUS1(static int, _anonymous, 70); 第三层:&&&&&&&&&&&&&&&&&&&&&&&&--&&&static int&&_anonymous70; 即每次只能解开当前层的宏,所以__LINE__在第二层才能被解开; 2、填充结构 #define&&FILL(a)&& {a, #a} enum IDD{OPEN, CLOSE}; typedef struct MSG{ &&IDD &&const char * }MSG; MSG _msg[] = {FILL(OPEN), FILL(CLOSE)}; 相当于: MSG _msg[] = {{OPEN, "OPEN"}, &&&&&&&&&&&&&&{CLOSE, "CLOSE"}}; 3、记录文件名 #define&&_GET_FILE_NAME(f)&& #f #define&&GET_FILE_NAME(f)&&&&_GET_FILE_NAME(f) static char&&FILE_NAME[] = GET_FILE_NAME(__FILE__); 4、得到一个数值类型所对应的字符串缓冲大小 #define&&_TYPE_BUF_SIZE(type)&&sizeof #type #define&&TYPE_BUF_SIZE(type)&& _TYPE_BUF_SIZE(type) char&&buf[TYPE_BUF_SIZE(INT_MAX)]; &&&& --&&&char&&buf[_TYPE_BUF_SIZE(0x7fffffff)]; &&&& --&&&char&&buf[sizeof "0x7fffffff"]; 这里相当于: char&&buf[11];
阅读(1406) | 评论(0) | 转发(2) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。Linux -gdb如何显示宏定义的值 - CSDN博客
Linux -gdb如何显示宏定义的值
本文大概阐述如何让gdb能够显示宏定义的值以及对应的原理
gcc默认编译的时候,gdb调试过程中是不能看到宏定义的,&p 宏名& 会显示错误,如下:
(gdb) p CLIENT6_BEGIN_FLG
No symbol &CLIENT6_BEGIN_FLG& in current context.
其中 #define CLIENT6_BEGIN_FLG &&Client6&&
这样gdb调试过程中就很不直观,尤其是很多大型程序中,宏定义比较复杂的时候。
如果需要在gdb中能查看宏定义,gcc编译的时候需要加上 -gdwarf-2和-g3的参数。
下面看一下-gdward-2 和-g3参数的意思。
-g3 参数的意思:
man gcc,可以得出如下的解释:
-ggdblevel
-gstabslevel
-gcofflevel
-gxcofflevel
-gvmslevel
Request debugging information and also use level to specify how much information. The default level is 2.
Level 1 produces minimal information, enough for making backtraces in parts of the program that you don’t plan to debug.
This includes descriptions of functions and external variables, but no information about local variables and no line numbers.
Level 3 includes extra information, such as all the macro definitions present in the program. Some debuggers support macro
expansion when you use -g3.
加了-g3的参数后,gcc编译的时候,会将扩展的debug 信息编译进二进制文件里面,包括宏定义信息。
所以,如果要使用gdb调试二进制文件里面的宏定义信息,这个选项必须开启。
-gdwarf-2 参数的意思:
man gcc, 可以得出如下相关的解释:
-gdwarf-2 does not accept a concatenated debug level, because GCC used to support an option -gdwarf that meant to generate
debug information in version 1 of the DWARF format (which is very different from version 2), and it would have been too con-
fusing. That debug format is long obsolete, but the option cannot be changed now. Instead use an additional -glevel option
to change the debug level for DWARF2.
DWARF是一种应用的比较广泛的elf(可执行和链接格式), 目前有dwarf1, dwarf2,dwarf3 3种版本,
其中版本1已经是比较老旧的,基本废弃不用了。
这边的-gdwarf-2意思是使用版本2的格式,
对dwarf格式感兴趣的,可以看一下ibm的开发者文档:
/developerworks/cn/opensource/os-debugging/
里面会有一些解释。
加上相关参数后,编译:
gcc -gdwarf-2 -g3 test.c
gdb a.out后就能够使用 &p 宏名& 输出宏的内容了
(gdb) p CLIENT6_BEGIN_FLG
$1 = &&Client6&&
需要查看宏定义是如何被展开的,可以使用如下的命令:
macro expand macro_name
本文已收录于以下专栏:
相关文章推荐
本文大概阐述如何让gdb能够显示宏定义的值以及对应的原理
gcc默认编译的时候,gdb调试过程中是不能看到宏定义的,&p 宏名& 会显示错误,如下:
(gdb) p CLIENT6_BEGIN_F...
宏定义#define APLLCON0 *((volatile unsigned int *)0xFF500100)
转自:/article.php?id=1298&act=print
gdb define查看一个宏(C预处理宏)
  某些语言,例如C和C++,提供定义和...
用gcc编译bitmap.c, 使用一下命令: gcc -g bitmap.c -o bitmap
使用gdb调试的时候无法打印宏:
原因分析:
编译器默认没有把宏定义扩展信息编...
原文地址:GDB调试技巧:调试复杂的宏定义 作者:GFree_Wind
作者:gfree.
博客:blog.focus-linux.net   linu...
1. gcc的__attribute__编绎属性
要了解Linux Kernel代码的分段信息,需要了解一下gcc的__attribute__的编绎属性,__attribute__主要用于改变所声明...
本文首先介绍Linux下的经典宏定义,感受极客的智慧,然后根据该经典定义为下篇博客作铺垫。
offsetof宏
// 获得结构体(TYPE)的变量成员(MEMBER)在此结构体中...
include/linux/kernel.h
------------------------------------------------------
 * min()/max() m...
在C中,宏定义的概念虽然简单,但是真要用好却并不那么容易,下面从Linux源码中抽取一些宏定义的使用方法,希望能从中得到点启发:
1. 类型检查
比如module_init的宏定义:
我们习惯在SI(Source Insight)中阅读Linux内核,SI会建立符号表数据库,能非常方便地跳转到变量、宏、函数等的定义处。但在处理系统调用的函数时,却会遇到一些麻烦:我们知道系统调用函数...
他的最新文章
讲师:吴岸城
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)什么时候应该使用宏定义? - 知乎460被浏览45514分享邀请回答565 条评论分享收藏感谢收起/vczh/tinymoe 用的一个超简单的单元测试框架。使用的时候是这样子的,随便找一个cpp空白的地方写:TEST_CASE(ThisIsATestCase){
TEST_ASSERT(1+1==2);}所有的testcase就会在main函数之前自动运行。最后在main函数里面把所有全局变量删除掉,用VC++自带的内存泄漏工具一搞,就完美了。test case不仅写起来方便,而且保证没有内存泄漏9125 条评论分享收藏感谢收起查看更多回答如何查找一个宏定义的位置 - CSDN博客
如何查找一个宏定义的位置
本文已收录于以下专栏:
相关文章推荐
#define OFFSETOF(type, field) ((size_t)&(((type *)0)-&field))(type *)0:把0地址当成type类型的指针。((type *)0)-&...
include/linux/kernel.h
------------------------------------------------------
 * min()/max() m...
用一个宏定义FIND求一个结构体struct里某个变量相对struc的编移量.
如:stuct student 
char b[20]; 
static int __init acpi_init(void)
    
    if (acpi_disabled) {
        prin...
include/linux/kernel.h
------------------------------------------------------
 * min()/max() m...
最近闲来无事,分析下linux kernel里面一些函数都是怎样定义使用的,它们都是怎样避免风险的,从include/linux/kernel.h中挑出一个经典的min宏进行分析一下
从我们最...
开拓视野,以方便对代码的学习、研读和编写。
#ifdef __MMI_BOOTUP_SCALE__
#define MMI_APP_INIT(func) {U32 start_time...
这几天写一个自用的定时器, 因为每个定时器都需要保存一个回调函数, 之前直接用的函数指针,后来想了下不靠谱。后来就用了std::function,用std::function的主要原因就是可以通过使用...
他的最新文章
讲师:吴岸城
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 linux c 宏定义 的文章

 

随机推荐