Muchas gracias a wallyk, yo era capaz de idear un código utilizar su método para generar un poco de montaje para demostrar a mí mismo la diferencia entre los diferentes métodos de puntero.
utilizando el código: y compilar con -03
int main (void)
{
while(p[2]);
return 0;
}
cuando p se declara simplemente como puntero, nos quedamos atascados en un bucle que es imposible salir. Tenga en cuenta que si se tratara de un programa de multiproceso y un subproceso diferente escribió p [2] = 0, entonces el programa se rompería fuera del bucle, mientras que y terminar normalmente.
int * p;
============
LCFI1:
movq _p(%rip), %rax
movl 8(%rax), %eax
testl %eax, %eax
jne L6
xorl %eax, %eax
leave
ret
L6:
jmp L6
observe que la única instrucción para L6 es ir a L6.
==
cuando p es puntero volátil
int * volatile p;
==============
L3:
movq _p(%rip), %rax
movl 8(%rax), %eax
testl %eax, %eax
jne L3
xorl %eax, %eax
leave
ret
aquí, el puntero de p consigue vuelve a cargar cada iteración de bucle y como consecuencia, el elemento de la matriz también recibe Reloaded. Sin embargo, esto no sería correcta si queríamos una matriz de enteros volátiles ya que esto sería posible:
int* volatile p;
..
..
int* j;
j = &p[2];
while(j);
y resultaría en el bucle que sería imposible para terminar en un programa de multiproceso.
==
finalmente, esta es la solución correcta como Tony explica muy bien.
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
En este caso la dirección de p [2] se mantiene en valor del registro y no cargado de la memoria, pero el valor de p [2] se vuelve a cargar desde la memoria en cada ciclo del bucle.
también en cuenta que
int volatile * p;
..
..
int* j;
j = &p[2];
while(j);
generará un error de compilación.
He encontrado una buena explicación aquí: http://www.embedded.com/story/OEG20010615S0107 – Mark
He comenzado una pregunta de usenet sobre esto: http://groups.google.com/group/comp.std .C++/browse_thread/thread/4af91d60c2a1af8a? pli = 1 –