It's guaranteed from the perspective of Fjuk
but not of Main
.
In Fjuk
the exception is thrown after the parameter is set. While there can be re-orderings done by compiler, jitter, and CPU, there will not be re-orderings such that the order observed by a single thread changes. Since a single thread could "notice" if the parameter wasn't set before the exception thrown, the parameter is guaranteed to be set.
In Main
though, we have no knowledge of the details of Fjuk
's implementation, so when the compiler analyses Main
, it can't depend on that. Hence in the variation where we don't assign a value to s
before the call:
static void Main()
{
string s;
try
{
Fjuk(out s);
Console.WriteLine(s ?? "");//fine
}
catch (Exception)
{
Console.WriteLine(s ?? "");//compiler error
}
Console.WriteLine(s ?? "");//compiler error
}
The first attempt to use s
immediately after the call to Fjuk
is fine, because one can only get there if Fjuk
succeeded, and if Fjuk
succeeded then s
must be assigned. In the second and third case though, it's possible to arrive at those lines without Fjuk
succeeding, and since one cannot tell by analysis of Main
whether an exception could be thrown before s
is set, the uses of s
must be prohibited.