On Sep 29, 7:23 am, "Peter Duniho" <
[email protected]>
wrote:
<snip.
The code you posted can't, I agree. Code that captures a by-reference
variable would have to ensure that it gets used only when the variable is
still present on the stack. Likewise, code that would reference one
thread's stack from another thread would indeed have to be careful to
preserve the stack variable until it's sure the other thread is done using
it.
In C#, it makes perfect sense to prohibit this sort of scenario except in
unsafe code. In C#, one fundamental assumption in the language is that
the language prevents you from accessing invalid data.
Exactly - and that's what I meant by "I don't see how it could work."
To expand that, "I don't see how it could be permitted and still
remain true to the spirit of C#"
Whatever else happens, you can always be assured that the simple
act of accessing a variable isn't going to blow up. But this isn't about
what C# _does_ do. It's about what it might do given alternate rules
of engagement.
True - but when considering "what if we could do X" I usually assume
that the core tenets of the language are adhered to. Anyway, so long
as we understand each other now it doesn't matter too much.
One interesting point would be whether such a program was verifiable.
I haven't looked closely at the verifiability rules. I might do so...
[...]
Well, anything involving pointers would make me suspicious to start
with - and anything relying on a particular stackframe in one thread
still being around by the time another thread executed some code just
sounds pretty evil to me.
For better or worse, .NET already has a specific example that deals with
that situation just fine: Control.Invoke().
Does that really rely on any particular stackframe? In particular, if
the calling thread is interrupted or aborted, I wouldn't expect the UI
thread to suffer corruption - or vice versa. But I do see what you're
getting at, I think.
The need to execute some specific code on some specific thread is
uncommon, but it does exist. Using normal synchronization mechanisms,
it'd be possible to write code that safely references variables from one
thread's stack in another thread. Is it a "pretty evil hack" for
Control.Invoke() to deliver some code to be executed on one thread, while
it blocks another? That sort of synchronization is all it'd take to
safely use by-reference variables cross-thread. And that's assuming no
language support such as the hypothetical behaviors I've mentioned above.
Well, it intertwines the threads more tightly than is the case now -
making situations like the above more risky. In the Control.Invoke
situation we're certainly blocking one thread based on another, but
the actual stackframes are still isolated which limits possible
damage. As soon as one stackframe "going away" puts another thread at
risk of corruption, the platform feels less stable.
p.s. As if all of the above wasn't enough, now I'm sitting here curious
what happens if you pass by-reference a member field of a class. Does the
by-reference argument preserve a reference to the instance of the class
that contains the field? If not, how does C# ensure that the instance
isn't GC'ed before it's done with the by-reference argument? A quick test
suggests that the reference to the containing instance _is_ kept
somewhere, but I haven't had time to research how that happens or why
(i.e. whether it's stipulated in the C# spec).
Hmm. Interesting question. I really don't know how that's handled.
I'll have a look into it - and see whether the book I'm reading at the
moment (CLR via C#) covers it. (If any non-spec book covers it,
this'll be the one
Jon