ทำไมโครงสร้างที่อัดแน่นจึงไม่ได้เป็นส่วนหนึ่งของภาษา C


10

คอมไพเลอร์ C ทุกตัวมีตัวเลือกในการ "แพ็ค" โครงสร้าง C (เช่น__attribute__ ((__packed__))หรือ#pragma pack()) ตอนนี้เราทุกคนรู้ว่าจำเป็นต้องมีการบรรจุถ้าเราต้องการส่งหรือเก็บข้อมูลด้วยวิธีที่เชื่อถือได้ สิ่งนี้จะต้องเป็นข้อกำหนดตั้งแต่วันแรกของภาษา C

ดังนั้นฉันสงสัยว่าทำไมโครงสร้างที่อัดแน่นจึงไม่ได้เป็นส่วนหนึ่งของข้อกำหนดภาษา C? พวกเขาไม่ได้อยู่ใน C99 หรือ C11 ถึงแม้ว่าความจำเป็นในการมีพวกเขาเป็นที่รู้จักกันมานานหลายทศวรรษแล้วหรือยัง? ฉันกำลังคิดถึงอะไร ทำไมคอมไพเลอร์จึงเจาะจง?


2
พวกเขาไม่จำเป็นต้องเขียนรหัส C บริสุทธิ์
user253751

คำตอบ:


7

ฉันเดาว่าเป็นเพราะมันขึ้นอยู่กับการรวมกันของ CPU / คอมไพเลอร์เป้าหมายที่ใช้ ซึ่งหมายความว่าเป็นการดีกว่าที่จะเป็นคอมไพเลอร์คำสั่ง (ตามที่เกี่ยวข้องกับที่) กว่าด้านภาษาเพราะวิธีการสเป็คที่? วิธีเดียวที่พวกเขาทำได้คืออยู่กับสหภาพ

บทความของ Raymond ให้ข้อมูลเชิงลึกว่าทำไมจึงเป็นเช่นนี้: http://www.catb.org/esr/structure-packing/


บทความที่น่าสนใจมาก (+1)
Giorgio

จะมีปัญหาอะไรในการอนุญาตให้โค้ดบอกว่า "ฉันต้องการโครงสร้างที่มีขนาด 12 ไบต์; ฟิลด์ X จะต้องทำงานเป็นจำนวนเต็ม 32- บิตที่เก็บเป็นสี่ออคเต็ตเล็ก ๆ น้อย ๆ ที่อ็อฟเซ็ตที่ออฟเซ็ต 0; เก็บไว้เป็น octets by little-endian ที่ offset 4 "? โค้ดที่ใช้จัดการกับแพลตฟอร์มใด ๆ ไม่ควรเลวร้ายไปกว่าประเภทของคอมไพเลอร์ที่มีอยู่แล้วสำหรับบิตฟิลด์และในกรณีที่โปรแกรมเมอร์เกิดขึ้นเพื่อระบุการจัดตำแหน่งที่ตรงกับเครื่องจักรดั้งเดิมอาจมีประสิทธิภาพมากกว่า สำหรับเครื่องอื่นมันจะมีประสิทธิภาพน้อยลง แต่ยังพกพาได้
supercat

5

มีสามปัจจัยหลัก

  1. โปรเซสเซอร์บางตัวไม่สามารถเข้าถึงข้อมูลที่ไม่ได้จัดแนว (ตัวอย่างเช่นจำนวนเต็มหรือทศนิยมเริ่มต้นจากที่อยู่แปลก ๆ ) ความพยายามที่จะทำให้เกิดข้อยกเว้น
  2. โปรเซสเซอร์บางตัวสามารถเข้าถึงข้อมูลที่ไม่ได้จัดแนว แต่มีค่าใช้จ่ายด้านประสิทธิภาพ
  3. โครงสร้างส่วนใหญ่เข้าถึงได้โดยซอร์สโค้ด C / C ++ ชุดเดียวและการทำงานร่วมกันกับภาษาอื่นเป็นข้อยกเว้นไม่ใช่กฎ

เมื่อคำนึงถึงปัจจัยเหล่านี้ทั้งโครงสร้างมาตรฐานและคอมไพเลอร์ C / C ++ ทุกแผ่นโครงสร้างเป็นประจำเพื่อให้แน่ใจว่ามีการจัดตำแหน่งที่เหมาะสมที่สุดสำหรับโปรเซสเซอร์

นี่ไม่ใช่สิ่งที่ถูกมองข้าม เป็นที่เข้าใจกันเป็นอย่างดีและสถานการณ์ปัจจุบันเกิดจากการออกแบบ เวอร์ชันล่าสุดของมาตรฐาน C ++ มีการสนับสนุนอย่างกว้างขวางสำหรับการจัดการปัญหาการจัดตำแหน่งซึ่งบางทีคุณอาจไม่คุ้นเคย


อาร์กิวเมนต์ใด ๆ ที่สามารถสร้างขึ้นจากโครงสร้างที่ถูกบีบอัดสามารถใช้เพื่อพิสูจน์ว่าการสร้าง bitfields เป็นคุณสมบัติเสริม การเข้าถึงสมาชิกของโครงสร้างที่ถูกบีบอัดจะช้าในโปรเซสเซอร์บางตัวเร็วในตัวอื่น ๆ แต่การที่คอมไพเลอร์พยายามแทนที่วิธีแก้ไขปัญหารหัสผู้ใช้เนื่องจากการขาดคุณสมบัติการเข้าถึงที่ไม่ได้รับการจัดการด้วยโค้ดที่มีประสิทธิภาพมากกว่านั้นซับซ้อนกว่า พวกเขาต้องการ.
supercat

@supercat: คุณโต้เถียงอะไร (หรือต่อต้าน)? ฉันไม่เข้าใจ
david.pfx

ฉันเห็นว่า bitfields ควรเป็นทางเลือก แต่ถ้า bitfields เป็นคุณลักษณะที่จำเป็นต้องใช้มันก็สมเหตุสมผลที่จะขยายออกไปในลักษณะที่ช่วยให้สามารถควบคุมเค้าโครง layout ได้อย่างชัดเจน มิฉะนั้นผลกระทบสุทธิคือคอมไพเลอร์ต้องทำงาน 90% ของงานที่จะต้องใช้สำหรับการควบคุมการจัดวางอย่างเต็มรูปแบบ แต่โปรแกรมเมอร์เขียนเพียง 10% ของผลประโยชน์
supercat

@supercat: บิตฟิลด์เป็นจำนวนเต็มและปฏิบัติตามกฎการเรียงลำดับบิตเลย์เอาต์เป็นจำนวนเต็ม: มีการนำไปปฏิบัติ สมาชิกโครงสร้างได้รับคำสั่งในขอบเขตของตัวละครตามที่ประกาศไว้อาจจะมีการแทรกการบรรจุ พวกเขาแยกทางความคิดค่อนข้าง [คุณจะต้องถามคำถามอื่นถ้าคุณต้องการขยายข้อเสนอของคุณ แต่ฉันไม่คิดว่ามันจะใช้ได้เลย]
david.pfx

0

มันเป็นคอมไพเลอร์เฉพาะเพราะมันไม่ได้อยู่ในมาตรฐาน และมันไม่ได้อยู่ในมาตรฐานเพราะเป็นการยากที่จะระบุในแบบที่ไม่ต้องใช้ความพยายามในการติดตั้งจำนวนมากสำหรับคอมไพเลอร์ของแพลตฟอร์มที่ไม่ชัดเจนด้วยข้อ จำกัด ในการจัดตำแหน่งที่บังคับใช้

และไม่มีความพยายามใดที่มีเหตุผลมากนักเพราะคอมไพเลอร์ / แพลตฟอร์มที่ทุกคนที่ใช้ C89 หรือคอมไพเลอร์รุ่นใหม่กว่านั้นใส่ใจกับมันแล้ว


2
??? คุณตอบคำถาม "ทำไมไม่อยู่ในภาษามาตรฐาน" โดยพูดว่า "เพราะไม่ได้อยู่ในมาตรฐาน" ...
Emilio Garavaglia

นั่นคือสิ่งที่ฉันคิดไว้ก่อน แต่จากนั้นอีกครั้งหนึ่งสามารถระบุคุณสมบัติเช่น "ถ้า struct ถูกกำหนดด้วยคำหลัก 'อัดแน่น' ขนาดจะรับประกันว่าจะเท่ากับขนาดเพิ่มของสมาชิกแต่ละคนบนแพลตฟอร์มที่ไม่สนับสนุน การเข้าถึงหน่วยความจำที่ไม่ได้ลงทะเบียนการเข้าถึงหนึ่งในค่าสมาชิก struct คือพฤติกรรมที่ไม่ได้กำหนด " นี้จะช่วยให้นักพัฒนาบนแพลตฟอร์มโดยไม่ต้องเข้าถึงแบบไม่ระบุชื่ออย่างน้อยก็รู้ขนาดของโครงสร้างและออฟเซ็ตของสมาชิกแต่ละคน ...
grasbueschel

1
มันจะเป็นไปได้ที่จะทำให้การทำงานการเข้าถึง unaligned ในระบบที่ไม่สนับสนุนมันในฮาร์ดแวร์โดยการใช้ structs เช่นอาร์เรย์ไบต์และมีประสิทธิภาพบิตขยับและจำเป็น&/ |การดำเนินงานในการอ่าน / เขียนค่าของแต่ละเขต
dan04

1
@ dan04: สำหรับโปรเซสเซอร์จำนวนมากคอมไพเลอร์สามารถสร้างโค้ดสำหรับการเข้าถึงที่ไม่ได้แนวซึ่งมีประสิทธิภาพมากกว่าการใช้ลำดับของการอ่านและกะไบต์ การมีไวยากรณ์สำหรับสิ่งนั้นจะทำให้ง่ายขึ้นสำหรับคอมไพเลอร์ดังกล่าวในการสร้างโค้ดที่มีประสิทธิภาพมากกว่าการกำหนดให้พวกเขารู้จักวิธีต่าง ๆ ที่โปรแกรมเมอร์อาจลองเขียนโค้ดเพื่อรวบรวมไบต์เป็นประเภทที่ยาวขึ้น
supercat
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.