C之 #error 和 #line(二十一)
我们今天来讲下 C 语言中的两个比较偏僻的知识点,之所以说偏僻是因为在平时的代码中我们见得很少。首先来说下 #error,它是用于生成一个编译错误消息。用法如下:#error message;注意 message 不需要用双引号包围。#error 编译指示字用于自定义程序员特有的编译错误消息,类似的,#warning 就用于生成编译警告的(但它可以编译成功,生成可执行文件)。
#error 是一种预编译器指示字,可用于提示编译条件是否满足。那么在编译过程中的任意错误信息意味着无法生成最终的可执行程序,自定义的 #error 也是一样。下来我们分析个示例代码,代码如下
#includeclass CppClass{private: int m_value;public: CppClass() { } ~CppClass() { }};int main(){ return 0;}
我们看这段代码,熟悉 C++ 的人,可能一眼就看出了这是一段 C++ 的代码。在我们没学习过 C++ 的前提下,我们用 C 的方式来编译下,看看什么情况
显然是报错了,不认识 class 的类型。那么我们在代码一开始就加上下面的代码进行说明这是段 C++ 的代码,必须用 C++ 的编译器才可以,编译信息也就很明显了。
#ifndef __cplusplus #error This file should be processed with C++ compiler.#endif
我们来看看编译结果
图中所指出的便是我们自己添加的 #error 信息了。下面箭头所指的便是用 g++ 来编译的,我们发现它成功编译,并没有出错。
下面通过一个示例代码来讲讲 #error 在项目工程中是怎样进行应用的
#includevoid f(){#if ( PRODUCT == 1 ) printf("This is a low level product!\n");#elif ( PRODUCT == 2 ) printf("This is a middle level product!\n");#elif ( PRODUCT == 3 ) printf("This is a high level product!\n");#else #error The 'PRODUCT' is NOT defined!#endif}int main(){ f(); printf("1. Query Information.\n"); printf("2. Record Information.\n"); printf("3. Delete Information.\n");#if ( PRODUCT == 1 ) printf("4. Exit.\n");#elif ( PRODUCT == 2 ) printf("4. High Level Query.\n"); printf("5. Exit.\n");#elif ( PRODUCT == 3 ) printf("4. High Level Query.\n"); printf("5. Mannul Service.\n"); printf("6. Exit.\n");#else #error The 'PRODUCT' is NOT defined!#endif return 0;}
我们直接编译,不加 -DPRODUCT,看看编译后的结果
直接报错,没有定义 PRODUCT。那我们分别定义它为 1, 2, 3 将会输出低,中,高版本的打印信息吗?我们看看编译结果
结果确实是如我们分析的那样,分别打印出低,中,高版本的信息啦。
我们下面来讲讲 #line 的用法,它用于强制指定新的行号和编译文件名,并对源程序的代码进行重新编号。用法:#line number filename。ps:filename 可省略。#line 编译指示字的本质就是重新定义我们 C 语言中内置的宏 __LINE__ 和 __FILE__。
我们来看个示例代码,代码如下
#includeint main(){ printf("%s : %d\n", __FILE__, __LINE__); #line 1 "a.c" printf("%s : %d\n", __FILE__, __LINE__); return 0;}
我们分析下,在程序的第5行会打印出 test.c:5。那么我们在第7行使用了 #line 后,在程序的第9行就应该打印出 a.c:2。我们来看看编译结果
那么这种写法有什么好处呢?在以前的开发中,为了加快开发速度,一个项目通常是由好几个人共同完成。那么把所有人的代码整合到一份代码中,我们编译的时候如果出错,我们又怎么知道是谁的代码出错呢?这时就需要 #line 编译指示字了。下面我们看看这个示例代码
#include// The code section is written by A.// Begin#line 1 "a.c"// End// The code section is written by B.// Begin#line 1 "b.c"// End// The code section is written by c.// Begin#line 1 "c.c"int main(){ printf("%s : %d\n", __FILE__, __LINE__) return 0;}// End
我们注释的代码,程序员当然看的懂,但是编译器不认识啊。这时我们就用 #line 指定后,编译器就知道那块代码是谁写的了,报错当然会报出来啦。我们故意在程序的第21行制造一个错误。看看编译器能否报出来是谁的错
它说在 c.c 中的第5行 return 前少一个 ;。我们再次加上之后编译,如下
我们看到结果已经正确。通过对 #error 和 #line 的学习,总结如下:1、#error 用于自定义一条编译错误信息,#waring 用于自定义一条编译警告信息;2、#error 和 #warning 常应用于条件编译的情形;3、#line 用于强制指定新的行号和编译文件名。
欢迎大家一起来学习 C 语言,可以加我QQ:243343083。