《gcc五分钟系列》第六节:编译期符号检查

    上一节,我们说了从源文件到目标文件的编译过程。这一节,我想讨论一下编译期符号检查的问题。
    请原谅我实在不知道如何翻译“reference”,“引用”似乎不能表达清楚,所以我擅自将它翻译成“符号”。
    比如,第四节的例子中,main.cpp文件中只有sum()函数的声明、而没有定义。
    相信您能够分辨C/C++中声明和定义的区别。
    可是将main.cpp编译成main.o的过程中,没有报任何错误。
   
    这里,我们看下面这个例子:
    我们只声明了一个结构体而没有定义这个结构体,然后定义一个这个结构体的变量。
    代码:

  1. //struct1.cpp 
  2. struct Poo; 
  3. int main() 
  4.     Poo a; 
  5.     return 0; 

    只编译而不链接:

  1. g++ -c struct1.cpp 

    这个时候它会报错:

  1. struct1.cpp: In function ‘int main()’: 
  2. struct1.cpp:4:6: error: aggregate ‘Poo a’ has incomplete type and cannot be defined 


    这说明,只有声明没有定义的结构体不能够定义变量。
    把代码稍微改一下,定义这个结构体的一个指针:

  1. //struct1.cpp 
  2. struct Poo; 
  3. int main() 
  4.     Poo *a; 
  5.     return 0; 


    只编译不链接,没有任何问题。

    这说明,虽然不能定义变量,但是可以定义指针。
    再把代码稍微改一下,实例化一下:

  1. //struct1.cpp 
  2. struct Poo; 
  3. int main() 
  4.     Poo *a=new Poo; 
  5.     return 0; 


    这个时候也会报错:

  1. struct1.cpp: In function ‘int main()’: 
  2. struct1.cpp:4:13: error: invalid use of incomplete type ‘struct Poo’ 
  3. struct1.cpp:1:8: error: forward declaration of ‘struct Poo’ 

   
    根据我的经验:
    1、编译期不会报错的几种情况(链接期会不会报错是另外一回事了,这里不讨论):
        1.1、调用一个只有声明没有定义的函数。
        1.2、定义一个只有声明没有定义的类型的指针。
        1.3、使用一个只有声明没有定义的变量。
        变量如何只声明不定义?int a;就已经是定义了。好吧,留个悬念,大家可以自己研究一下。
    2、编译期会报错的几种情况:
        2.1、定义一个只有声明没有定义的类型的变量。
        2.2、实例化一个只有声明没有定义的类型。
       
    这节好像稍微有点长,好吧。结束。