3 puan yazan GN⁺ 2024-10-16 | 1 yorum | WhatsApp'ta paylaş
  • Yeni C standardına uyarlanmış Modern C’nin gözden geçirilmiş sürümü ücretsiz indirilebilir olarak yayımlandı; C dilini öğrenme ve başvuru materyallerini C23 temelinde yeniden değerlendirmek mümkün
  • Revizyonun odağında C23’ün yansıtılması var; ISO’nun yayın süreci ve zamanlamasıyla uyumlu biçimde yeni standarda geçişe yardımcı olmaya odaklanıyor
  • Başlıca derleyicilerin yeni sürümleri C23 özelliklerinin çoğunu şimdiden uyguladığı için, kitaptaki değişiklikler deneysel bir tanıtımın ötesine geçip gerçek kullanım ortamlarıyla bağlantı kuruyor
  • _BitInt(N), nullptr, auto, typeof, constexpr gibi dil ve kütüphane değişiklikleri geniş kapsamlı biçimde yansıtılmış; bunlar mevcut C kodu yazma biçimlerini de etkiliyor
  • Mevcut platformlarda hemen deneme yapılabilmesi için geçişe yönelik ek ve geçici include header’ları eklendi, ancak Manning’in MEAP’i hâlâ devam ediyor

Ücretsiz yayımlanan materyaller ve standart belgeleri

  • Modern C C23 Sürümü ücretsiz olarak indirilebilir
  • Kitaba özel sayfada ilgili materyalleri de bulabilirsiniz
  • Gözden geçirilmiş sürümde birçok açıklama elden geçirilmiş olsa da temel amaç, yeni C standardı olan C23’ü yansıtmak
  • Herkese açık erişilebilen belgeler içinde yeni standardın içeriğine en yakın kaynak N3220 PDF
  • Başlıca derleyicilerin yeni sürümleri, C23’ün getirdiği yeni özelliklerin çoğunu şimdiden uygulamış durumda

C23 dil değişiklikleri ve geçiş desteği

  • Tamsayılarla ilgili değişiklikler önemli bir yer tutuyor
    • Yeni bit kesinlikli tip _BitInt(N) eklendi
    • Taşma denetimli aritmetik ve bit işlemleri için yeni C kütüphanesi header’ları eklendi
    • Modern mimarilerde 128 bit tip olasılığı yansıtıldı
    • enum tiplerinde kayda değer iyileştirmeler de içeriyor
  • C23’ün diğer yeni kavramları da dahil edildi
    • nullptr sabiti ve onun temel tipi
    • attributes aracılığıyla sözdizimsel açıklama ekleme
    • auto ve typeof dahil tip-jenerik programlama araçları
    • Değişken uzunluklu dizilere de uygulanan {} varsayılan başlatma
    • Tüm tiplerde adlandırılmış sabitler için constexpr
  • Yeni materyal; bileşik ifadeleri, lambda’ları, “uluslararasılaştırma”yı ve program hatalarına kapsamlı yaklaşımı da ele alıyor
  • Mevcut platformlarda C23’e hemen başlanabilmesi için ek ve geçici include header’ları eklendi
  • Manning’in yeni sürüm MEAP’i hâlâ açık

1 yorum

 
GN⁺ 2024-10-16
Hacker News görüşleri
  • Benim makinemdeki depolama sırası olan little endianın aksine, en yüksek basamaklı gösterimin önce geldiği yönteme big endian deniyor; ama modern işlemcilerde ikisinin de yaygın kullanıldığını söylemek, s390x dışında pek bir şey kalmadığı için biraz abartı gibi geliyor
    Herkesin sevdiği niş/ölmüş big endian mimarileri yorumları birazdan gelir gibi

    • Arm bi-endian ve çoğu telefonda yaşamaya devam ediyor
      Bir üst yorumdaki gibi, modern demek mutlaka popüler ya da yaygın kullanılıyor demek değildir
    • POWER bi-endian’dır. Güncel Linux on POWER little endian’dır; eskiden big endian Linux on POWER yaygındı ama dağıtımlar birkaç yıl önce geçiş yaptı. Öte yandan AIX ve IBM i big endian’dır
      AIX ve IBM i, IBM mainframe’leri kadar aktif olmayabilir; ancak AIX’in Solaris ya da HP/UX’ten bile daha canlı olduğu söylenebilir, eski pek çok ticari Unix ile kıyaslayınca bu daha da geçerli. IBM i de zar zor ayakta duruyor, ama HP MPE gibi satıcı desteği resmen sona ermiş rakip legacy midrange platformlardan çok daha canlı
    • MIPS tüketici sınıfı ağ donanımlarında hâlâ epey canlı
    • Bir açıdan tüm işlemcilerin bunu yaygın kullandığı da söylenebilir. Çünkü network byte order big endian’dır
    • Sparc big endian değil mi?
  • C’nin en önemli yönü taşınabilirliktir. Küçük mikrodenetleyicilerden neredeyse tüm bilişim platformlarına kadar gidebilmesi işin özü; ama yeni C sürümünün bu kadar benimseneceğinden şüpheliyim
    En ileri olanı kullanmak istesem C yerine C++2x ya da Rust seçerdim. Bir şeyi kaçırıyor muyum? Bu sözde modern C’nin sağladığı avantajın ne olduğunu merak ediyorum

    • C kodu yazmanın avantajlarından biri, idiomatik kodun nasıl görünmesi gerektiği ya da hangi dil alt kümesinin doğru olduğu gibi can sıkıcı tartışmalara girmek zorunda olmamaktır
      En ileri uç için Zig’i öneririm. Modern C++ ve Rust’a göre dil karmaşıklığı çok daha düşük. C23’ün daha az göze çarpan güzel bir yan etkisi de ... = {} ve {0} gibi sözdizimlerini C++ ile daha uyumlu hâle getirerek, C kütüphanesi bakımcılarının C kodunu C++ derleyicisiyle derlemek isteyenleri desteklemesini daha az zahmetli kılması
    • Geçmişte C11, GNU genişletmeleri ve şimdi C23’e giren tekil özelliklerde olduğu gibi sonunda benimsenecek. Örneğin ikili sayı gösterimi 0b, mikrodenetleyici dünyasında yaygın kullanılıyor
      Mikrodenetleyici araç zincirleri genelde GCC üzerine kurulduğu için özellikleri bedavaya alıyor. Her zaman geriden gelen tescilli C derleyicileri de var, ama 20 yıl önceki kadar önemli değiller
    • Bu özellikler sonunda ana akıma sızacak. Bugün C11’in başına gelen de buna benziyor
      Gömülü sistemleri ya da çok geniş bir mimari kümesini hedeflemiyorsanız, bugünden C23 kullanmamanız için bir neden yok
    • thread_local belirteci bazı mikrodenetleyici platformlarında zaten kullanılıyor, ama C11 öncesinde tamamen yasa dışıydı. Yine de iş parçacıklı ortamlarda bellek yönetimini büyük ölçüde basitleştiriyor
      Bunun için özellikle C++ dünyasına girmeye gerek var mı?
    • LLVM/GCC’nin desteklediği bir hedefse yeni C sürümünü de otomatik olarak almıyor musunuz? Yalnızca başka mimariler için satıcının değiştirdiği eski GCC araç zincirlerinde bunu alamazsınız
  • Şahsen guard, defer, auto, constexpr, nullptr gibi şeyler C’yi çok daha karmaşık hâle getiriyor. C’yi sadelik gerektiği için seçiyorum; karmaşıklık istesem genelde istemesem bile C++ seçerim, hatta onun yerine Go’yu ya da sunucu tarafındaysa Elixir’i seçerdim
    _BitInt(N) de çirkin; neyse ki artık bool olan _Boolu hatırlatıyor. constexpr ve nullptr ise fazla C++ kokuyor. Yine de Modern C harika bir kitap ve kullanmaya devam etmeyi düşündüğüm C99 için çok işime yaradı

    • NULLda sorun ne sorusunun yanıtı, ISO standardizasyonunun az sayıdaki avantajlarından biri sayesinde ilgili belgeyi okuyunca ortaya çıkıyor: https://wg21.link/p2312
      Özetle, NULL argümanını tür-jenerik makrolara verdiğinizde şaşırtıcı sonuçlar doğabilir ve (1 ? 0 : NULL) ile (1 ? 1 : NULL) gibi koşullu ifadelerin statüsü NULLın nasıl tanımlandığına göre değişir. Ayrıca işaretçi bekleyen değişken argümanlı bir fonksiyona NULL geçirmek ciddi sonuçlar doğurabilir. Günümüzde birçok mimaride int ile void* boyutları farklı olduğundan, NULL yalnızca 0 ise fonksiyona yanlış boyutta argüman iletilir
    • Karmaşıklığın doğrusal artmadığını düşünüyorum. Aksine, daha karmaşık bir aracın süreci ve nihai sonucu basitleştirdiği çok olur
      Ev inşa etmeye benzer. Çekiç ve tornavida çok basittir, vinç ise aşırı karmaşıktır; ama ev inşa etmeyi basitleştiren vinçtir. Yalnızca çekiç ve tornavidayla ev yapmak için son derece karmaşık bir prosedür tasarlamanız gerekir
      Programlama dilleri de aynıdır. C++’ta jenerik container yapmak önemsizdir, C’de ise çok zordur. void * ve manuel cast ile bir ölçüde taklit edebilirsiniz, ama zahmetlidir, hataya açıktır ve kodu daha karmaşık hâle getirir
      std::sort ve qsort için de durum aynı. Template’lerin ve fonksiyon nesnelerinin gücüyle implementasyon daha basit ve hızlıdır. void * geçirip çalışma zamanında dereference etmek gerekmez, karşılaştırmayı fonksiyon tanımının içine koyabilirsiniz. Dolaylı çağrı yoktur, stack üzerinden geçiş yoktur ve karşılaştırma fonksiyonu inline bile edilebilir. Dil karmaşıklığı implementasyon karmaşıklığı anlamına gelmez
    • auto çoğunlukla tür-jenerik makrolarla uğraşırken faydalıdır, ama normal kodda kullanmamak daha iyi. Bir dönem C++ dünyasında moda olan almost always auto gibi çılgınlıklardan kaçınılmasını umarım
      Ne yazık ki derleyiciler arasında küçük farklar var. Hatırladığım kadarıyla Clang C++ tarzı autoyu, GCC ise C tarzı autoyu implemente etmişti; auto pointer’larda ince bir fark vardı. Bu fark şimdi düzeltildi mi bilmiyorum
      _BitInt(N) genelde doğrudan kullanılmaz, ihtiyaç duyulan genişliğe göre typedef edilerek kullanılır. Örneğin typedef _BitInt(2) u2; gibi. _B gibi çirkin sözdizimleri, alt çizgi ardından büyük harf kombinasyonları C standardında ayrılmış olduğu için, dile küçük bir özellik eklerken mevcut kodla çakışmamak adına gereklidir. _Bool adı da aynı nedenden. Bildiğim kadarıyla defer aslında C23’e girmedi
  • Eski tanım, NULLın işaretçi mi yoksa tamsayı mı olduğunu bile belirtmiyordu. Bu yüzden Posix’in ((void*)0) şartını izlemeyen platformlarda, ne işaretçi türünde ne de işaretçi boyutunda bir mayın gibiydi
    constexpr ve nullptrın C++ kokması muhtemelen C++’tan geri ithal edilmiş olmalarından. Yine de NULL kullanılmaya devam edebilir; görünüşe göre nullptr olarak yeniden tanımlanmış gibi

    • Bu kod hatalı ve bazı mimarilerde çökebilir: execlp("echo", "echo", "Hello, world!", NULL);
      Bu kodda o hata yok: execlp("echo", "echo", "Hello, world!", nullptr);
      Bu da olur: execlp("echo", "echo", "Hello, world!", (char *)NULL);
  • İyi bir C kitap listesi var mı diye soracaktım, cevabı kendim buldum. Burada Modern C orta seviye olarak sınıflandırılıyor
    https://stackoverflow.com/questions/562303/the-definitive-c-...

    • Modern C’yi seviyorum ve birçok yerde iyi değerlendirilmiş. Orta seviye olduğuna katılıyorum
      K&R’ye modern bir C eşlikçisi olarak Ben Klemens’in 21st Century C kitabı ile King’in C Programming: A Modern Approach kitabının daha erişilebilir alternatifler olduğunu düşünüyorum
    • Christopher Preschern’in Fluent C: Principles, Practices and Patterns kitabı da bakmaya değer
    • Bu liste eksiksiz değil. Örneğin Effective C eksik: https://nostarch.com/effective-c-2nd-edition
      Kişisel olarak Effective C’yi Modern C’den daha çok beğeniyorum. Modern C çok titiz; uzmanlar için gerekli olabilecek, dil üzerine açıklamalı bir spesifikasyon okuyormuş hissi veriyor ve benim gibi C’yi daha hafif kullanan biri için okuması sıkıcı
  • Metaware’in High C genişletmelerinden bazıları epey hoşuma gidiyor
    https://news.ycombinator.com/item?id=41647843
    https://news.ycombinator.com/item?id=38938402

  • Son bir yılı aşkın süredir kişisel projem olan bir dil yorumlayıcısında modern C++ kullanıyorum; ama C++’ın zihinsel yükü ve araç sorunları yüzünden sürekli C’ye geçmeyi düşünüyorum. Visual Studio’nun IntelliSense’i C++20 modülleri kullanıldığında hâlâ neredeyse hiç çalışmıyor; dilin başarısızlığı yüzünden çok fazla şey arayüze itilmiş durumda ve derleme süreleri de çirkinleşiyor
    Öte yandan sınıflara, üye fonksiyonlara, generic programminge ve ad alanlarına fazla alıştığım için çoktan tuzağa düşmüşüm gibi de geliyor

    • Uzun süredir C++ kullanıyorum ve C’ye geçmek için destructorlardan vazgeçmeyi hiç düşünmüyorum
      Bu amaç için C#’ı düşündün mü? Visual Studio, C# ile çok daha iyi uyumlu
  • macOS Preview’de kenar çubuğundaki içindekiler bağlantılarına tıklayınca düzgün çalışmıyor

    • zathura PDF okuyucusunda içindekilerdeki birkaç bağlantıyı test ettim; düzgün çalışıyor
    • Şu an içindekiler kısmı kesinlikle bozuk
  • Bakımını yaptığım bir kütüphanede C derleyicilerinin hepsinin C99 desteklediğine güvenebilir hâle gelmem sadece birkaç yıl önce oldu: https://github.com/eyalroz/printf
    Ama birkaç yıl geçer geçmez, kaçınılmaz olarak bazı kadim gömülü araç zincirleri yüzünden C89 uyumluluğu isteyen bir issue açıldı. Yani C23 güzel, ama sanki bunu 20 yıl sonra tekrar konuşalım gibi

  • Pratikte C’nin neden fiilen C99’da takılı kaldığını açıklayan bir yazı linkleyebilecek olan var mı? Konuşmaya değer projeler arasında C11 sonrası özelliklerden yararlanan neredeyse hiç yok

    • C99 hâlâ yeni sayılır. Microsoft, C++’ta da bulunanlar dışında özellikleri uygulamayı reddederek C’yi öldürmeye çalıştı. MSVC, C99 uygulamasında 16 yıl gecikti ve yalnızca asgari düzeyde uyguladı. C11 uygulaması da 11 yıl gecikti
      Onlarca yıl boyunca C fiilen donmuş kaldığı için, kullanıcı kitlesi de C’yi olduğu gibi seven ve antik döküntü derleyici desteğinden rahatsız olmayan kişilerden kendi kendine seçilmiş gibi. Sabrını yitiren ya da 21. yüzyıl dili isteyenler C++/Rust/Zig vb. dillere geçti
    • Microsoft, Visual Studio C derleyicisinde 2015 civarına kadar C99 özelliklerini neredeyse hiç uygulamayarak fiilen C99’u engelledi. 2019’da ise başarısızlığı kabul edip daha yeni C sürümleri için desteği yeniden başlattı. MSVC’nin C front-end’i hâlâ Clang ve GCC’nin istikrarlı biçimde gerisinde
      2010 civarında MSVC hâlâ çok önemliydi; bugün çoğu geliştiricinin Linux’a geçmiş gibi göründüğü bir bakış açısından bu kulağa garip geliyor. Öte yandan C11 özelliklerine mutlaka ihtiyaç duyan proje de pek yok. C11, C99’daki VLA’yı da götürdü; pek de üzülecek bir kayıp değildi. C23, C99’dan bu yana birçok C kod tabanının gerçekten yükseltmeye değer bulabileceği ilk sürüm olabilir