Langsung ke konten utama

Iklan





Penggunaan Linker untuk Menyelesaikan Simbol Global Bahasa C

Ketika melakukan kompilasi program, kompilator akan mengeksport setiap simbol global menuju ke assembler apakah termasuk kategori yang kuat atau lemah, selanjutnya assembler melakukan encode informasi tersebut secara implisit dalam tabel simbol dari file object relokasi. Fungsi dan inisialisasi variabel global akan mendapatkan simbol yang kuat. Sedangkan variabel global yang tidak diinisialisasi akan mendapatkan simbol yang lemah. Untuk lebih memahami pendefinisian ini perhatikan contoh program berikut ini.

/* fungsi main.c */

void swap();

int buf[2] = {1, 2};

 

int main()

{

swap();

return 0;

}

 

/* fungsi swap.c */

extern int buf[];

 

int *bufp0 = &buf[0];

int *bufp1;

 

void swap()

{

int temp;

 

bufp1 = &buf[1];

temp = *bufp0;

*bufp0 = *bufp1;

*bufp1 = temp;

}


Tentukan apakah simbol berikut ini termasuk simbol yang kuat atau lemah, Unix Linker menggunakan aturan berikut ini untuk beurusan dengan banyak simbol yang didefinisikan:

Aturan satu: Multiple strong simbol dengan nama variabel sama tidak dibolehkan.

Aturan dua: Jika diberikan strong simbol dan weak simbol, maka yang dipilih adalah strong simbol.

Aturan tiga: Jika diberikan banyak weak simbol, pilih salah satu dari weak simbol apapun. Contohnya, misalnya akan berupaya untuk mengkompilasi dan menautkan dua modul bahasa C berikut ini:

/* foo1.c */
int main()
{
return 0;
}

/* bar1.c */
int main()
{
return 0;
}



Iklan

Pada contoh program sebelumnya, akan dihasilkan pesan error karena strong simbol main didefinsikan lebih dari satu kali (aturan satu);

/* foo1.c */

int main()

{

return 0;

} 


/* bar1.c */

int main()

{

return 0;

}


Dengan hasil yang sama, akan dihasilkan pesan error dari modul berikut karena strong simbol x didefinisikan dua kali (aturan satu);

/* foo2.c */

int x = 15213;

int main()

{

return 0;

}

  

/* bar2.c */

int x = 15213;

void f()

{}


Namun demikian, jika x tidak diinisialisasi dalam satu modul, maka linker akan memilih strong simbol yang didefinisikan pada (aturan dua) modul lainnya seperti contoh program berikut ini:

/* foo3.c */

#include <stdio.h>

 

void f(void);

int x = 15213;

 

int main()

{

f();

printf("x = %d\n", x);

return 0;

}

 

/* bar3.c */

int x;

 

void f()

{

x = 15212;

}


Saat waktu running program, fungsi f() mengubah nilai dari x yang awalnya 15213 menjadi 15212, yang mungkin saja tidak diterima oleh author dari fungsi main. catatan, bahwa linker umumnya tidak memberikan indikasi bahwa telah mendeteksi definisi ganda dari x.

Hal serupa juga dapat terjadi jika terdapat dua definisi weak dari x (aturan 3).

/*a.c*/

#include <stdio.h>

void b(void);

 

int x;

int main()

{

x = 2016;

b();

printf("x = %d ",x);

return 0;

}

 

/*b.c*/

#include <stdio.h>

int x;

 

void b()

{

x = 2017;

}


Penerapan aturan dua dan aturan tiga dapat mengakibatkan bug runtime yang berbahaya yang tidak inconferehensif bagi para programmer, khususnya jika terjadi pendefinisikan duplikasi simbol pada tipe yang berbeda Contoh; x didefinisikan sebagai int pada modul satu dan juga didefinisikan pada modul yang lainnya.

/*a.c*/

#include <stdio.h>

void b(void);

 

int x = 2016;

int y = 2017;

 

int main()

{

b();

printf("x = 0x%x y = 0x"

"%x \n", x, y);

return 0;

}

 

/*b.c*/

double x;

 

void b()

{

x = -0.0;

}


Program yang telah dibuat tersebut telah menghasilkan bug, khususnya karena bug tersebut sulit dideteksi, karena tidak ada pesan warning dari sistem kompilasi, dan juga bug tersebut tetap dapat muncul pada bagian program lainnya, jauh dari tempat kemunculan awal dari bug tersebut. Pada program dengan skala yang lebih luas jenis bug yang telah diciptakan seperti ini akan jauh lebih sulit lagi untuk dideteksi, khususnya karena banyak programmer tidak antisipasi terhadap bagaimana linker bekerja. Tanpa ragu, seorang programmer memanggil linker dengan flag seperti gcc -fno-common flag, yang dapat men-trigger error dalam multi definisi simbol yang global.


Iklan

Komentar

  1. Apa yang dimaksud dengan linker?

    BalasHapus
    Balasan
    1. Dalam dunia komputasi atau pemrograman komputer, linker atau editor link adalah program sistem komputer yang mengambil satu atau lebih objek file yang dihasilkan oleh sebuah kompilator atau assembler dan menggabungkannya menjadi satu file baru yang dapat eksekusi oleh mesin berupa file library, atau file objek lainnya.

      Hapus
  2. Apa yang dimaksud dengan linker dan loader pada bahasa C?

    BalasHapus
    Balasan
    1. Linker merupakan objek yang menggabungkan satu atau lebih objek file beserta beberapa kode library yang diubah menjadi beberapa objek baru atau library baru yang dapat dieksekusi.

      Sedangkan loader merupakan sebuah pembaca kode program yang kemudian mengeksekusinya ke dalam sebuah memori, juga dapat melakukan beberapa penerjemahan alamat dan dapat menjalankan program ataupun menampilkan pesan kesalahan atau error tertentu.

      Hapus
    2. Linker mengambil masukkan kode dari sebuah objek yang dihasilkan oleh kompilator atau assembler. Sedangkan loader mengambil masukkan daril file yang dapat dieksekusi yang dihasilkan oleh linker.

      Hapus

Posting Komentar

Respon komentar 7 x 24 jam, so please be patient :D