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>34int toplam(int adet,...) {5va_list args;6va_start(args, adet);78int sonuc = 0;9for (int i = 0; i < adet; i++) {10sonuc += va_arg(args, int);11}1213va_end(args);14return sonuc;15}1617int main() {18printf("%d\n", toplam(3, 10, 20, 30)); // 6019printf("%d\n", toplam(5, 1, 2, 3, 4, 5)); // 1520return 0;21}Beklenen çıktı:
160215printf() benzeri format desteğiyle daha gerçekçi bir örnek:
1#include <stdio.h>2#include <stdarg.h>34void log_msg(const char *format,...) {5printf("[LOG] ");6va_list args;7va_start(args, format);8vprintf(format, args);9va_end(args);10printf("\n");11}1213int 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: 9500Sı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.
5 yorum
peki ya format string yanlışsa mesela printf gibiyse tip uyuşmazlığı fark etmiyor mu
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
o yüzden printf de mesela buffer overflow de olabiliyor değil mi yanlış format yazınca
evet format string vulnerability diye ciddi bir açık bu %x ya da %n gibi format
ya %n özellikle tehlikeli çünkü bellekte yazı yazabiliyor format stringi yanlış yazarsan hatta stack üstündeki değerleri okuyabilirsin