เมื่อเราตรวจสอบขนาดของฟังก์ชันโดยใช้sizeof()
เราจะได้1 ไบต์เสมอ 1 ไบต์นี้มีความหมายว่าอย่างไร?
เมื่อเราตรวจสอบขนาดของฟังก์ชันโดยใช้sizeof()
เราจะได้1 ไบต์เสมอ 1 ไบต์นี้มีความหมายว่าอย่างไร?
คำตอบ:
เป็นการละเมิดข้อ จำกัด และคอมไพเลอร์ของคุณควรวินิจฉัย หากคอมไพเลอร์ถึงแม้จะเป็นเช่นนั้นโปรแกรมของคุณก็มีพฤติกรรมที่ไม่ได้กำหนดไว้ [ขอบคุณ @Steve Jessop สำหรับการชี้แจงโหมดความล้มเหลวและดูคำตอบของ @Michael Burrว่าทำไมคอมไพเลอร์บางตัวจึงอนุญาต]: จาก C11, 6.5.3.4./ 1:
ห้ามใช้
sizeof
ตัวดำเนินการกับนิพจน์ที่มีประเภทฟังก์ชัน
-std=c11
, ไม่ gnu11
นี่เป็นส่วนขยายของคอมไพเลอร์ที่แปลกจริงๆ
sizeof(void)
เป็น 1 ใน GNU C.
-std=c11
: ใครบางคนควรอ้างถึง-std=c*
ตัวเลือกในมาตรฐานการโฆษณา พวกเขาไม่ได้เปิดใช้งานโหมดความสอดคล้องพวกเขาเป็นเพียงปิดการใช้งานส่วนขยายที่จะป้องกันไม่ให้โปรแกรมที่มีรูปแบบดีรวบรวม (เช่นเป็นtypeof
คำหลักเนื่องจากโปรแกรม C ที่มีรูปแบบดีสามารถใช้เป็นชื่อตัวแปรได้ แต่gcc
โดยค่าเริ่มต้นจะปฏิเสธสิ่งนั้น ). ส่วนขยายปิดการใช้งานนอกจากนี้ที่อนุญาตให้โปรแกรมที่ไม่ดีเกิดขึ้นที่จะผ่าน undiagnosed คุณต้องหรือ-pedantic
-pedantic-errors
นี่ไม่ใช่พฤติกรรมที่ไม่ได้กำหนด - มาตรฐานภาษา C ต้องการการวินิจฉัยเมื่อใช้ตัวsizeof
ดำเนินการกับตัวกำหนดฟังก์ชัน (ชื่อฟังก์ชัน) เนื่องจากเป็นการละเมิดข้อ จำกัด สำหรับตัวsizeof
ดำเนินการ
อย่างไรก็ตามในฐานะที่เป็นส่วนขยายของภาษา C, GCC ช่วยให้การทางคณิตศาสตร์ในการvoid
ชี้และคำแนะนำการทำงานซึ่งจะทำโดยการรักษาขนาดของที่หรือฟังก์ชั่นเป็นvoid
1
เป็นผลให้ผู้sizeof
ประกอบการจะมีการประเมินเพื่อ1
สำหรับvoid
หรือฟังก์ชั่นที่มี GCC ดูhttp://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html#Pointer-Arith
คุณสามารถขอให้ GCC ออกคำเตือนเมื่อใช้sizeof
กับตัวถูกดำเนินการเหล่านี้ได้โดยใช้-pedantic
หรือ-Wpointer-arith
ตัวเลือกสำหรับ GCC หรือทำให้เกิดข้อผิดพลาดกับ-Werror=pointer-arith
.
sizeof
ฟังก์ชันไม่ใช่ UB (ซึ่งฉันพูดถึงค่อนข้างมากเพราะคำตอบอื่นระบุว่าเป็น UB) แต่บางทีฉันอาจสับสนเพราะวิธีที่ฉันจัดโครงสร้างประโยค ให้ชัดเจนยิ่งขึ้น. sizeof
ฟังก์ชันไม่ใช่ UB (ตามที่มีการอ้างคำตอบหลายข้อ) เป็นการละเมิดข้อ จำกัด ดังนั้นจึงต้องมีการวินิจฉัย GCC อนุญาตให้เป็นส่วนขยาย
หมายความว่าผู้เขียนคอมไพเลอร์ตัดสินใจที่ค่า 1 แทนที่จะทำให้ปีศาจบินออกจากจมูกของคุณ (อันที่จริงมันเป็นการใช้งานที่ไม่ได้กำหนดอีกอย่างหนึ่งsizeof
ที่ทำให้เรามีนิพจน์นั้น: "ตัวคอมไพเลอร์ C ต้องออกการวินิจฉัยหากเป็นสิ่งแรกที่จำเป็น การวินิจฉัยที่เป็นผลมาจากโปรแกรมของคุณจากนั้นอาจทำให้ปีศาจบินออกจากจมูกของคุณ (ซึ่งอาจเป็นข้อความวินิจฉัยที่บันทึกไว้) เช่นเดียวกับที่อาจออกการวินิจฉัยเพิ่มเติมสำหรับการละเมิดกฎไวยากรณ์หรือข้อ จำกัด เพิ่มเติม (หรือ สำหรับเรื่องนั้นไม่ว่าจะด้วยเหตุผลใดก็ตาม) " https://groups.google.com/forum/?fromgroups=#!msg/comp.std.c/ycpVKxTZkgw/S2hHdTbv4d8J
จากนี้มีคำแสลง "จมูกปีศาจ" สำหรับสิ่งที่คอมไพเลอร์ตัดสินใจที่จะตอบสนองต่อโครงสร้างที่ไม่ได้กำหนด 1
เป็นปีศาจจมูกของคอมไพเลอร์นี้สำหรับกรณีนี้
ตามที่คนอื่น ๆ กล่าวไว้ sizeof () สามารถใช้ตัวระบุที่ถูกต้อง แต่จะไม่ส่งคืนผลลัพธ์ที่ถูกต้อง (เป็นจริงและถูกต้อง) สำหรับชื่อฟังก์ชัน นอกจากนี้อาจส่งผลให้เกิดกลุ่มอาการ "ปีศาจออกจากจมูก" อย่างแน่นอนหรือไม่ก็ได้
หากคุณต้องการกำหนดโปรไฟล์ขนาดฟังก์ชันโปรแกรมของคุณให้ตรวจสอบแผนผังตัวเชื่อมโยงซึ่งสามารถพบได้ในไดเร็กทอรีผลลัพธ์ระดับกลาง (รายการที่รวบรวมสิ่งต่าง ๆ ไว้ใน. obj / .o หรือตำแหน่งของรูปภาพ / ปฏิบัติการที่เป็นผลลัพธ์) บางครั้งมีตัวเลือกในการสร้างหรือไม่สร้างไฟล์แผนที่นี้ ... ขึ้นอยู่กับคอมไพเลอร์ / ตัวเชื่อมโยง
หากคุณต้องการขนาดของตัวชี้ไปยังฟังก์ชันก็จะมีขนาดเท่ากันทั้งหมดคือขนาดของคำที่อยู่บนซีพียูของคุณ
int x = 1;
ก็ได้ แต่มีเพียงหนึ่งในนั้นเท่านั้นที่ได้รับอนุญาตสำหรับคอมไพเลอร์ที่เป็นไปตามมาตรฐาน เมื่อsizeof()
นำไปใช้กับฟังก์ชันอาจส่งคืนค่าที่ตั้งไว้หรือปฏิเสธที่จะคอมไพล์หรือส่งกลับค่าสุ่มตามสิ่งที่อยู่ในรีจิสเตอร์เฉพาะในขณะนั้น ปีศาจจมูกตามตัวอักษรไม่น่าเป็นไปได้ แต่อยู่ในตัวอักษรของมาตรฐาน
sizeof
ไปใช้กับตัวชี้กับฟังก์ชัน
-pedantic
) แสดงว่าคุณมีคอมไพลเลอร์ที่ไม่เป็นไปตามข้อกำหนดและทุกโปรแกรมมีพฤติกรรมที่ไม่ได้กำหนดไว้