เมื่อเราตรวจสอบขนาดของฟังก์ชันโดยใช้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) แสดงว่าคุณมีคอมไพลเลอร์ที่ไม่เป็นไปตามข้อกำหนดและทุกโปรแกรมมีพฤติกรรมที่ไม่ได้กำหนดไว้