Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapa Pertukaran Pengisytiharan Pembolehubah Global dalam C Membawa kepada Gelagat Tidak Dijangka?

Mengapa Pertukaran Pengisytiharan Pembolehubah Global dalam C Membawa kepada Gelagat Tidak Dijangka?

Susan Sarandon
Susan Sarandonasal
2024-10-30 06:38:03778semak imbas

 Why Does Swapping Global Variable Declarations in C   Lead to Unexpected Behavior?

Tertib Permulaan Global dalam C : Mengabaikan Ketergantungan

Dalam C , susunan permulaan pembolehubah global dalam unit terjemahan ditakrifkan dengan baik. Walau bagaimanapun, kebergantungan antara global boleh diabaikan, membawa kepada tingkah laku yang mengejutkan.

Pertimbangkan kod berikut:

<code class="cpp">struct Foo;

extern Foo globalFoo;

struct Foo {
    Foo() { printf("Foo::Foo()\n"); }
    void add() { printf("Foo::add()\n"); }
    static int addToGlobal() {
        printf("Foo::addToGlobal() START\n");
        globalFoo.add();
        printf("Foo::addToGlobal() END\n");
        return 0;
    }
};

Foo globalFoo;
int dummy = Foo::addToGlobal();

int main() {
    printf("main()\n");
    return 0;
}</code>

Apabila disusun dengan GCC 4.4.3, output yang dijangkakan ialah:

Foo::Foo()
Foo::addToGlobal() START
Foo::add()
Foo::addToGlobal() END
main()

Ini kerana pembolehubah global globalFoo dimulakan sebelum memanggil kaedah statik Foo::addToGlobal(). Walau bagaimanapun, jika kita menukar susunan globalFoo dan pengisytiharan tiruan, outputnya menjadi:

Foo::addToGlobal() START
Foo::add()
Foo::addToGlobal() END
Foo::Foo()
main()

Nampaknya kaedah contoh Foo sedang dipanggil pada tika yang tidak dibina. Ini kerana susunan pemula global mengabaikan kebergantungan.

Untuk memastikan pembina Foo dipanggil sebelum memulakan dummy, kita perlu memastikan globalFoo ditakrifkan sebelum dummy dalam unit terjemahan yang sama. Sebagai alternatif, kita boleh menggunakan penuding statik kepada contoh global, yang akan dimulakan kepada nol sebelum sebarang permulaan dinamik. Kaedah addToGlobal kemudiannya boleh menyemak sama ada penuding adalah batal dan mencipta Foo global jika perlu.

Atas ialah kandungan terperinci Mengapa Pertukaran Pengisytiharan Pembolehubah Global dalam C Membawa kepada Gelagat Tidak Dijangka?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn