4 ms·
I really don't know what you mean by this: > That frob is forbidden isn't because the compiler detected that foo is a signal handler, but because no forbidden
by alxlaz 9y ago
I really don't know what you mean by this:
> That frob is forbidden isn't because the compiler detected that foo is a signal handler, but because no forbidden functions exist.
or this:
> not possible - if frob might be forbidden anywhere then it's not callable like this
- alkonaut 9y agoI was trying to describe how an api would look where the compiler would make sure you could not call a certain function from a certain context. So I was trying to argue that then the api would have to be such that you can't actually import that function to that context. So basically: say that putchar is the forbidden function. Then there exists no global function "putchar". There is no way to just "import" a header and call putchar in our language/api. Instead, everything available to a function is what's passed to it (an interface to available API). So for example for a particular type of context (a handler, say) - a very restricted api is passed in as argument, meaning the code inside that function has very little api surface area to play with.
- alxlaz 9y ago> I was trying to describe how an api would look where the compiler would make sure you could not call a certain function from a certain context. It's not a certain set of functions that you want to forbid, it's a certain behaviour (e.g. being interruptible by signals, or being non-reentrancy). Forbidding functions won't get you anywhere. You can always forbid write(), but you won't be able to forbid functions that dynamically dispatch to write() at runtime, or user-defined functions that aren't reentrant. Edit: i.e. when we say you shouldn't call write(2) from a signal handler, that's not because there's a list somewhere in a POSIX standard with functions that you shouldn't call in a signal handler and write(2) is on it \. That's because the POSIX spec allows write(2) to be interrupted by a signal and that's not okay inside a signal handler. ___ \ There might be one, I haven't looked at a POSIX spec in a long time now -- but either way, the point is that such a list is open :-).
- alkonaut 9y agoI see. Preventing access to classes of behaviour is a harder problem. Reentrancy (single threaded - such as mutual recursion) must be really hard to detect with certainty other than at runtime, for example. In a multi threaded context it's obviously even harder. Classifying functions into more categories like "interruptible", "uninterruptible" seems doable with enough language support. It doesn't look to far from what e.g. Rust and C# does with "unsafe", i.e. a status of functions that bubbles up so that your function may be tainted as unsafe by calling unsafe functions. If the number of classifications of functions is small as is the case with unsafe/safe, or uninterruptible/interruptible then it would seem possible to sort this out via compiler support and keywords for example. So for example a signal handler is then an uninterruptible function. It's a compiler error to call even indirectly, or dynamically dispatch to interruptible functions. For any type of safety, dynamic dispatch obviously needs to be done in a type safe manner, so no pointer arithmetic/function pointer invocation can be allowed. Doing so would make the called code be assumed to be the worst of all categories: unsafe, interruptible etc). This is how unsafe/safe works too. So while it's cumbersome I'm sure it would be possible to achieve at least to some extent, given an expressive enough language and a clever enough compiler.