2

I'm forced to use IAR EW430 compiler v7.12 for an embedded project, and it only officially supports c99.

I would like to be able to emulate GCC's statement-expressions in a general way by any means OTHER than writing a bunch of dedicated inline functions.

Is there any way to achieve this? (perhaps using MACRO-wizardry? Or emulating Lambdas, or some hidden compiler switches that will allow this?) Obviously other than changing compiler.

Specifically, the result of the last statement of the compound expression should carry both its type AND value out, not have those passed in as a macro parameter.

I've been searching for months, but the closest I can get is the impressive impressive library, but that seems like an awful lot to lay down.

Gunther Schulz
  • 575
  • 3
  • 18
  • 4
    The correct way is to write (inline) functions. There's a reason why the "statement expressions" never made it to the standard. If you are forced to only use the C standard, then now's the perfect time to do so properly, without using messy, non-standard, superfluous features. What is the actual problem you are trying to solve? Need to pre-calculate something at compile-time or...? – Lundin Jun 29 '18 at 13:11
  • @Lundin i know inline functions is the correct way :), like i said, "i would like to..." – Gunther Schulz Jun 29 '18 at 13:13
  • But _why_ would you like that? – Lundin Jun 29 '18 at 13:18
  • For a toy project – Gunther Schulz Jun 29 '18 at 13:19
  • The macro library you link to does not provide statement expressions, nor really anything very close to them. It provides (the appearance of) several varieties of *function* that C does not natively support. The key difference between a function and a statement expression is that you need to *call* a function to obtain its value. – John Bollinger Jun 29 '18 at 13:28
  • @JohnBollinger the library goes to emulating Lambdas – Gunther Schulz Jun 29 '18 at 13:34
  • Yes, @GuntherSchulz, and Lambdas are a variety of function. One uses a lambda by calling it, and a lambda generally specifies its return value in the same way as ordinary functions in its language. That is not analogous to a statement expression. But perhaps this is your chance to clarify just what properties you want the construct you're after to exhibit, and how you would like to use it. – John Bollinger Jun 29 '18 at 13:38
  • Thanks @JohnBollinger, I am aware of the difference. Perhaps I have a language issue here. My intent is to truly (or as closely as possible) emulate Statement Expressions, to be used in every way that they can be used, with every property they have. Lets call it an open "can it even be done?" kind of question. – Gunther Schulz Jun 29 '18 at 13:45
  • By linking the library I was trying to be responsible and show there has been effort on my part to get as close to and answer as I could, and not just troll other people for free answers. – Gunther Schulz Jun 29 '18 at 13:47
  • 1
    An alternative might be to build some GCC cross-compiler for your platform (perhaps by compiling GCC source code). In other words, you don't explain what forces you to use IAR EW430 compiler v7.12 f – Basile Starynkevitch Jun 29 '18 at 13:50
  • @BasileStarynkevitch - Its a personal challenge / bet – Gunther Schulz Jun 29 '18 at 13:53
  • You could consider a GCC-C to C90 compiler. That is a crazy (but interesting) idea (which you might implement as some GCC plugin) – Basile Starynkevitch Jun 29 '18 at 13:56
  • @BasileStarynkevitch, +1 for the idea :) – Gunther Schulz Jun 29 '18 at 14:01
  • The closest standard feature to block expressions is the [comma operator](https://stackoverflow.com/questions/52550/what-does-the-comma-operator-do). It is more limited but does allows you to call void functions in line, assign variables in line, etc – user16217248 Jun 28 '21 at 22:21

2 Answers2

5

I realize this is not the answer you're looking for, but since you asked "Is there any way to achieve this?", I have to say the answer is simply "No".

Don't get me wrong -- I know what you're looking for, and why you want it. It's a very cool feature. Once upon a time I was trying to invent my own C-like language, and one of my goals was that every statement be usable as an expression. But this feature is simply not part of C, and there's no decent way to emulate it.

In fact, you can pretty easily prove that there's no decent way to emulate it, because if there were, the gcc folks would have not have had to implement those crazy, nonstandard extensions.

So if you want to use gcc and its extensions, by all means, use gcc and its extensions. But if you want to write in reasonably pure C, you're simply going to have to learn to live without statement expressions. "When in Rome, do as the Romans do." Anything you manage to achieve with insane macro magic will probably (a) not really satisfy your craving for true statement expressions and (b) make maintenance of your program a nightmare for anyone who comes after you and doesn't understand what's so great about them.

You say you're doing embedded work, but are you sure there isn't a port of gcc for your platform? (I know you said you're "forced to" use IAR, but you also said this is a "toy project", so maybe you can break that rule. IAR always makes me think of the Wikipedia slogan "Ignore All Rules" anyway. :-) )

But since you said you're doing embedded work, that's an additional reason to discourage this kind of out-at-the-edge featurephilia. The impression I get is that one of the defining characteristics of "embedded work" is that it seeks to deny the use of half the language anyway, to mandate the use of only an extremely well defined, extremely safe subset. So I doubt an extension like statement expressions is going to fly for your project.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • There are GCC ports, but I do agree with all your points inherently. This was a personal challenge / bet. I suppose the argument goes "If it could have been done, surely it would have been done already, given the huge number of people interested and chipping away at this kind of issue. But someone has to be the first to try" :)) – Gunther Schulz Jun 29 '18 at 13:58
3

In comments, you clarify that

My intent is to truly (or as closely as possible) emulate Statement Expressions, to be used in every way that they can be used, with every property they have.

Therefore, let's look at how statement expressions are formed and what they do:

A compound statement enclosed in parentheses may appear as an expression in GNU C. This allows you to use loops, switches, and local variables within an expression.

[...]

The last thing in the compound statement should be an expression followed by a semicolon; the value of this subexpression serves as the value of the entire construct.

(GCC Documentation)

There are two key parts to that:

  • The construct is built around a compound statement, and therefore can have within anything that a compound statement can have.

  • The construct evaluates to a value.

Moreover, you explicitly say

Specifically, the result of the last statement of the compound expression should carry both its type AND value out, not have those passed in as a macro parameter.

You have painted yourself into a corner here. C statements are not expressions, which exactly means that they do not evaluate to values. It is why GCC statement expressions are an extension. Values have no linkage, and to the extent that they can be considered to have scope, it is limited to the expressions in which they appear and to the objects that store them. The only way to transfer a value out of a statement is to assign it to an object of appropriate type (and you expressly want to avoid doing that) or to return it (which requires it to be in a function).

There are other characteristics of statement expressions that may have attracted your interest in the first place. In particular, inasmuch as you brought up lambdas, I suspect you're interested in the fact that statement expressions live inside the context of the surrounding code, so that, among other things, they can use the identifiers that are in scope there. If that's what you're after then you probably need to just write ordinary blocks of code, and provide variables in which to report out the result.

HOWEVER, there is another alternative that could give you a little of what you're after. You can compute several expressions in turn, each able to make use of the side effects of the previous ones, by using the comma operator. For example,

int first = 1, second = 2, temp, new_first;

new_first = (temp = second, second = first, first = temp);

The result is that the values of first and second are swapped, with the resulting new value of first being assigned to new_first. Of course, this does not afford loops, if statements, etc, and it especially does not provide for declaring local variables, such as temp. As I said a little of what statement expressions can do.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157