เหตุใดขนาดของชื่อผู้ดำเนินการรวบรวมเวลา


12

แต่เดิมนี่เป็นส่วนหนึ่งของคำถามอื่น

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


4
ตอบในรายละเอียดที่ SO: ทำไมขนาดของ (x ++) ไม่เพิ่มขึ้น x
ริ้น

3
คุณคาดหวังว่าขนาดของประเภทที่จะเปลี่ยนแปลงที่รันไทม์?

@MichaelT: ขนาดของอินสแตนซ์ของประเภทสามารถเปลี่ยนแปลงได้อย่างแน่นอน - มีความแตกต่างระดับหลังจากทั้งหมด ฉันยืนยันว่าsizeof(polymorphic_ptr*)ค่าคงที่ค่อนข้างตอบโต้ได้ง่ายและไร้สาระ ใช่มันเป็นวิธี C ++ แต่ยังงี่เง่า
Reinstate Monica

@KubaOber แน่นอน ฉันแค่อยากรู้ว่า OP คิดว่ามันควรจะทำงานในกรณีที่แตกต่างกันอย่างไรและหวังว่าจะได้รหัสที่จะแสดงให้เห็นถึงความสับสนของเขาในเรื่องนี้เพื่อช่วยขยายคำถาม

4
มา upvote คำตอบ "เพราะมันทำงานในเวลารวบรวม" ทำให้ผิดหวัง
Ben Jackson

คำตอบ:


23

sizeof()ให้ขนาดของชนิดข้อมูลไม่ใช่ขนาดของอินสแตนซ์เฉพาะของประเภทนั้นในหน่วยความจำ

ตัวอย่างเช่นถ้าคุณมีวัตถุข้อมูลสตริงที่จัดสรรอาร์เรย์อักขระขนาดตัวแปรที่รันไทม์sizeof()ไม่สามารถใช้เพื่อกำหนดขนาดของอาร์เรย์อักขระนั้น มันจะให้ขนาดของตัวชี้เท่านั้น

ขนาดของชนิดข้อมูลเป็นที่รู้จักกันเสมอในเวลารวบรวม


3
เนื่องจาก C (++) ไม่มีข้อมูลเมตาของวัตถุขณะใช้งานคุณจึงไม่สามารถรับสิ่งเหล่านั้นในเวลาทำงานได้เช่นกัน
C. Ross

5
ที่จริงแล้วถ้าคุณใช้sizeofกับอาร์เรย์คุณจะได้ขนาดของอาร์เรย์ (นั่นคือขนาดองค์ประกอบคูณด้วยจำนวนองค์ประกอบ) แต่ถ้าคุณใช้มันกับตัวชี้คุณจะได้ขนาดของตัวชี้เท่านั้น ดังนั้นเนื่องจากในกรณีส่วนใหญ่ที่คุณต้องการทราบขนาดของอาเรย์คุณมีเพียงพอยน์เตอร์เท่านั้นจึงไม่ใช่ทั้งหมดที่มีประโยชน์
sepp2k

1
@Jens คำถามถูกแท็ก [C ++] และ VLA ไม่ได้ทำให้เป็นมาตรฐาน C ++
authchir

13

เพราะขนาดทั้งหมดของ "การโทร" ถูกคำนวณ ณ เวลาที่คอมไพล์และสิ่งใดก็ตามที่อยู่ระหว่างวงเล็บถูกยกเลิกและไม่ได้รันในรันไทม์

ผลลัพธ์จะขึ้นอยู่กับข้อมูลประเภทคงที่ที่มีอยู่ในคอมไพเลอร์


7

เหตุใดขนาดของชื่อผู้ดำเนินการรวบรวมเวลา

เนื่องจาก ณ เวลารวบรวมคอมไพเลอร์จะคำนวณขนาดของนิพจน์และทดแทนที่มีค่าคงที่เวลาคอมไพล์

จริง ๆ แล้วมันไม่ใช่ผู้ดำเนินการ

ฉบับที่คุณยังสามารถใช้sizeofในการประเมินขนาดของการแสดงออกคุณไม่สามารถดำเนินการถูกต้องตามกฎหมาย (เช่นที่จะก่อให้เกิดพฤติกรรมที่ไม่ได้กำหนด) ดังนั้นตราบใดที่คอมไพเลอร์สามารถคิดออกว่าสิ่งที่ประเภทของการแสดงออกเป็น

นอกจากนี้ก่อน C ++ 11 constexprคุณสามารถใช้sizeofนิพจน์ในแบบที่คุณไม่สามารถใช้นิพจน์แบบรันไทม์

และถ้ามันเป็นตัวรวบรวมเวลาจริงมันช่วยในการสร้างโค้ดพกพาได้อย่างไร ...

ประเภทอาจแตกต่างกันในขนาดบนแพลตฟอร์มที่แตกต่างกัน การใช้sizeofนิพจน์แทนการใช้รหัสตายตัวหมายความว่าโค้ดของคุณจะไม่แตกเมื่อคุณคอมไพล์บนแพลตฟอร์มอื่นและขนาดของคุณเปลี่ยนไป


1
ฉันคิดว่านี่เป็นคำตอบที่มีประโยชน์ที่สุด) พี่ชาย (สมมติว่าคุณเป็นผู้ชาย) ฉันมีข้อสงสัย คุณหมายถึงจะบอกว่าเมื่อมีคนบอกว่า sizeof ทำให้โปรแกรมพกพาพวกเขาหมายความว่าซอร์สโค้ดสามารถรวบรวมได้โดยไม่มีข้อผิดพลาดใด ๆ ในเครื่องทั้งหมดและพวกเขาไม่ได้หมายความว่าโปรแกรมปฏิบัติการสามารถทำงานในเครื่องใดก็ได้ ใช่มั้ย หากถูกต้องข้อสงสัยของฉันจะหายไปจริงๆ
ผู้ทำรหัสอย่างสันติ

1
ใช่รหัสเป็นแบบพกพาในแง่ที่คุณสามารถรวบรวมไบนารีที่ถูกต้อง (แตกต่างกัน) สำหรับแต่ละแพลตฟอร์ม
ไม่มีประโยชน์

5

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

ดูที่ C-C ++ โปรแกรม seg-fault ไม่ให้อ่านจนถึงจุดสิ้นสุดของอาร์เรย์ (UNIX) หรือไม่? สำหรับตัวอย่างจาก SO

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.