Pertanyaan c & c ++ global variable linkage, multiple declaration & definition problem


Sebagai contoh:

kode1.c / .cpp

int a;

// ... and so on

kode2.c / .cpp

int a;

int main(void) {
    return 0;
}

pergi ke kompilasi:

$gcc code1.c code2.c      # this is fine
$

$g++ code1.cpp code2.cpp  # this is dead
/tmp/ccLY66HQ.o:(.bss+0x0): multiple definition of `a'
/tmp/ccnIOmPC.o:(.bss+0x0): first defined here
collect2: ld returned 1 exit status

Apakah ada perbedaan hubungan variabel global antara C & C ++?


25
2018-06-16 11:27


asal


Jawaban:


Ini tidak sepenuhnya legal. int a; adalah definisi tentatif dalam C. Anda diizinkan beberapa definisi tentatif dan paling banyak satu definisi non-tentatif per unit penerjemahan dari setiap objek dengan hubungan eksternal dalam C, tetapi hanya satu definisi di semua unit terjemahan dalam sebuah program.

Ini adalah ekstensi yang diimplementasikan secara umum untuk memungkinkan definisi sementara di beberapa unit terjemahan di C selama tidak lebih dari satu unit terjemahan mengandung definisi non-tentatif, tetapi itu tidak benar-benar standar.

Di C ++ int a; hanyalah sebuah definisi - tidak ada konsep tentatif - dan masih ilegal untuk memiliki beberapa definisi dari suatu objek di seluruh unit terjemahan dari sebuah program.

Untuk kasus C, Anda mungkin ingin melihatnya pertanyaan ini.


18
2018-06-16 11:35



Ini ilegal di keduanya, tetapi C compiler umumnya menerapkan ekstensi. Lihat jawaban ini.


4
2018-06-16 11:35



Ada tiga cara untuk memecahkan masalah:

  1. Jika variabel a sama di kedua file, Anda harus menyatakannya sebagai extern di semua file kecuali satu. extern kata kunci mengatakan kepada penaut bahwa nama ini terletak di file lain.

  2. Anda dapat menggunakan static kata kunci untuk membatasi ruang lingkup variabel ke satu file. Di mana itu diumumkan.

  3. Atau Anda dapat menggunakan namespace tanpa nama.


2
2018-06-16 11:38



g ++ compiler lebih ketat daripada compiler gcc. Ini juga tergantung pada versi gcc, mungkin versi lebih tinggi dari gcc i.e. 4.X dan seterusnya dapat memberikan kesalahan yang sama.

Menggunakan extern menghindari


1
2018-06-16 11:40