This doesn't work. People who understand C As She Is Spoke will understand clearly enough: neither possible result of the conditional ternary is an expression that can be evaluated on its own. The conditional is parsed as though if_foo and if_bar are standalone identifiers, and of course they're not.

But of course, if you look at the statement another way, it does make some sense. The presence of the dereference operator -> along with the subsequent grouped expression, seems to establish a lexical scope that needs to be resolved before parsing can continue.

And if seems were seams, I'd be Betsy Ross. You read the C spec and that's not how it works, and that's that. Can we gain any insight by trying to make it work another way?

The first one is how I actually do it. The second approach loses type information that you have to restore. I will admit to using the third approach or something like it, deep within macros that generate reams of boilerplate code. The fact that the fourth works at all is a tribute to how far the new C99 and C11 specifications have come compared to C89/90.

But it gets ugly so fast. The inner scope can create shadowed identifiers simply by being created (e.g. what if struct my_callbacks contained a field named is_foo?) How do we handle this? We need some kind of token to indicate whether an identifier is part of the inner scope or the outer, indicating outer scope with something like C++'s ::.

Or...maybe that's the wrong approach. What if the outer scope is still default, and we specify inner scope the way we normally do?

Like the proverbial regex-smith, now we have two problems. Except for the prefix dereference operators, we have a pretty clear expression, that says evaluate the conditional, call cb with the result of that, expect a function pointer as a result of that, then call the function pointer with the argument param. This is wrong on two counts, and this is where I leave well enough alone.

A final aside, for the sake of Monday morning quarterbacks: Was it a bad idea to use parentheses for all of the type cast operator, the function invocation operator and the statement grouping operator?