C之 #error 和 #line(二十一)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C之 #error 和 #line(二十一)相关的知识,希望对你有一定的参考价值。

        我们今天来讲下 C 语言中的两个比较偏僻的知识点,之所以说偏僻是因为在平时的代码中我们见得很少。首先来说下 #error,它是用于生成一个编译错误消息。用法如下:#error message;注意 message 不需要用双引号包围#error 编译指示字用于自定义程序员特有的编译错误消息,类似的,#warning 就用于生成编译警告的(但它可以编译成功,生成可执行文件)。

        #error 是一种预编译器指示字,可用于提示编译条件是否满足。那么在编译过程中的任意错误信息意味着无法生成最终的可执行程序,自定义的 #error 也是一样。下来我们分析个示例代码,代码如下

#include <stdio.h>

class 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 在项目工程中是怎样进行应用的

#include <stdio.h>

void 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__

        我们来看个示例代码,代码如下

#include <stdio.h>

int 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 <stdio.h>

// 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

以上是关于C之 #error 和 #line(二十一)的主要内容,如果未能解决你的问题,请参考以下文章

Python学习(二十一) —— 前端之JavaScript

转: Java并发编程之二十一:并发新特性—阻塞队列和阻塞栈(含代码)

java基础之二十一-;Stream api

CSS学习(二十一)-flexbox模型之二

BetaFlight模块设计之二十一:dashboard任务分析

Hadoop MapReduce编程 API入门系列之网页流量版本1(二十一)