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!