---
title: 'Derleyici Uyarıları ve Standartlar'
source: 'https://academia.sh/tr/kurslar/c-temelleri/derleyici-uyarilari-ve-standartlar'
course: 'C Temelleri'
language: tr
updated: '2026-09-13T05:07:32+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Bir uyarının neden yalnız derleyici aşamasında doğabileceğini gerekçelendirir'
    - 'Standardın garanti ettiği ile uygulamaya bıraktığı davranışı bir örnekle ayırt eder'
    - 'Uyarısız derlenmenin doğruluk garantisi olmadığını çalışan bir örnekle gösterir'
---

# Derleyici Uyarıları ve Standartlar

Bir uyarı yalnız derleyici aşamasında doğabilir, çünkü yalnız o aşama tek bir birimin içindeki tipleri ve ifadeleri görür. Standardın garanti ettiği ile uygulamaya bıraktığı yan yana konuyor — sizeof(char) == 1 garantidir, öteki boyutlar değildir. Uyarısız derlenen bir programın doğru olduğu da söylenemez; bunu göstermek için uyarı basmayan ama yanlış bir sonuç üreten bir hesap koşturuluyor.

Önceki ders ön işlemcinin dört kararını derinleştirdi ve kapanışta bir gözlemi öne çıkardı:
bu dört ders boyunca hiçbir kod bloğu bir uyarı bırakmadı, ama bu tesadüf değil, elle
sağlanan bir tutarlılıktı. Bu ders o tutarlılığın nasıl denetlendiğine bakıyor — bir
uyarının hangi aşamada doğduğuna ve standardın neyi garanti edip neyi uygulamaya
bıraktığına. Kurs, açılışında dört aşamayı adlandırmıştı; bu son ders o dört adı bir kez
daha kullanıyor, ama bu kez bir "karar" değil bir "denetim" için: dört aşamadan yalnız
biri, kendi girdisinin sınırları içinde kalarak, kaynağın **muhtemelen** yanlış olduğunu
düşünebiliyor. Bu dersin ölçtüğü, o düşüncenin doğduğu yer ve o düşüncenin ne kadar
güvenilir olduğudur.

## Uyarı Nerede Doğar

Bir uyarı yalnız derleyici aşamasında doğabilir. Ön işlemci tip bilmediği için bir tipin
yanlış kullanıldığını fark edemez — onun elinde yalnız metin var. Bağlayıcı yalnız adları
eşler, bir ifadenin içeriğini hiç incelemez. Koşum ise kaynağın kendisini artık taşımıyor;
elindeki yalnız veri, uyaracağı bir şey yok. Derleyici ise tam olarak bunun tersini yapıyor
— tek bir birimin içindeki her ifadenin tipini, her değişkenin kullanımını, her denetim
yolunun hangi değeri döndürdüğünü görüyor ve bu görüşün sonucunda bir şeyin **şüpheli**
olduğunu düşünebiliyor.

Bu, Derleme Aşamaları dersindeki gözlemin bir uzantısı: dört aşamanın her biri yalnız kendi
girdisine bakıyordu ve bir hatanın nerede yakalanacağı da bu girdiyle sınırlıydı. Uyarı,
tam olarak derleyicinin kendi girdisinin sınırları içinde kalan bir denetimdir — yalnız
tek bir birime bakarak fark edebileceği bir şeyi işaretler. Bir hata birden çok birim
arasında yayılıyorsa (Başlık Dosyaları dersindeki bildirim/tanım uyuşmazlığı gibi),
derleyicinin bunu bir uyarıyla yakalaması da mümkün değildir — çünkü o hata, derleyicinin
girdisinin tamamen dışında kalır.

Şüpheli olmak yanlış olmakla aynı şey değildir. Bir uyarı tipik olarak şu kalıplardan birine
işaret eder: bir sabit değerin taşıyamayacağı kadar dar bir tipe doğrudan atandığı, bir
değişkenin tanımlandığı ama hiç kullanılmadığı, işaretli bir sayıyla işaretsiz bir sayının
doğrudan karşılaştırıldığı, ya da bir işlevin döndürmesi beklenen bir değeri bazı yollarda
hiç döndürmediği. Dördü de aynı özelliği taşır: kaynak **derlenebilir** durumdadır, ama
derleyici, tek bir birimin içindeki tipleri ve akışı görerek, kendi gördüğü kalıptan bir
risk çıkarmıştır.

Bu dört kalıbın ortak noktası, hiçbirinin kendi başına bir hata **olmamasıdır**. Kullanılmayan
bir değişken kaynağın çalışmasını engellemez; işaretli bir sayıyla işaretsiz bir sayının
karşılaştırılması geçerli bir C ifadesidir; bir işlevin bazı yollarda değer döndürmemesi
kaynağı derlenemez kılmaz. Derleyici bu kalıpların hiçbirini **reddetmiyor**, yalnız
işaretliyor — çünkü her biri, programcının aslında istemediği bir şeyin **belirtisi**
olabilir, ama olmak zorunda da değildir. Bu, uyarının neden isteğe bağlı bir bayrakla
(`-Wall`, `-Wextra` gibi) açılması gerektiğini de açıklıyor: standart, derleyicinin hangi
kalıpları şüpheli sayacağını belirlemez, yalnız programın hangi kalıplarla **derlenebilir**
kalacağını belirler.

Bu kursun bütün kod örnekleri bu dört kalıptan kaçındı, ama kaçınmak elle yapılan bir
seçimdi — dilin kendisi hiçbir örneği bu kalıplara girmekten alıkoymadı. Bu konudaki yirmi
bir kod bloğunun hepsi uyarısız kaldıysa, bunun nedeni derleyicinin cömert davranması
değil, her değişkenin kullanılması, her karşılaştırmanın aynı işaretteki tiplerle
yapılması, her işlevin her yolda bir değer döndürmesiydi.

Bu tutarlılığı sağlamak, kursun kalan bölümünde de aynı yükümlülük olarak kalacak. Bir
uyarı çıkardığında, o uyarı kaynaktaki tek bir birime, tek bir ifadeye işaret eder — kaynağı
düzeltmenin ilk adımı, uyarının hangi birime ait olduğunu bilmektir. Bu da uyarının neden
derleyici sınıfına bu kadar sıkı bağlı olduğunu bir kez daha doğruluyor: bir uyarı, ancak
onu doğuran birim yeniden derlenince kaybolur; başka hiçbir aşamanın onu susturmaya gücü
yetmez.

## Ne Garanti, Ne Değil

C standardı (C17) bazı şeyleri kesin olarak garanti eder, bazılarını uygulamaya bırakır.
Aradaki fark koşturarak gösterilebilir — ama yalnız garanti edilen tarafı, çünkü garanti
edilmeyen bir sayı bu kursun hiçbir yerinde basılmaz.

Bu ayrım rastgele değil, dilin donanıma yakınlığının doğrudan sonucu. Dört ayrı donanım
dört ayrı tam sayı genişliği sunabilir; standart, dilin her donanımda çalışabilmesi için
kesin bir genişlik dayatmak yerine bir **alt sınır** dayatıyor ve gerisini derleyiciye,
dolayısıyla dolaylı olarak donanıma bırakıyor. `int`in bu makinede kaç bayt olduğu bu
yüzden dilin bir sözü değil, derleyicinin bir kararıdır — ve bu kurs boyunca hiçbir yerde
basılmayan bir gözlemdir.

```c
// garanti.c — standardin garanti ettigi ile birakmadigi yan yana
#include <limits.h>
#include <stdio.h>

int main(void) {
    printf("sizeof(char) == 1: %s\n", (sizeof(char) == 1) ? "dogru" : "yanlis");
    printf("CHAR_BIT >= 8: %s\n", (CHAR_BIT >= 8) ? "dogru" : "yanlis");
    printf("INT_MAX >= 32767: %s\n", (INT_MAX >= 32767) ? "dogru" : "yanlis");
    printf("LONG_MAX >= 2147483647: %s\n", (LONG_MAX >= 2147483647L) ? "dogru" : "yanlis");
    return 0;
}
```

```
sizeof(char) == 1: dogru
CHAR_BIT >= 8: dogru
INT_MAX >= 32767: dogru
LONG_MAX >= 2147483647: dogru
```

**DD13.** Dört satırın dördü de bir **karşılaştırmanın sonucunu** basıyor, hiçbiri ham bir
sayıyı basmıyor. `sizeof(char)`, `CHAR_BIT`, `INT_MAX`, `LONG_MAX`in kendi değerleri
uygulamaya göre değişebilir — standart yalnız bir **alt sınır** garanti eder, üst sınırı
serbest bırakır. `int`in gerçekte kaç bayt olduğu, `long`un gerçekte kaç bit taşıdığı bu
kursun hiçbir yerinde basılmadı ve basılmayacak; basılan yalnız "bu değer en az şu kadardır"
sorusunun `dogru`/`yanlis` yanıtı, çünkü bu yanıt standarda uygun her C17 derleyicisinde
aynıdır.

Bu dört satırın hepsi `dogru` çıktı, çünkü hepsi gerçekten garanti edilen alt sınırlar.
Standardın garanti **etmediği** şey ise satırlarda hiç görünmüyor: `sizeof(int)`in tam
değeri, `int`in `short`tan gerçekten daha geniş olup olmadığı, `char`ın imzasız mı imzalı
mı sayıldığı. Bunların hepsi uygulamaya bırakılmıştır ve bu yüzden bu kursun hiçbir
dersinde koşturulmadı.

Alt sınır ile üst sınır arasındaki bu fark, kursun daha önce gördüğü "garanti ile kesit"
ayrımına benziyor: bir başlık dosyası bir bildirimi paylaşabiliyordu, ama tanımın onunla
uyuşacağını garanti etmiyordu (Başlık Dosyaları dersi); burada da standart bir alt sınır
veriyor, ama gerçek değerin o sınırın neresinde duracağını garanti etmiyor. İkisinde de
aynı örüntü tekrar ediyor: dilin verdiği söz her zaman bir **asgari**dir, üstüne ne
eklendiği uygulamaya, yani derleyiciye ve donanıma kalır.

Bu dört satırın hiçbiri bir uyarı da doğurmadı ve bu tesadüf değil. `CHAR_BIT >= 8` gibi bir
karşılaştırma, iki sabit ifadenin karşılaştırılmasıdır ve derleyici bunu şüpheli bulacak bir
kalıp görmüyor — karşılaştırmanın iki tarafı da aynı geniş tam sayı sınıfına ait, işaretli
ile işaretsiz arasında bir karışıklık yok, bir değer daralmıyor. Standardın garanti ettiği
tarafı ölçmek bu yüzden hem doğru hem güvenli: ne ortama bağlı bir sayı sızdırıyor, ne de
derleyicinin şüphelendiği bir kalıba giriyor.

Bu ayrımın pratik bir sonucu var: bir kaynak, yalnız standardın **garanti ettiği** taraf
üzerine kurulduğunda, hangi derleyiciyle ve hangi donanımla derlendiğinden bağımsız olarak
aynı sonucu verir. `sizeof(char) == 1` her yerde `dogru`dur, çünkü standart bunu zaten
zorunlu kılmıştır. Ama bir kaynak `sizeof(int) == 4` gibi bir varsayıma dayansaydı, bu
varsayım bazı uygulamalarda doğru, bazılarında yanlış çıkabilirdi — ve derleyici bu
varsayımı kaynakta göremeyeceği için, yanlış çıktığı yerde de bir uyarı basmazdı. Yalnız
garanti edilen tarafa dayanan bir kaynak, hangi derleyiciyle ve hangi donanımla
derlendiğinden bağımsız olarak doğruluğunu korur; garanti edilmeyen bir tarafa dayanan bir
kaynak ise, derleyici hiçbir uyarı basmasa bile, farklı bir donanımda sessizce yanlış
sonuç verebilir.

## Sınırlayıcı Ölçüm

Bir uyarı bir hata değildir; derleyici uyarı bastıktan sonra bile programı derlemeye devam
eder ve program çalışır. Bunun aynadaki yansıması da doğrudur: uyarısız derlenen bir
programın doğru olduğu **söylenemez**. Bu iki cümle birlikte, uyarının ne olduğunu değil,
ne **olmadığını** tanımlıyor: bir uyarı ne bir hata kanıtıdır, ne yokluğu bir doğruluk
kanıtıdır — yalnız derleyicinin fark ettiği şeyler hakkında bir bilgidir, o kadar.
Aşağıdaki program hiçbir uyarı bırakmadan derlenir, ama ikinci satırı beklenmeyen bir
sonuç verir.

```c
// oran.c — uyarisiz derlenen bir program dogru oldugunu garanti etmez
#include <stdio.h>

int main(void) {
    int parca = 2;
    int toplam = 5;

    int tamsayi_oran = parca / toplam * 100;
    double kayan_oran = (double)parca / toplam * 100;

    printf("tam sayiyla hesaplanan oran: %d\n", tamsayi_oran);
    printf("kayan noktayla hesaplanan oran: %.1f\n", kayan_oran);

    return 0;
}
```

```
tam sayiyla hesaplanan oran: 0
kayan noktayla hesaplanan oran: 40.0
```

**DD14.** İki satır da aynı iki sayıdan (`2` ve `5`) yola çıkıyor ve ikisi de derleyiciden
tek bir uyarı almadı. Ama `tamsayi_oran` `0` verdi, çünkü `parca / toplam` iki `int`
arasında yapıldı ve `2 / 5` sıfıra doğru yuvarlanarak `0` verdi — çarpma `100`le ondan sonra
geldi ve zaten sıfır olan bir sayıyı yüz katına çıkarmak yine sıfır verdi. `kayan_oran` ise
`parca`yı önce `double`a çevirdiği için bölme kayan noktalı aritmetikte yapıldı ve doğru
oranı, `40.0`ı verdi. Derleyici bu ikisinden hiçbirini "yanlış" bulmuyor, çünkü ikisi de
kendi tipiyle tutarlı: `int / int` işleminin sonucunun `int` olması C'nin bir kuralı, bir
hata değil — bu kursun ikinci dersinde `7 / 2` ile `7 / 2.0` arasındaki fark olarak zaten
görüldü.

Kaynakta `tamsayi_oran`ı düzeltmenin yolu, tıpkı `kayan_oran`da olduğu gibi, bölmeden önce
taraflardan birini `double`a çevirmektir — programın çalıştırdığı işlem aynı kalır, yalnız
hangi aritmetiğin kullanılacağı kaynakta açıkça belirtilir. Derleyici bu düzeltmeyi
öneremez, çünkü önermek için "programcı burada bir oran istiyordu" bilgisine ihtiyaç duyar
ve bu bilgi hiçbir yerde yazılı değildir. Derleyicinin görebildiği tek şey, iki ifadenin de
kendi tipiyle tutarlı olduğudur.

Bu, dilin verdiği bir güvenceyle programcının verdiği bir kararı birbirinden ayırıyor. Dil
`int / int`in `int` vereceğini garanti ediyor ve bunu tutarlı biçimde uyguluyor — derleyici
burada hiçbir şeyi ihlal etmiyor. Yanlış olan, iki tam sayının bölümünün bir **oran**
taşıyacağını varsaymak; bu varsayım kaynakta hiçbir yerde yazılı değil, yalnız programcının
zihnindeydi. Derleyici zihinde olanı göremez, yalnız kaynakta yazılanı görür — ve kaynakta
yazılan, tamamen tutarlı, tamamen uyarısız bir `int` bölmesiydi.

Bu, dört ders boyunca kurulan bir örüntünün son halkası: her aşama yalnız kendi girdisine
bakar ve kendi girdisinde tutarlı olan her şeyi kabul eder. Ön işlemci metni tutarlı buldu,
derleyici tipleri tutarlı buldu — ama tutarlılık doğrulukla aynı şey değildir. `tamsayi_oran`
değişkeni derleyicinin gözünden kusursuzdur; bir programcının gözünden ise muhtemelen bir
hatadır. Bu ikisi arasındaki boşluk, hiçbir aşamanın dolduramayacağı bir boşluktur — onu
yalnızca kaynağı yazan doldurabilir.

Bu, beş ders boyunca kurulan çerçevenin son dersi için de doğru olan bir sonuç: dört
aşamanın hiçbiri, kaynağın **doğru** olduğunu kanıtlamaz — yalnız kendi aşamasına özgü bir
tutarlılığı denetler. Ön işlemci metnin biçimini denetler, derleyici tipleri ve akışı
denetler, bağlayıcı adları denetler, koşum ise yalnız verdiği veriyle çalışır. Dördü birden
geçildiğinde elde edilen şey, çalışan bir programdır — ama çalışan bir programın **istenen**
programla aynı olduğunu söyleyen hiçbir aşama yoktur.

## Özet

- Bir uyarı yalnız derleyici aşamasında doğabilir; yalnız bu aşama tek bir birimin içindeki
  tipleri ve ifadeleri görüp bir kalıbı şüpheli bulabilir.
- Bir uyarı bir hatayla aynı şey değildir: program uyarıyla birlikte de derlenir ve çalışır.
- Standart bazı şeyleri kesin garanti eder (`sizeof(char) == 1`, `CHAR_BIT >= 8`), bazılarını
  uygulamaya bırakır (gerçek tip boyutları); bu kurs yalnız garanti edileni bastı.
- Uyarısız derlenen bir program doğru olduğunu göstermez: `int / int` bölmesi dilin bir
  kuralıdır, ama sonucu bir oran sanmak programcının kaynakta yazmadığı bir varsayımdır.
- Standardın verdiği söz her zaman bir asgaridir; üstüne ne eklendiği derleyiciye ve
  donanıma kalır, bu yüzden bu kurs boyunca yalnız asgari, garanti edilen taraf koşturuldu.
- Dört aşamanın hiçbiri kaynağın doğru olduğunu kanıtlamaz; her biri yalnız kendi aşamasına
  özgü bir tutarlılığı denetler, çalışan bir programla istenen program arasındaki farkı
  yakalamak dilin değil kaynağı yazanın işidir.

## Sonraki Adım

Bu, Dil ve Derleme konusunun son dersidir. Beş ders aynı çekirdekten, aynı dört sınıftan
geçti ve her biri ayrı bir köşeyi aydınlattı. C'nin Konumu çekirdeği tam koşturdu ve on dört
gözlemin 4/4/3/3 dağılımıyla dört aşamanın adını koydu. Derleme Aşamaları aynı dört sınıfı
küçük bir kesitle yan yana koşturup her birinin hangi girdiye baktığını gösterdi ve
aşamaların geri dönüşü olmayan bir sırayla çalıştığını kanıtladı. Başlık Dosyaları bildirim
ile tanımı ayırdı ve bir başlığın aynı bildirimi birden çok birime nasıl taşıdığını, çifte
içerme korumasının neyi engellediğini gösterdi. Ön İşlemci dört ayrı yönergenin aslında tek
bir işin — metin ikamesinin — görünümü olduğunu ortaya koydu ve bir makronun argümanını
birden çok kez yerine koyabildiğini kanıtladı. Bu son ders beşinci köşeye baktı: bir
uyarının yalnız derleyicide doğabildiğini ve uyarısız derlenmenin doğruluk garantisi
olmadığını.

Beş dersin ortak paydası, hiçbirinin öbürünün ölçtüğü şeyi tekrar ölçmemesiydi — her biri
aynı dört adı kullandı, ama her biri kendi sorusunu sordu. Bu ortak payda kursun geri
kalanında da sürecek: Temel Sözdizim konusunun sekiz dersi de aynı dört sınıfı kullanacak,
ama her biri C'nin farklı bir köşesine — tiplere, değişkenlere, işleçlere, denetim akışına,
fonksiyonlara, dizilere, kayıt tiplerine, girdi ve çıktıya — bakacak.

Temel Sözdizim konusu bu çerçeveyi değiştirmiyor, ona C'nin kendi tiplerini, değişkenlerini
ve işleçlerini ekliyor; ilk soru, bir tipin taşıdığı değerlerin hangi aşamada karara
bağlandığıdır.
