Tail recursion for preprocessor macros

9 comments · 85% upvoted · source · other discussions

comments

tstanisl [OP]

I like the simplicity of proposed extension. When __VA_ARGS__ is non-empty, just replace __VA_TAIL__(FOO) with FOO(__VA_ARGS__) and expand it even within FOO macro. Infinite recursion is prevented by requiring FOO macro to have at least one named parameter. So one parameter is consumed each time thus the recursion will end (hopefully). Moreover, __VA_ARGS__ is not rescanned reducing expansion complexity from quadratic to linear. 

aalmkainzi

does it always shift one parameter? from my understanding it shifts based on the number of named arguments, for example:

#define FOO(a, b, ...) b, a __VA_OPT__( , __VA_TAIL__() )
tstanisl [OP]

I does not shift. However the macro that is a parameter to __VA_TAIL__ must have at least one named parameter thus ... shrinks with every expansion.

It should prevent infinite recursion .. at least in a typical use case.

aalmkainzi

really cool. we will finally be able to iterate over __VA_ARGS__

flatfinger

I wonder if there would have been any difficulty simply saying that a macro invocation with N arguments is allowed to call itself recursively with any smaller number of arguments, or having a syntax to allow macro overloading based on argument count? Allowing those two things would have made many operations very simple.

Jinren

The same author is also working on a project to separate the definition of the preprocessor from the C Standard entirely, which would have several neat implications going forward.

torsten_dev

I like it.

Now how about standardizing [[clang::musttail]] so we can get some guaranteed diagnostic if a tail call does not get optimized.

Jinren

workin' on it, workin' on it (section 5)

Since it's a TS, you should get this before the next major version, too!

GCC recently added it as [[gnu::musttail]] so there's no longer any dispute among the Big Compilers that this is deliverable (apparently they just kinda forgot to do it for several years)

torsten_dev

Interesting Interesting. I do take issue with _Self. I'd prefer _Recur.

That's more in line with existing practices in functional languages and will not confuse the object oriented guys needlessly.

EDIT: author seemed receptive to changing it. Big ups.