Cảm ơn rất nhiều để wallyk, tôi đã có thể đưa ra một số mã sử dụng phương pháp của mình để tạo ra một số lắp ráp để chứng minh cho bản thân mình sự khác biệt giữa các phương pháp con trỏ khác nhau.
sử dụng mã: và biên soạn với -03
int main (void)
{
while(p[2]);
return 0;
}
khi p chỉ đơn giản là khai báo là con trỏ, chúng tôi gặp khó khăn trong một vòng lặp mà không thể thoát ra được. Lưu ý rằng nếu đây là một chương trình đa luồng và một luồng khác đã viết p [2] = 0, thì chương trình sẽ thoát khỏi vòng lặp while và kết thúc bình thường.
int * p;
============
LCFI1:
movq _p(%rip), %rax
movl 8(%rax), %eax
testl %eax, %eax
jne L6
xorl %eax, %eax
leave
ret
L6:
jmp L6
lưu ý rằng lệnh duy nhất cho L6 là đi tới L6.
==
khi p là con trỏ dễ bay hơi
int * volatile p;
==============
L3:
movq _p(%rip), %rax
movl 8(%rax), %eax
testl %eax, %eax
jne L3
xorl %eax, %eax
leave
ret
đây, con trỏ p được nạp lại mỗi vòng lặp và kết quả là mục mảng cũng được nạp lại. Tuy nhiên, điều này sẽ không chính xác nếu chúng tôi muốn một mảng các số nguyên không ổn định vì điều này sẽ có thể:
int* volatile p;
..
..
int* j;
j = &p[2];
while(j);
và sẽ cho kết quả trong vòng lặp đó sẽ không thể chấm dứt trong một chương trình đa luồng.
==
cuối cùng, đây là giải pháp đúng như tony độc đáo giải thích.
int volatile * p;
LCFI1:
movq _p(%rip), %rdx
addq $8, %rdx
.align 4,0x90
L3:
movl (%rdx), %eax
testl %eax, %eax
jne L3
leave
ret
Trong trường hợp này địa chỉ của p [2] được giữ ở giá trị đăng ký và không được nạp từ bộ nhớ, nhưng giá trị của p [2] được nạp lại từ bộ nhớ trên mỗi chu kỳ vòng lặp.
cũng lưu ý rằng
int volatile * p;
..
..
int* j;
j = &p[2];
while(j);
sẽ tạo ra một lỗi biên dịch.
Tôi đã tìm thấy giải thích tốt ở đây: http://www.embedded.com/story/OEG20010615S0107 – Mark
Tôi đã bắt đầu một câu hỏi về usenet: http://groups.google.com/group/comp.std .C++/browse_thread/thread/4af91d60c2a1af8a? pli = 1 –