Tôi không thể cho bạn biết chi tiết về nền tảng của bạn vì tôi không biết nhưng có một câu trả lời chung cho hành vi bạn thấy.
Khi một số hàm có trả về được biên dịch, trình biên dịch sẽ sử dụng quy ước về cách trả về dữ liệu đó. Nó có thể là một máy tính đăng ký, hoặc một vị trí bộ nhớ được xác định như thông qua một ngăn xếp hoặc bất cứ điều gì (mặc dù thường đăng ký máy được sử dụng). Mã được biên dịch cũng có thể sử dụng vị trí đó (đăng ký hoặc cách khác) trong khi thực hiện công việc của hàm.
Nếu hàm không trả về bất kỳ thứ gì, trình biên dịch sẽ không tạo mã để lấp đầy vị trí đó với giá trị trả về một cách rõ ràng. Tuy nhiên như tôi đã nói ở trên, nó có thể sử dụng vị trí đó trong suốt hàm. Khi bạn viết mã đọc giá trị trả về (ch2 = toUpper(ch);)
, trình biên dịch sẽ viết mã sử dụng quy ước của nó về cách lấy trả về từ vị trí thông thường. Theo như mã người gọi là có liên quan, nó sẽ chỉ đọc giá trị đó từ vị trí, ngay cả khi không có gì được viết rõ ràng ở đó. Do đó bạn nhận được một giá trị.
Bây giờ hãy xem ví dụ của @ Ray, trình biên dịch đã sử dụng thanh ghi EAX, để lưu trữ kết quả của hoạt động vỏ trên. Nó chỉ xảy ra, đây có lẽ là vị trí trả về giá trị được ghi vào. Trên ch2 bên gọi được nạp với giá trị trong EAX - do đó trở về phantom. Điều này chỉ đúng với phạm vi xử lý x86, như trên các kiến trúc khác, trình biên dịch có thể sử dụng một lược đồ hoàn toàn khác để quyết định cách thức tổ chức hội nghị
Tuy nhiên trình biên dịch tốt sẽ cố gắng tối ưu hóa theo các điều kiện địa phương, kiến thức mã, quy tắc và phỏng đoán. Vì vậy, một điều quan trọng cần lưu ý là đây chỉ là may mắn mà nó hoạt động. Trình biên dịch có thể tối ưu hóa và không làm điều này hoặc bất cứ điều gì - bạn không nên trả lời về hành vi.
Nguồn
2011-09-02 08:28:13
Mùi giống như hành vi không xác định. – ThiefMaster
@ThiefMaster: Nó ** là ** UB. Anh ta chỉ may mắn rằng thanh ghi trong đó giá trị trả về thường được đặt xảy ra cũng được sử dụng cho phép trừ. –
Cảm ơn tất cả mọi người :) – harrison