Khi chúng tôi kiểm tra kích thước của một hàm đang sử dụng sizeof()
, chúng tôi luôn nhận được 1 byte . 1 byte này biểu thị điều gì?
Khi chúng tôi kiểm tra kích thước của một hàm đang sử dụng sizeof()
, chúng tôi luôn nhận được 1 byte . 1 byte này biểu thị điều gì?
Câu trả lời:
Đó là một vi phạm ràng buộc và trình biên dịch của bạn nên chẩn đoán nó. Nếu nó biên dịch nó bất chấp điều đó, chương trình của bạn có hành vi không xác định [cảm ơn @Steve Jessop đã giải thích rõ về chế độ lỗi và xem câu trả lời của @Michael Burr để biết lý do tại sao một số trình biên dịch cho phép điều này]: Từ C11, 6.5.3.4./ 1:
Các
sizeof
nhà điều hành sẽ không được áp dụng cho một biểu thức có kiểu chức năng
-std=c11
, không phải gnu11
. Đây là một phần mở rộng trình biên dịch thực sự kỳ lạ.
sizeof(void)
là 1 trong GNU C.
-std=c11
: ai đó nên tham khảo các -std=c*
tùy chọn cho Tiêu chuẩn quảng cáo. Họ không bật chế độ tuân thủ, họ chỉ vô hiệu hóa các tiện ích mở rộng có thể ngăn một chương trình đã được định dạng tốt biên dịch (chẳng hạn như typeof
là một từ khóa, vì một chương trình C được định dạng tốt có thể sử dụng nó làm tên biến, nhưng gcc
theo mặc định sẽ từ chối điều đó ). Ngoài ra, để vô hiệu hóa các tiện ích mở rộng cho phép các chương trình không hợp lệ vượt qua mà không được chẩn đoán, bạn cần -pedantic
hoặc -pedantic-errors
.
Đây không phải là hành vi không xác định - tiêu chuẩn ngôn ngữ C yêu cầu chẩn đoán khi sử dụng sizeof
toán tử với bộ chỉ định hàm (tên hàm) vì đó là một vi phạm ràng buộc đối với sizeof
toán tử.
Tuy nhiên, như là một phần mở rộng của ngôn ngữ C, GCC cho phép số học trên void
con trỏ và con trỏ hàm, được thực hiện bằng cách coi kích thước của một void
hoặc một hàm là 1
. Do đó, sizeof
nhà điều hành sẽ đánh giá 1
cho void
hoặc một chức năng với GCC. Xem http://gcc.gnu.org/onlineocs/gcc/Pointer-Arith.html#Pointer-Arith
Bạn có thể yêu cầu GCC đưa ra cảnh báo khi sử dụng sizeof
với các toán hạng này bằng cách sử dụng -pedantic
hoặc -Wpointer-arith
các tùy chọn đối với GCC. Hoặc làm cho nó một lỗi với -Werror=pointer-arith
.
sizeof
một chức năng không phải là UB (mà tôi đã đề cập khá nhiều chỉ vì các câu trả lời khác nói rằng đó là UB). Nhưng có lẽ tôi đã nhầm lẫn điều đó vì cách tôi cấu trúc câu. Để rõ ràng hơn. sizeof
một chức năng không phải là UB (như một số câu trả lời đã tuyên bố). Đó là một sự vi phạm ràng buộc. Như vậy, nó yêu cầu một chẩn đoán. GCC cho phép nó như một phần mở rộng.
Nó biểu thị rằng người viết trình biên dịch đã quyết định giá trị là 1 thay vì khiến ma quỷ bay khỏi mũi bạn (thực sự, đó là một cách sử dụng không xác định khác của sizeof
nó đã cho chúng ta biểu thức đó: "Bản thân trình biên dịch C PHẢI đưa ra chẩn đoán NẾU đây là yêu cầu đầu tiên kết quả chẩn đoán từ chương trình của bạn, và sau đó chính nó CÓ THỂ khiến ma quỷ bay khỏi mũi bạn (nhân tiện, có thể là thông báo chẩn đoán được ghi lại bằng văn bản) giống như nó CÓ THỂ đưa ra thêm chẩn đoán đối với những vi phạm thêm các quy tắc hoặc ràng buộc cú pháp (hoặc, cho vấn đề đó, vì bất kỳ lý do gì nó chọn). " https://groups.google.com/forum/?fromgroups=#!msg/comp.std.c/ycpVKxTZkgw/S2hHdTbv4d8J
Từ này có thuật ngữ tiếng lóng "quỷ mũi" cho bất cứ điều gì mà trình biên dịch quyết định làm để đáp ứng với một cấu trúc không xác định. 1
là con quỷ mũi của trình biên dịch này cho trường hợp này.
Như những người khác đã chỉ ra, sizeof () có thể lấy bất kỳ số nhận dạng hợp lệ nào, nhưng nó sẽ không trả về kết quả hợp lệ (một kết quả trung thực đúng và hợp lệ) cho các tên hàm. Hơn nữa, nó chắc chắn có thể, hoặc có thể không, dẫn đến hội chứng "quỷ không có mũi".
Nếu bạn muốn định cấu hình kích thước hàm chương trình của mình, hãy kiểm tra bản đồ trình liên kết, có thể tìm thấy trên thư mục kết quả trung gian (thư mục nơi mọi thứ được biên dịch thành .obj / .o hoặc nơi chứa hình ảnh / tệp thực thi kết quả). Đôi khi có một tùy chọn để tạo hoặc không tạo tệp bản đồ này ... nó phụ thuộc vào trình biên dịch / trình liên kết.
Nếu bạn muốn kích thước của một con trỏ đến một hàm, chúng đều có cùng kích thước, kích thước của một từ địa chỉ trên cpu của bạn.
int x = 1;
nhưng chỉ một trong những điều đó được phép đối với trình biên dịch tuân thủ các tiêu chuẩn. Với sizeof()
việc được áp dụng cho một hàm, nó có thể có hoặc không trả về một giá trị đã đặt, hoặc từ chối biên dịch hoặc trả về một giá trị ngẫu nhiên dựa trên bất kỳ giá trị nào trong một thanh ghi cụ thể tại thời điểm đó. Quỷ mũi theo nghĩa đen là không chắc, nhưng trong tiêu chuẩn chữ cái.
sizeof
cho một con trỏ tới một hàm.
-pedantic
), bạn có một trình biên dịch không phù hợp và mọi chương trình đều có hành vi không xác định.