Tôi đang cố gắng hiểu rõ hơn về cách trình biên dịch tạo mã cho các biểu thức undefined ví dụ: cho đoạn mã sau:Trình gỡ lỗi trình gỡ lỗi của biểu thức không xác định
int main()
{
int i = 5;
i = i++;
return 0;
}
Đây là mã lắp ráp tạo ra bởi gcc 4.8.2 (Tối ưu hóa là tắt -O0 và tôi đã chèn số dòng của riêng mình cho mục đích tham khảo):
(gdb) disassemble main
Dump of assembler code for function main:
(1) 0x0000000000000000 <+0>: push %rbp
(2) 0x0000000000000001 <+1>: mov %rsp,%rbp
(3) 0x0000000000000004 <+4>: movl $0x5,-0x4(%rbp)
(4) 0x000000000000000b <+11>: mov -0x4(%rbp),%eax
(5) 0x000000000000000e <+14>: lea 0x1(%rax),%edx
(6) 0x0000000000000011 <+17>: mov %edx,-0x4(%rbp)
(7) 0x0000000000000014 <+20>: mov %eax,-0x4(%rbp)
(8) 0x0000000000000017 <+23>: mov $0x0,%eax
(9) 0x000000000000001c <+28>: pop %rbp
(10) 0x000000000000001d <+29>: retq
End of assembler dump.
Việc thực thi mã này dẫn đến giá trị i
còn lại với giá trị (được xác minh bằng tuyên bố printf()
) tức là i
dường như không bao giờ được tăng lên. Tôi hiểu rằng các trình biên dịch khác nhau sẽ đánh giá/biên dịch các biểu thức không xác định theo các cách khác nhau và điều này có thể chỉ là cách mà gcc thực hiện nó, tức là tôi có thể nhận được kết quả khác với trình biên dịch khác.
đối với mã lắp ráp Với, như tôi hiểu:
Bỏ qua dòng - 1-2 thiết lập của con trỏ stack/cơ sở, vv dòng 3/4 - là như thế nào giá trị của được gán đến i
.
Có ai có thể giải thích những gì đang xảy ra trên dòng 5-6 không? Dường như i
cuối cùng sẽ được gán lại giá trị (dòng 7), nhưng hoạt động tăng (yêu cầu cho hoạt động tăng bài đăng i++
) chỉ đơn giản là bị bỏ qua/bỏ qua bởi trình biên dịch trong trường hợp?
Related: [sequence point] (http://stackoverflow.com/q/3575350/2564301) – usr2564301