Rust’ta C-variadic tanımı hangi ABI’lerde geçerli?

  • Konuyu Başlatan Konuyu Başlatan Görkem
  • Başlangıç tarihi Başlangıç tarihi
  • Cevaplar Cevaplar 0
  • Görüntüleme Görüntüleme 3

Görkem

WFN Üye
Katılım
21 Mar 2025
Mesajlar
1,518
Çözüm
1
Tepki Skoru
23
Ticaret Puanı
0
Üyelik
1 Yıl 6 Ay 17 Gün
Konum
Adıyaman
Web Sitesi
Yok
Alanı
Reklam Al-Sat
1/3
Konu sahibi
Rust’ta C-variadic fonksiyon tanımı, her ABI’de çalışan genel bir özellik değildir; desteklenen ABI ve hedef mimari birleşimine bağlıdır. Doğru sınırı bilmek, derleme hatasını ve FFI uyumsuzluğunu önler.

Bu yazı, önce hangi ABI’lerin variadic tanıma izin verdiğini, sonra hangi hedeflerde bu desteğin geçerli olduğunu ve son olarak güvenli kullanım kurallarını ayırarak anlatır. Böylece aynı özelliğin extern blok bildirimi ile gerçek fonksiyon tanımını karıştırmadan ilerleyebilirsiniz.

Rust’ta C-variadic tanımı nerede geçerlidir?​

Variadic fonksiyonlar Rust’ta yalnızca dış arayüzlerde kullanılır; normal Rust fonksiyonları variadic olamaz. Resmî referans, extern ABI’sinin variadic olabilmesi için belirli ABI'derle sınırlı olduğunu ve işaret edilen ABI dışına çıkılamadığını söyler. Ayrıca fn türü düzeyinde de variadic olabilmek için dış ABI’nin izin verilen ABI'den biri olması gerekir.

ABI sınırını doğru okumak​

Rust referansına göre variadic tanım için temel çerçeve C ailesi ABI’leridir; C ve cdecl güvenli taraftaki ana örneklerdir. system ABI’si ise platforma göre C ile eşlenebilir; Windows’ta variadic davranışın özel eşleşmesi ayrıca belirtilir. Bu yüzden “Rust function item” değil, “extern ABI’li fonksiyon” zihniyetiyle düşünmek gerekir.

Bildirim ile tanımı ayırmak​

Extern blokta variadic bildirim yapılabilir; gerçek fonksiyon tanımıysa hedef ve ABI desteğine tabidir. Referans, ... işaretinin yalnızca dış blok fonksiyonlarının son parametresi olabileceğini belirtir. Bu ayrım önemlidir çünkü bir başlık dosyasını modelleyen bildirim geçerli görünse bile, hedefte gerçek tanım desteklenmeyebilir.

Hangi hedeflerde derlenir?​

Resmî referans, C-variadic fonksiyon tanımlarının hangi hedef mimarilerde kararlı olduğunu ayrıca listeler. Bu listede x86/x86-64, ARM, AArch64, RISC-V’in belirli alt kümeleri, PowerPC aileleri, s390x, wasm32/wasm64 ve bazı diğer hedefler yer alır; bazı hedefler ise açıkça destek dışı kalır. Bu nedenle konu “Rust sürümü var mı?” sorusundan çok “hedef triple bu özelliği destekliyor mu?” sorusudur.

Hedef destek yoksa ne olur?​

Desteklenmeyen bir hedefte tanım kullanılırsa derleyici hata verir. Bu durum özellikle gömülü ya da özel mimarilerde önemlidir; çünkü aynı kaynak kodu masaüstünde derlenip hedefte kırılabilir. Pratik karar ölçütü, FFI yüzeyini yazmadan önce hedefin destek tablosunu kontrol etmektir.

Rust sürümü tek başına yeterli değildir​

Son release notları, bazı ABI’lerde variadic tanım desteğinin zaman içinde stabil hale geldiğini gösteriyor. Bu da sadece “Rust kullanıyorum” demenin yetmediği anlamına gelir; aynı sürümde bile hedef ve ABI kombinasyonu sonucu değiştirebilir. Yani sürüm kontrolü, hedef kontrolünün yerine geçmez.

Güvenli kullanımda hangi kurallar geçerli?​

Variadic fonksiyon tanımları unsafe olmalıdır ve async ya da const olamaz. Ayrıca extern blokta safe bildirim kullanılsa bile, bu yalnızca fonksiyonun variadic argümanlara dokunmadığı durumda anlamlıdır. Başka bir deyişle, güvenli görünen imza gerçek çağrı riskini ortadan kaldırmaz.

Argüman türü uyumu​

Referans, okunan VaList öğesi ile çağrıda geçirilen türün uyumlu olmasını ister. Tam sayılar için boyut uyumu, işaretçiler için hedef tür uyumu önemlidir; aksi durumda tanımsız davranış riski doğabilir. Bu kısım, FFI yazarken “C tarafı zaten anlar” varsayımının doğru olmadığını gösterir.

VaList ile köprü kurma​

Rust’un VaList tipi, C’nin va_list tipiyle ABI uyumludur. Bu, C’den gelen variadic akışı doğrudan başka bir C fonksiyonuna taşıyan ara katmanlar için yararlıdır. Ancak bu uyumluluk, yalnızca ABI uyumlu hedef ve doğru imza ile anlam taşır.

Ne zaman bu yaklaşımı seçmelisiniz?​

Eğer karşı tarafta mevcut bir C API’si zaten variadic ise, Rust tarafında çoğu zaman amacı bu API’yi modellemek olur; yeni bir tasarım olarak variadic seçmek ise genelde daha risklidir. Çünkü tür doğrulaması çağrı anında daha zayıftır ve kullanım kurallarını taşıyan kod daha kırılgan olur. Bu yüzden tercih, çoğunlukla “mevcut FFI’yi doğru sarmala” yönünde olmalıdır.

Kısa karar kuralı​

API C tarafında sabitse ve hedefiniz destekliyorsa variadic tanım mantıklıdır. Yeni bir Rust API tasarlıyorsanız, çoğu durumda sabit imza veya slice/iterator tabanlı bir tasarım daha okunur ve daha güvenlidir. Bu ayrım, sadece derlenebilirlik değil bakım maliyeti açısından da önemlidir.

KontrolAnlamı / uygulanacak adım
ABI seçimiTanım için C / cdecl ve bazı durumlarda system ABI’nin sınırlarını kontrol et; normal Rust ABI variadic olamaz.
Hedef mimariDerleme hedefi C-variadic tanımı desteklemiyorsa kod kabul edilmez; özellikle bazı gömülü/hedef dışı mimarilerde bu sınır geçerlidir.
Tanım mı bildirim miTanım tarafında kısıtlar daha sıkıdır; extern blok içindeki bildirim ile gerçek fonksiyon tanımı aynı şey değildir.
Güvenlik işaretiVariadic kullanımda fonksiyon tanımları unsafe olmalıdır; çağrının doğru argümanlarla yapılması beklenir.
Argüman uyumuOkunan tür ile çağrıda geçirilen tür uyumlu olmalı; özellikle tam sayı ve işaretçi eşleşmelerine dikkat et.
Dönüşümlü kullanımC’nin va_list akışını Rust’taki VaList ile doğrudan geçirmek, FFI köprüsünü sadeleştirir.
 

Sende şimdi bize katılmak ister misin?

Kayıt ol

Bize katılım kolay ve ücretsizdir!

Giriş Yap

Zaten bir hesabınız var mı? Buradan giriş yapın.

Foruma git ?

Bu konuyu görüntüleyen kullanıcılar

İpuçları
Geri
Üst
Kendinize göre özelleştirin

Bazı Topluluk Kısayolları...

Forumda sık kullandığınız alanlara hızlıca ulaşın.

Görünüm Tema Değiş?
Hızlı kısayollar