Thread overview
C++/D Linker Nasıl Bir Mantıkla Çalışıyor?
Dec 11, 2015
İbrahim
Dec 11, 2015
İbrahim
Dec 12, 2015
İbrahim
December 11, 2015

Selamün Aleyküm.

Bundan bir önceki "İnşa Araçları" adlı konumda Ali Hocam g++ a.cpp b.cpp -o app şeklinde derlemem gerektiğini söylediniz, yoksa linker sorunu olacağını söylediniz. Şimdiki konum işte bu konuda. Şöyle bir örnek var: http://www.tutorialspoint.com/makefile/why_makefile.htm. Buradaki örneği g++ hello.cpp -o hello olarak derlemeye çalıştım ve hata aldım. Sonra bir tane de kendim örnek yaptım şu şekilde:

// functions.h
int factorial(int n);
int max(int x, int y);

// functions.cpp
#include <functions.h>

int factorial(int n)
{
	return (n > 1) ? n * factorial(n - 1) : 1;
}

int max(int x, int y)
{
	return (x > y) ? x : y;
}

// main.cpp
#include <iostream>

#include "functions.h"

using namespace std;

int main()
{
	cout << "Factorial of 5 is " << factorial(5);
	cout << endl;
	cout << "Max(5, 7) = " << max(5, 7) << endl;

	return 0;
}

Terminalde şu şekilde: 'g++ main.cpp -o main' derlemeye çalıştım fakat hata verdi. Dediğim gibi hatanın linker'dan kaynaklandığını biliyorum. Fakat bu örneği mesela QtCreator gibi bir ide'de yazınca çalıştır diyorsun ve çalışıyor fakat bir editörde yazında terminalden çalışmıyor. Acaba bu linker functions.cpp'de fonksiyon kodları olduğu halde main'de sadece functions.h yi çağırınca nasıl birbirine bağlıyor? Terminalde neden 'g++ main.cpp -o main' yazınca çalışmıyor da 'g++ main.cpp functions.cpp -o main' yazınca çalışıyor? Tüm cpp dosyalarını derlemeyle linker'ın arasında nasıl bir bağlantı var? Çalıştığım kitapta bunu şu an görmedim, sanırım ilerki sayfalarda bahsedecek ama şu an merak ettim.
Ali Hocam cevap verirseniz sevinirim, nasıl olsa sitede ikimiz varız genelde :)
Teşekkürler!

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 12, 2015

Alıntı:

>

Aynı neden: main'in çağırdığı işlevler programı oluştururken kullanılmamış. main.cpp'nin functions.h'yi eklemiş olması hiç yeterli değil çünkü onun bildirdiği işlevlerinin hangi kaynak dosyalarda olduklarını bağlayıcıya söylemiyoruz.

Anladığım kadarıyla tüm cpp dosyalarını derlemeyle oluşan .o dosyasından asıl olarak verilere ulaşılıyor, cpp'lerin bir kısmını derlemezsek bağlayıcı (linker) mesela fonksiyonun kodlarını .o dosyası oluşmadan bulamıyor ve hata veriyor. Doğru anlamışımdır umarım.

Alıntı:

>

Hangi kitap?

Bu kitap: http://www.kitapyurdu.com/kitap/nesne-yonelimli-c-programlama-kilavuzu/47958.html&filter_name=robert%20lafore sizce iyi midir bu kitap?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 12, 2015

Peki Qt bildiğimiz gibi uygulamaları statik derlemeyi yasal kabul etmiyor. Acaba bu .o dosyalarını da beraberinde vermemizi mi istiyor? Statik derleme tam olarak bu .o dosyalarını ve dll gibi dosyaları hep birlikte mi derliyor?

ACCU'ya baktım ve anladığım kadarıyla 1-2 anlatım hatasından bahsetmiş, İnşallah bana yanlış öğretmiyordur kitap :) .

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 11, 2015

Bağlayıcı (linker) ve onun ikiz kardeşi yükleyici (loader) işletim sistemi ile ilgili konulardır. Temelde çok basit bir kavramdır:

Derlenmiş bir program parçası (.o dosyası), bir kavramı ismiyle anarak bir işlem yapar: "g_değişken adlı değişkenin değeri bir arttırılıyor" gibi. Olasılıkla, g_değişken adlı değişken başka bir .o (veya kütüphane) dosyasındadır. Bağlayıcının görevi, bu iki .o dosyasını belleğe yerleştirmek ve ismiyle g_değişken diye anılan değişkenin bu yerleşim sonrasında tam olarak nerede olduğunu görmek ve yukarıdaki ifadeyi "0x1234 adresindeki değişkenin değeri bir arttırılıyor" diye değiştirmektir.

Aynısı işlevler için de geçerlidir: Program parçaları ve kütüphaneler belleğe okunduktan sonra onlar içindeki "foo()'yu çağırıyoruz" gibi ifadeleri "0x5678 adresindeki kodu işletiyoruz" gibi ifadelerle değiştirir.

Gerçekten, temelde bundan başka bir şey değil. Ancak, her olayda olduğu gibi, bağlayıcıların binbir ayrıntısı var: Derlenmiş dosyalar ve kütüphaneler için farklı düzenler (ELF, vs.), farklı işletim sistemleri, vs.

Alıntı (İbrahim):

>

g++ hello.cpp -o hello olarak derlemeye çalıştım ve hata aldım.

Çünkü derlenmiş kod içinde örneğin "foo()'yu çağır" gibi bir bilgi var ama bağlayıcının elinde bulunan hiçbir program parçasında foo()'nun tanımı yok. Hiçbir şey yapamaz.

Alıntı:

>

g++ main.cpp -o main

Aynı neden: main'in çağırdığı işlevler programı oluştururken kullanılmamış. main.cpp'nin functions.h'yi eklemiş olması hiç yeterli değil çünkü onun bildirdiği işlevlerinin hangi kaynak dosyalarda olduklarını bağlayıcıya söylemiyoruz.

Alıntı:

>

QtCreator gibi bir ide'de yazınca çalıştır diyorsun ve çalışıyor

Çünkü o perde arkasında bütün dosyaları kullanıyor: g++ main.cpp functions.cpp -o main

Alıntı:

>

main'de sadece functions.h yi çağırınca

Hassas konuşmakta yarar var: :) main functions.h'yi olduğu gibi ekliyor ve örneğin factorial() diye bir işlevin varlığını öğreniyor. Böylece, factorial(5) yapıldığında derleme hatası oluşmuyor. Ancak, derlenen kodda yalnızca şu bilgi var: "burada factorial'ı 5 değeri ile çağırıyoruz." O kadarı derleme için yeterli ama programın çalışması sırasında onun factorial'ın gerçek bellek adresine gidecek biçimde değiştirilmesi (bağlanması) gerek.

Alıntı:

>

Terminalde neden 'g++ main.cpp -o main' yazınca çalışmıyor

Tekrarlamak pahasına: Yalnızca main.cpp programı oluşturmak için yeterli değil.

Alıntı:

>

da 'g++ main.cpp functions.cpp -o main' yazınca çalışıyor?

Şimdi bütün tanımlar var.

Alıntı:

>

Çalıştığım kitapta

Hangi kitap?

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 12, 2015

Alıntı (İbrahim):

>

tüm cpp dosyalarını derlemeyle oluşan .o dosyasından

Her .cpp'ye karşılık bir .o oluşuyor; birleştirilerek tek .o oluşmuyor.

Alıntı:

>

cpp'lerin bir kısmını derlemezsek bağlayıcı (linker) mesela fonksiyonun kodlarını .o dosyası oluşmadan bulamıyor

Evet. Ama çok mantıklı, değil mi? Bağlayıcı olmayan şeylerle program oluşturamıyor.

Alıntı:

>

Bu kitap: http://www.kitapyurdu.com/kitap/nesne-yonelimli-c-programlama-kilavuzu/47958.html&filter_name=robert%20lafore sizce iyi midir bu kitap?

ACCU iyi bulmamış:

http://accu.org/index.php?module=bookreviews&func=search&rid=1745

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 12, 2015

Alıntı (İbrahim):

>

Qt bildiğimiz gibi uygulamaları statik derlemeyi yasal kabul etmiyor.

Bundan haberim yok. Acaba eskiden yalnızca dinamik kütüphane mi veriyorlardı?

Alıntı:

>

Statik derleme tam olarak bu .o dosyalarını ve dll gibi dosyaları hep birlikte mi derliyor?

Statik bağlama, bütün işlev tanımlarının programın içine gömülmesidir. Örneğin, çağrılan foo() falanca.a kütüphanesindedir; bağlayıcı foo()'nun tanımını (doğrusu, bütün falanca.a kütüphanesini) programa dahil eder. Program büyük olur ama tanım tam da istenen yerde bulunur.

Sakıncalar: falanca.a kütüphanesini kullanan her program onun bir kopyasını içerir. Programlar büyük olduklarından gerçek belleğe sığma şansları azalır; sistem yavaşlar. (Yararları da var.)

Dinamik bağlamada ise foo()'nun tanımı veya falanca.so programa dahil edilmez. Ancak, foo()'nun hangi kütüphanede bulunduğu programa yazılır. Program başlayınca falanca.so dosyası açılır ve programın belleğinin bir parçasına yazılır.

Sakınca: Programlar daha geç başlarlar çünkü falanca.so'nun bulunması ve belleğe okunması, işlev adreslerinin buna uygun olarak ayarlanması, vs. gerekir. Ama, işletim sistemi her program için ayrı falanca.so açmaz; hepsine aynı gerçek bellek bölgesinden hizmet eder. Böylece programlar bellekte topluca daha az yer kaplarlar.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]