Varargs Fonksiyonları Yazma: printf() Benzeri Fonksiyon Tasarımı

C'de bazen fonksiyona kaç parametre geleceğini önceden bilemeyiz. printf() gibi fonksiyonlar bunu nasıl yapıyor? Cevap: varargs mekanizması.

Varargs (variable arguments), stdarg.h kütüphanesi ile sağlanır. Fonksiyon tanımında son parametreden sonra... yazarak değişken sayıda argüman kabul edebilirsin.

Mekanizma şöyle çalışır: Sabit parametrelerden sonra gelen argümanlar stack üzerinde tutulur. va_list ile bu stack üzerinde dolaşırız, va_start ile başlatırız, va_arg ile sıradaki argümanı okuruz, va_end ile temizleriz.

Pratik bir örnek: Sayıları toplayan fonksiyon yazalım. İlk parametre kaç sayı geleceğini gösterir, sonra o kadar sayı gelir.

1#include <stdio.h>
2#include <stdarg.h>
3
4int toplam(int adet,...) {
5va_list args;
6va_start(args, adet);
7
8int sonuc = 0;
9for (int i = 0; i < adet; i++) {
10sonuc += va_arg(args, int);
11}
12
13va_end(args);
14return sonuc;
15}
16
17int main() {
18printf("%d\n", toplam(3, 10, 20, 30)); // 60
19printf("%d\n", toplam(5, 1, 2, 3, 4, 5)); // 15
20return 0;
21}

Beklenen çıktı:

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası
160
215

printf() benzeri format desteğiyle daha gerçekçi bir örnek:

1#include <stdio.h>
2#include <stdarg.h>
3
4void log_msg(const char *format,...) {
5printf("[LOG] ");
6va_list args;
7va_start(args, format);
8vprintf(format, args);
9va_end(args);
10printf("\n");
11}
12
13int main() {
14log_msg("Kullanıcı %s giriş yaptı", "Ali");
15log_msg("ID: %d, Skor: %d", 42, 9500);
16return 0;
17}

Çıktı:

1[LOG] Kullanıcı Ali giriş yaptı
2[LOG] ID: 42, Skor: 9500

Sık yapılan hata: va_end() çağırmazsan bellek sızıntısı yaşayabilirsin. Her va_start() için mutlaka va_end() yaz. Ayrıca varargs fonksiyonunda tür kontrolü olmaz, yanlış tip geçirirsen undefined behavior oluşur. Format string kullanırken dikkatli ol.

Varargs güçlü ama tehlikeli bir araçtır. Modern C'de type safety için printf() yerine compile-time format checking sunan derleyici extensions tercih edilir.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz

5 yorum

  • adlı kullanıcıya yanıt verdi
    kayipkumanda

    o yüzden printf de mesela buffer overflow de olabiliyor değil mi yanlış format yazınca

  • kayipkumanda

    peki ya format string yanlışsa mesela printf gibiyse tip uyuşmazlığı fark etmiyor mu

  • adlı kullanıcıya yanıt verdi
    kayipkumanda

    ya %n özellikle tehlikeli çünkü bellekte yazı yazabiliyor format stringi yanlış yazarsan hatta stack üstündeki değerleri okuyabilirsin

  • adlı kullanıcıya yanıt verdi
    kodkafasi

    evet format string vulnerability diye ciddi bir açık bu %x ya da %n gibi format

  • adlı kullanıcıya yanıt verdi
    kodkafasi

    aynen format string yanlışsa hiçbir şey anlamıyor mesela %d yerine %s yazıp int gönderirsen program o bellek adresine string gibi bakıyor çöp görür