zoukankan      html  css  js  c++  java
  • 第23课

    第23课 - #error 和 #line 使用分析

    1. #error 的用法

    (1)#error 是一个预处理器指示字,用于生成一个编译错误消息,这个消息最终会传递到编译器(gcc)

             在思考这一点的过程中,领悟到了两个点:

             ① 使用 gcc 编译代码,输出的错误(警告)信息,是由预处理器、编译器、汇编器、链接器产生的。

             ② gcc表示整个编译过程,它会调用 预处理器程序 -> 编译器程序 -> 汇编器程序 -> 链接器程序

    (2)使用方法:#error message     // 不需要在message上使用双引号

    (3)#error 编译指示字用于自定义程序员特有的编译错误消息。类似的,#warning 用于生成编译警告错误

    (4)#error 可用于提示编译条件是否满足。编译过程中的任何错误意味着无法生成最终的可执行程序。

    下面我们通过一个示例程序来说明 #error 的用法:

    下面是一段C++ 的代码,如果我们错误的使用gcc对其进行编译就会报错

     1 #include <stdio.h>
     2 
     3 class CppClass
     4 {
     5 private:
     6     int m_nValue;
     7 public:
     8     CppClass(){};
     9     ~CppClass(){};
    10 };
    11 
    12 int main()
    13 {
    14     return 0;
    15 }

    使用gcc编译该代码报错  

     

     那如何解决这个问题呢?答案就是使用 条件编译 + #error 

     1 #include <stdio.h>
     2 
     3 // __cplusplus宏是C++编译器内置的一个宏,C编译器中是没有的
     4 // 如果使用C编译器编译该程序#error就会报编译报错
     5 #ifndef __cplusplus
     6     #error This file should be processed with C++ compiler
     7 #endif
     8 
     9 class CppClass
    10 {
    11 private:
    12     int m_nValue;
    13 public:
    14     CppClass(){};
    15     ~CppClass(){};
    16 };
    17 
    18 int main()
    19 {
    20     return 0;
    21 }

    在上篇文章的最后,我们分析了一个通过条件编译区分产品版本的小程序,在那个代码中我们没有考虑一种情况,那就是如果没有定义PRODUCT这个宏会怎么样?

    #include <stdio.h>
    
    void f()
    {
    #if (PRODUCT == 1)
        printf("This is a low level product!
    ");
    #elif (PROUDCT == 2)
        printf("This is a middle level product!
    ");
    #elif (PRODUCT == 3)
        printf("This is a high level product!
    ");
    #endif
    }
    
    int main()
    {
        f();
        
        printf("1. Query Information.
    ");
        printf("2. Record Information.
    ");
        printf("3. Delete Information.
    ");
        
    #if (PRODUCT == 1)
        printf("4. Exit.
    ");
    #elif (PRODUCT == 2)
        printf("4. High Level Query.
    ");
        printf("5. Exit.
    ");
    #elif (PRODUCT == 3)
        printf("4. High Level Query.
    ");
        printf("5. Mannual Service.
    ");
        printf("6. Exit.
    ");
    #endif
        
        return 0;
    }

    如果我们在编译该程序时没有通过-DPRODUCT指定这个宏的值,编译并不会报错但是执行结果就有问题了

    使用 #error 完善该程序,如果没有定义PRODUCT或者PRODUCT的值不为1、2、3中的一个,程序在编译时就会报错。

     1 #include <stdio.h>
     2 
     3 void f()
     4 {
     5 #if (PRODUCT == 1)
     6     printf("This is a low level product!
    ");
     7 #elif (PROUDCT == 2)
     8     printf("This is a middle level product!
    ");
     9 #elif (PRODUCT == 3)
    10     printf("This is a high level product!
    ");
    11 #else
    12     // 如果PRODUCT未定义或定义了但!=1 != 2 != 3
    13     #error The PRODUCT macro is NOT defined!
    14 #endif
    15 }
    16 
    17 int main()
    18 {
    19     f();
    20     
    21     printf("1. Query Information.
    ");
    22     printf("2. Record Information.
    ");
    23     printf("3. Delete Information.
    ");
    24     
    25 #if (PRODUCT == 1)
    26     printf("4. Exit.
    ");
    27 #elif (PRODUCT == 2)
    28     printf("4. High Level Query.
    ");
    29     printf("5. Exit.
    ");
    30 #elif (PRODUCT == 3)
    31     printf("4. High Level Query.
    ");
    32     printf("5. Mannual Service.
    ");
    33     printf("6. Exit.
    ");
    34 #else
    35     // 如果PRODUCT未定义或定义了但!=1 != 2 != 3
    36     #error The PRODUCT macro is NOT defined!
    37 #endif
    38     
    39     return 0;
    40 }

    2. #line 的用法

    (1)#line 用于强制指定新的行号和编译文件名,并对源程序的代码重新编号

    (2)用法: 

                ① #line number newFilename

                ② #line number     // 不改变文件名,只改变行号

    (3)#line 编译指示字的本质是重定义 __LINE__ __FILE__

     1 #include <stdio.h>
     2 
     3 int main()
     4 {
     5     printf("%s : %d
    ", __FILE__, __LINE__);
     6 
     7     #line 1 "new_line.c"    // 这里改变了行号和文件名,行号为1(下一行行号为1)、文件名为new_line.c(注意这里需要使用用双引号)
     8 
     9     printf("%s : %d
    ", __FILE__, __LINE__);
    10 
    11     return 0;
    12 }

    // 输出结果

        swj@ubuntu:~/c_course/ch_23$ ./a.out
        line.c : 5
        new_line.c : 2

    #line 是C语言早期的产物(在当今的软件工程中已经不使用了),那时候代码量比较小,通常放到一个文件中。如果这个程序由几个人分工协作完成的话,就是每个人先各写各的,最后再统一放到一个文件中。

    那如果编译发生错误,如何知道错误的代码是谁写的呢?这个就要使用 #line 预处理指令了。 

     1 #include <stdio.h>
     2 
     3 // The code section is written by A.
     4 // Begin
     5 #line 1 "a.c"
     6 
     7 // End
     8 
     9 // The code section is written by B.
    10 // Begin
    11 #line 1 "b.c"
    12 
    13 // End
    14 
    15 // The code section is written by Scott.
    16 // Begin
    17 #line 1 "scott_shi.c"
    18 
    19 
    20 int main()
    21 {
    22     printf("%s : %d
    ", __FILE__, __LINE__);
    23     
    24     printf("%s : %d
    ", __FILE__, __LINE__)    // 这里编译会报错
    25     
    26     return 0;
    27 }
    28 
    29 // End

     编译报错,提示是 scott_shi.c 这个文件的 第9行 发生错误,这样就定位了是哪个人写的。

  • 相关阅读:
    传智博客.NET培训第13季 Ajax教程(共十三季) 学习资源
    一些sql语句的常用总结(重要)
    处理oracle的死锁
    Adroid 总结--android ListView美化,个性化更改的属性
    如何远程备份sql server数据库
    VSS (Visual Source Safe 2005) 用法详解
    php插入代码数据库
    PHP之PHP文件引用详解
    需要引入库:vue-resource
    axios调用详解
  • 原文地址:https://www.cnblogs.com/shiwenjie/p/11853947.html
Copyright © 2011-2022 走看看