be "pushed" in the stack, the "pop" operations could happen ill paired:

x3

could be "popped" in the

meth(...,2,2)

line, and

x2

could be "popped" in the

meth(...,3,3)

line, against the desired.

This situationg is completely unlikely, and it seems that under Standard C99 there is not formal solution.

However, in C11 we have the concept of

inderminately sequenced

side effects.

We have that:

When a function is called, all its side effects are resolved indeterminaly sequenced respect any other expression around the expression that makes the function call. [See paragraph (12) here: sequence points].

Since the side effects in the function call of

meth

involved in the expression:

my_stack(x2,"push") -> meth(my_stack(0,"pop"),2,2)

have to resolved "completely before" or "completely after" the side effects in:

my_stack(x3,"push") -> meth(my_stack(0,"pop"),3,3)

I conclude that the "push" and "pop" operations are well paired.

Is it OK my interpretation of the standard? I will cite it, just in case:

[C11, 6.5.2.2/10] There is a sequence point after the evaluations of the function designator and the actual arguments but before the actual call. Every evaluation in the calling function (including function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.94)

[Footnote 94]: In other words, function executions do not ‘‘interleave’’ with each other.

That is, although the order of evaluation of arguments in a function call cannot be predicted, I think that one can, anyway, be sure that the rules of "sequence" stablished in ISO C11 are enough to ensure that the "push" and "pop" operations work well in this case.

So, a "method"-like syntax can be used in C, in order to emulate a rudimentary but consistent OOP capability of "methods as members of objects".

The evaluations of B and C are completely independent and must both be done before the function call D. The arguments of a function and the function designator are not much different for that.

Because A and B are function calls, they are in fact sequenced, but this is indeterminely, so you don't know which one comes first and which second.

I think you would be far better off by making your call an inline function. If you really need versions of call for different types, you could go to select the function with a _Generic expression. But as someone already said in the comments, you are really at the limits of what you should reasonably do in C.