It's good to learn about the "statement expression" language extension.
It doesn't seem particularly well thought-through; all bets are obviously off when you start jumping into the middle of expressions. Seems a good enough reason to always use
-std=C++11 -Wall -Wextra -pedantic
.
I suppose, you can use
switch
to implement things like
GOSUB
.
In case you're unfamiliar, GOSUB is a primitive version of a function call. Jump somewhere, then return back to where you started later. The differences are relatively simple: no new lexical
scope (edit: environment, technically; you can get a new scope by inserting braces), no explicit parameters, no explicit return values, no built-in ways to enforce those things. It's essentially a
goto
that you can return from if you want.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
# include <stack>
# include <iostream>
int main() {
std::stack <int> s;
# define GOSUB(proc) do { \
s.push(__LINE__); goto proc; case __LINE__: \
} while (false)
# define RETURN() do { \
if (! s.empty()) { target = s.top(); s.pop(); goto _top_; } \
} while (false)
int target = 0;
_top_:
switch(target) { default:
begin:
std::cout << "Started!" << "\n";
RETURN();
GOSUB(elsewhere);
std::cout << "Made it back!" << "\n";
GOSUB(begin);
std::cout << "Ending!" << "\n";
break;
elsewhere:
std::cout << "Gosub'd!" << "\n";
RETURN();
}
}
|
Some notes:
With some more abuse it's maybe possible to move some macro anaphors into another namespace or something. But C++ is quite limited in this respect.
Certain toolchains provide a
__COUNTER__
predefined macro, which would be a better choice then
__LINE__
, for obvious reasons, except it's not standard.
Of course, to make this "full-power", you need real macros. The C preprocessor is insufficient.
I can think of a way to allow multiple GOSUBs per line by (ab)using templates, but beyond that I'd need to have more thought.