■
SigScheme で setjmp() を使っててややこしい代入操作が。
これってどうだっけか。これだと volatile store にはならんのだっけか。
type *var; (type * volatile)var = sth;
忘れた。C99 rationale 見よう。何か書いてあったはず。
追記: っていうかこれだと error 出るよorz
うん、やっぱ駄目らしい。左辺の var の部分だけで既に non-volatile な lvalue として評価されてるからそれを後付けで cast しても遅い。というわけで
*(type ** volatile)&var = sth;
あれ? これでも駄目?
とか思って色々やっていて、理解不能な光景を目の当りにする。
jun@debian /tmp $ cat tmp.c int b; int f(int a) { *(volatile int *)&b = a; return *(volatile int *)&b; } jun@debian /tmp $ gcc -S -o - -O2 tmp.c .file "tmp.c" .text .p2align 4,,15 .globl f .type f, @function f: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax movl %eax, b popl %ebp ; %eax の reload は!? ret .size f, .-f .comm b,4,4 .ident "GCC: (GNU) 4.0.3 20051201 (prerelease) (Debian 4.0.2-5)" .section .note.GNU-stack,"",@progbits
b の宣言を volatile b にしたり、GCC 3.3 で build すると ret の前に movl b, %eax する。これはどういう事? どうも 3.3 は access 時の型で access の種類を決めてるのに対して、4.0 は識別子についてる情報で決めてるような感じだけど。 volatile access から volatile access までの間には volatile semantics は適用しないようになったという事なのか。
ああ、二つ目の access は "produces no necessary side effects" と判定されてるのね。
でもよく見ると sigscheme での code には volatile いらんかった。