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 いらんかった。