>So make sure b does not change at the clock edge
Its not so simple to do that when you actually implement in RTL.
tbyeoh,
They're right about that its a compiler specific thing. The thing to remember is that your situation is essentially a setup/hold violation in hardware.
You cannot simply not change signals on edges at will as recommended. Imagine b is coming from a flop just before the flop given in your code (and this is not in your hand, its just what the design requirement is). You just have to hope timing will be closed b/w the 'b' generating flop and your flop. Also in this case, I think modelsim's behaviour is the way to go, since the propagation delay of the source flop will make the destination flop see a 0 till 'b' actually arrives at its input. In that sense, I think modelsim's and similar professional simulator's algorithms have complex delta scheduling algorithms (change of multiple signals at same edge) to take care of such exigencies.
'b' if it is an external signal is another matter - you have to double-synchronize it if it is asynchronous. If timing of 'b' is known (say it is coming from a memory device whose timing characteristics are known), then appropriate constraints can be applied.
Hope this makes sense even if you're a pure verification guy.