ヘッダファイルで変数を定義しない

1618 ワード

Cコードを書くときは、ヘッダファイルに予め定義された情報を含めることがよくあります.たとえば、いくつかの構造体の宣言、外部変数、関数の宣言などです.
ソースファイルで定義する必要がないように、ヘッダファイルに変数を定義する必要がある場合があります.しかし、このようにするのは、大きな問題があります.
たとえば
//test.h
  1 #ifndef _TEST_H
  2 #define _TEST_H
  3 int x;
  4 const char *name = "hhcn";
  5 #endif
~              
//test.c

#include "test.h"
//main.c
  1 #include 
  2 #include "test.h"
  3 
  4 int main()
  5 {
  6     int j = x;
  7     printf("j= %d
", j); 8 9 const char *p = name; 10 printf("%s
", p); 11 12 return 0; 13 } ~
このように、コンパイルする時、すべて通過して、しかしリンクする時、報告します
cc    -c -o main.o main.c
cc    -c -o test.o test.c
gcc main.o test.o -o test
test.o:(.data+0x0): multiple definition of `x'
main.o:(.data+0x0): first defined here
test.o:(.data+0x4): multiple definition of `name'
main.o:(.data+0x4): first defined here
collect2: ld returned 1 exit status
make:***[all]エラー1
xは他の場所で定義されていないと思うかもしれません.文字列nameも定数ですが、どうして繰り返し定義を報告しますか?
実はtestでcにはtestが含まれている.h,xとname,mainが定義されている.c中もそうです.するとリンクするとき、どの定義を使うべきか分かりません.
正しい方法は、ヘッダファイルのみで宣言し、真の定義をソースファイルに配置することです.これにより、どのソースファイルにヘッダファイルが含まれていても問題はありません.定義された場所は1つしかないので、リンクするときに見つかります.
本当にヘッダファイルで変数を定義する必要があると思ったら、staticを前に付けましょう.少なくともあなたがコンパイルすることを保証することができて、リンクの時に間違いがありません.