Context: I am trying to create macros to create some efficient coroutines. In my concept, the function has multiple passes (running, cleaning, checking). Currently I implement it using switch/case The running part is a happy path, basically a fallthrough in a switch. While the other passes need to be invoked only in error modes. I would like it so that a label can jump to next label in sequence.
step1: ...goto step2; // How to generate this statement? Equivalent of __COUNTER__+1
In other words macro code likle this:
BEGINAWAIT action1();AWAIT action2();AWAIT action3();END
To become essentially
if (0) { if (pass == CLEANING) { clean1: clean(1) goto clean2; // <- } else ...}case 1:action1()if (0) { if (pass == CLEANING) { clean2: // no cleaning code here, compiler hopefully will optimize it out // jumping from step 1 to step 3 goto clean3(); // <- } else ...}case 2:action2()if (0) { if (pass == CLEANING) { clean3: clean(3) goto clean4(); // <- } else ...}case 3:action3()if (0) {clean4: // complete}
I tried different approaches using switch statements & extra cases. Also tried building a skiplist to dispatch to correct case. But i'd like to do it without dispatching my "passes" through switch, and "connect" them using gotos directly. Generating label with __COUNTER__
is easy, but generating goto label ## __COUNTER__ + 1
seems to be impossible.
Are there any other options? (Let's say using anything GCC offers)
- Jump table? The way i use macros, i can not build the jump table upfront because i dont know how many steps will be there
- Multi-pass jump table? Creating some code that runs the full length of function first to create jump table seems to work, but it does not get optimized out on -O1/O2/Og, at least nothing I tried made it usable. It worked for O3, but it was very inefficient on others, which was really not very good for my needs.
- Maybe if instead of incrementing
__COUNTER__
i could somehow have access to "previous" value, i could work it out, but that seems to require some sort of runtime stuff. Saving counter value as enum does not really give me a way to concat labels anyway. - Using asm goto maybe? Is it possible to create label name dynamically like that? Using asm macro perhaps?
- Labels-as-references seem to have the same problem that
__COUNTER__ + 1
does not compute during preprocessing. - Creating a ton of macros like
#define INCREMENT_3 4
seems to be the only idea that can actually work. But i'm afraid of running out of numbers. I dont understand exactly what does "translation unit" scope mean for__COUNTER__
- it's can be potentially more than one file, right?