Paketlenmiş yapılar neden C dilinin bir parçası değildir?


10

Her C derleyicisi, C yapılarını (örn . __attribute__ ((__packed__))Veya #pragma pack()) "paketleme" seçeneği sunar . Artık, verileri güvenilir bir şekilde göndermek veya depolamak istiyorsak, ambalajın gerekli olduğunu hepimiz biliyoruz. Bu, C dilinin ilk günlerinden beri de bir gereklilik olmalıydı.

Öyleyse paketlenmiş yapıların neden C dil spesifikasyonunun bir parçası olmadığını merak ediyorum? Onlara sahip olmanın gerekliliği onlarca yıldır bilinmesine rağmen C99 veya C11'de bile değiller mi? Neyi kaçırdım? Derleyiciye neden özeldir?


2
Onlar değil saf C kodu yazmak için gerekli.
user253751

Yanıtlar:


7

Sanırım çünkü kullanılan hedef CPU / derleyici kombinasyonuna bağlı. Bu, bir dil yönünden bir derleyici yönergesi (bununla ilgili olduğu gibi) olmanın daha iyi olduğu anlamına gelir, çünkü nasıl belirtilir? Bunu yapmanın tek yolu sendika ile.

Raymond'un makalesi bunun neden olduğu konusunda bir fikir veriyor: http://www.catb.org/esr/sttruc-packing/


Çok ilginç bir yazı. (+1)
Giorgio

Kodun "12 bayt tutan bir yapıya ihtiyacım var; X alanı, ofset 0'da dört oktet little-endian olarak depolanan 32 bitlik bir tam sayı gibi davranmalı; Y alanı 64 bitlik bir tam sayı gibi davranmalıdır. ofset 4 "sekizli bayt küçük endian depolanan? Herhangi bir platformda bunu işlemek için kod, derleyicilerin bit alanları için zaten olması gerekenden daha kötü olmamalıdır ve programcının yerel makineyle eşleşen hizalamayı belirtmesi durumunda çok daha verimli olabilir. Diğer makinelerde, daha az verimli ancak yine de taşınabilir olacaktır.
supercat

5

Üç ana faktör vardır.

  1. Bazı işlemciler hizalanmamış verilere erişemez (örneğin tek bir adresten başlayan bir tam sayı veya kayan nokta). Bunu yapmaya çalışmak bir istisnayı tetikler.
  2. Bazı işlemciler hizalanmamış verilere ancak performans maliyetiyle erişebilir.
  3. Çoğu yapıya tek bir C / C ++ kaynak kodu seti ile erişilir ve kural değil, diğer dillerle birlikte çalışabilirlik istisnadır.

Bu faktörler göz önünde bulundurularak, hem standart hem de tüm C / C ++ derleyicileri, işlemci için en uygun hizalamayı sağlamak için rutin olarak yapıları doldurur, ancak aynı zamanda birlikte çalışma amacıyla gerekirse geçersiz kılmak için mekanizmalar sağlar.

Bu kesinlikle gözden kaçan bir şey değildir. Son derece iyi anlaşılmıştır ve mevcut durum tasarım gereğidir. C ++ standardının en son sürümlerinde, belki de bilmediğiniz hizalama sorunlarını ele almak için kapsamlı bir destek vardır.


Paketlenmiş yapılara karşı yapılabilecek herhangi bir argüman, bitfieldleri isteğe bağlı bir özellik haline getirmek için de kullanılabilir. Paketlenmiş yapıların üyelerine erişim bazı işlemcilerde yavaş, diğerlerinde hızlı olacaktır, ancak daha verimli kodla hizalanmamış erişim özelliklerinin olmaması için derleyicilerin kullanıcı kodu geçici çözümlerini değiştirmeye çalışması, derleyicilerin programcıların ihtiyaçları var.
supercat

@supercat: Ne için tartışıyorsun (ya da karşısın)? Anlamıyorum.
david.pfx

Bitfieldlerin isteğe bağlı olması gerektiğine inanıyorum, ancak bitfields zorunlu bir özellik olacaksa, bunları yapı düzeninin açık kontrolüne izin verecek şekilde genişletmek mantıklı olacaktır. Aksi takdirde, net etki, derleyicilerin düzenin tam kontrolü için gerekli olan işin% 90'ını yapması gerektiğidir, ancak programcılar avantajın sadece% 10'unu elde eder.
supercat

@supercat: bit alanları tamsayıdır ve tamsayılarla aynı bit düzeni sıralama kurallarına uyar: uygulama tanımlı. Yapı üyeleri, büyük olasılıkla salmastra yerleştirilmiş olarak beyan edilen karakter sınırlarında sıralanır. Kavramsal olarak oldukça ayrılar. [Teklifinizi genişletmek istiyorsanız başka bir soru sormanız gerekecek, ancak bunun işe yarayacağını düşünmüyorum.]
david.pfx

0

Derleyiciye özgüdür, çünkü standartta değildir. Ve bu standartta değil, çünkü zorlanmış hizalama kısıtlamaları olan belirsiz platformların derleyicileri için çok fazla uygulama çabası gerektirmeyecek şekilde belirtmek zor olurdu.

Ve bu çabaların hiçbirinin pek bir gerekçesi yoktur, çünkü C89 veya daha sonraki bir derleyiciyi kullanan herkesin önemsediği her derleyici / platform zaten uygulanmıştır.


2
??? "Neden standart dilde değil" sorusuna "çünkü standartta değil" diyerek
cevap verdiniz

İlk önce böyle düşündüm, ama sonra tekrar, "yapı 'paketlenmiş' anahtar kelimesi ile tanımlanmışsa, boyutunun her bir üyenin eklenen boyutu ile aynı olduğu garanti edilemez. atanmamış bellek erişimi, yapı üyesi değerlerinden birine erişim tanımlanmamış davranıştır. " Bu, en azından her bir üyenin
yapısını

1
Bir bayt dizisi gibi yapıları uygulayarak ve her alanın değerlerini okumak / yazmak için gerekli bit kaydırma ve &/ |işlemlerini gerçekleştirerek donanımda desteklemeyen sistemlerde hizalanmamış erişimin çalışması mümkün olacaktır .
dan04

1
@ dan04: Birçok işlemcide, bir derleyici, hizalanmamış erişim için bir dizi bayt okuma ve kaydırma dizisinden daha verimli olan kod üretebilir. Bunun için bir sözdizimine sahip olmak, bu tür derleyicilerin verimli kod üretmelerini, programcıların baytları daha uzun türlere birleştirmek için kod yazmaya çalışabilecekleri tüm farklı yolları tanımalarını gerektirmekten daha kolay hale getirecektir.
supercat
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.