关于条件编译和预编译的一点学习心得
2013-03-28 00:10
381 查看
项目经验丰富的朋友可能知道,要想让软件可移植性好,代码里面少不了很多的条件编译语句。我最近在移植一个模块时发现了一个我以前不是很懂的东西,那就是条件编译。以前只是知道有这么回事,但具体的细节全然不知。但是每当遇到一个问题,我都会追究到底,不会解决了就放下了。我想这应该是作为一个程序基本的素质吧!下面我简单分享一下我的理解,有不足和遗漏之处,希望大家指正!
1、条件编译
请看下面一个例子:
如果你觉得这个打印会是hello CC.那你就和我犯了一样的错误了。如果你用gcc -E hello.c -o hello.i 编译,(这条是预编译命令,下面会讲到。)会出现:error: #if with no expression的错误。原因是BB虽然定义了,但是定义的是空值,放在#elif后面就不行。因为#elif不仅仅是检查后面的宏有没有定义,还会检查其值。但是#ifdef就只是检查后面的宏是否定义,而不管其值为多少。读者可以把#define
BB改成#define AA试一下,结果就会打印hello world了。
读者如果有兴趣,也可以把#define BB改成#define BB 0 试一试,这时用gcc -E hello.c -o hello.i预编译可以编译通过,但是编译过程就不行了,因为#elif 0为假,HELLO没有定义。
2、预编译
如果你对预编译有过研究,那么下面的内容可能就不适合你了,这里我只是简单的讲讲预编译是怎么回事,不打算也还没能力潜的太深!
预编译大概有以下内容:
(1)将以#开头的全部去掉,是宏的就展开,是include的就把源文件内容包含进来
(2)然后把注释去掉
(3)添加行号和文件名,以便编译时产生调试信息
(4)保留所有#pragma编译器指令,因为编译器需要使用它们
预编译的命令上面已经提到过 :gcc -E 。预编译产生为.i的文件。下面是我预编译后产生hello.i文件的部分内容:
extern char *ctermid (char *__s)__attribute__ ((__nothrow__));
# 820"/usr/include/stdio.h" 3 4
extern void flockfile (FILE*__stream) __attribute__ ((__nothrow__));
extern int ftrylockfile (FILE*__stream) __attribute__ ((__nothrow__)) ;
extern void funlockfile (FILE*__stream) __attribute__ ((__nothrow__));
# 850"/usr/include/stdio.h" 3 4
# 2 "hello.c" 2
# 11 "hello.c"
int main()
{
printf("%s\n","helloworld");
return 1;
}
有兴趣的朋友可以再深入的研究研究。今天就到这里,欢迎大家提出意见和建议。如果有什么想一起探讨的话题,欢迎大家提出来,我会尽我最大的努力来和你们一起探讨,一起进步。
1、条件编译
请看下面一个例子:
#include<stdio.h> #define BB #ifdef AA #define HELLO "hello world" #elif BB #define HELLO "hello CC" #endifint main() { printf("%s\n",HELLO); return 1; }
如果你觉得这个打印会是hello CC.那你就和我犯了一样的错误了。如果你用gcc -E hello.c -o hello.i 编译,(这条是预编译命令,下面会讲到。)会出现:error: #if with no expression的错误。原因是BB虽然定义了,但是定义的是空值,放在#elif后面就不行。因为#elif不仅仅是检查后面的宏有没有定义,还会检查其值。但是#ifdef就只是检查后面的宏是否定义,而不管其值为多少。读者可以把#define
BB改成#define AA试一下,结果就会打印hello world了。
读者如果有兴趣,也可以把#define BB改成#define BB 0 试一试,这时用gcc -E hello.c -o hello.i预编译可以编译通过,但是编译过程就不行了,因为#elif 0为假,HELLO没有定义。
2、预编译
如果你对预编译有过研究,那么下面的内容可能就不适合你了,这里我只是简单的讲讲预编译是怎么回事,不打算也还没能力潜的太深!
预编译大概有以下内容:
(1)将以#开头的全部去掉,是宏的就展开,是include的就把源文件内容包含进来
(2)然后把注释去掉
(3)添加行号和文件名,以便编译时产生调试信息
(4)保留所有#pragma编译器指令,因为编译器需要使用它们
预编译的命令上面已经提到过 :gcc -E 。预编译产生为.i的文件。下面是我预编译后产生hello.i文件的部分内容:
extern char *ctermid (char *__s)__attribute__ ((__nothrow__));
# 820"/usr/include/stdio.h" 3 4
extern void flockfile (FILE*__stream) __attribute__ ((__nothrow__));
extern int ftrylockfile (FILE*__stream) __attribute__ ((__nothrow__)) ;
extern void funlockfile (FILE*__stream) __attribute__ ((__nothrow__));
# 850"/usr/include/stdio.h" 3 4
# 2 "hello.c" 2
# 11 "hello.c"
int main()
{
printf("%s\n","helloworld");
return 1;
}
有兴趣的朋友可以再深入的研究研究。今天就到这里,欢迎大家提出意见和建议。如果有什么想一起探讨的话题,欢迎大家提出来,我会尽我最大的努力来和你们一起探讨,一起进步。
相关文章推荐
- 关于C#中AutoResetEvent和ManualResetEvent的一点学习心得
- 关于51单片学习的一点心得
- 关于android studio 编译报错的一点小心得
- 关于C#中AutoResetEvent和ManualResetEvent的一点学习心得
- 关于framebuffer这几天学习的一点心得体会和疑惑
- 关于java内存泄漏的一点学习心得
- [转载]关于文件系统和磁盘驱动的一点学习心得
- 关于学习新技术的一点心得
- 关于多态的一点学习心得
- 关于NOSQL和MongoDB的一点学习心得
- 【分享】关于第10章-同时替换栈和.data中COOKIES来突破GS的一点学习心得
- 初学者学习分布式的一点心得,关于Remoting的分布式简单实例的
- Unity3d C#学习小结(五)[关于不同平台的条件编译]
- 关于编程语言的学习的一点心得
- 《More Effective C++》学习心得(四) 关于类中类型转换
- 关于本科学习GIS的一点感悟,不知道自己该干些什么的学弟学妹们可以借鉴一下……
- 关于UILabel的一点使用心得
- 关于学习嵌入式的一点问题
- 关于position标签的一点心得
- 关于embedded linux的使用、开发、学习的一点自已的体会