Could you make the badge the last argument and give it a default value, so you don't need the initialization at the function call? It looks a bit strange and would need an explanation for why the empty initialization list is there IMO.
I'm not sure if it would work, cppreference has this to say about default arguments:
> The names used in the default arguments are looked up, checked for accessibility, and bound at the point of declaration, but are executed at the point of the function call
It's an empty struct so the compiler will elide any storage either way, but agreed having it be the first arg is a bit odd. Perhaps it's for regularity in the cases where you want to make variadic functions 'badged' in this way.
I'm surprised, particularly about the cross-linking bit as that seems to violate the spec (per my recollection of the spec, which is the most likely thing to be wrong).
It's worth noting that it does apply to the latest gcc and Clang but not to all the compilers listed there. For an example of a difference, the latest djggp (7.2.0) inserts an extra push in the call when the empty argument is present.
If you use a calling convention that mandates the use of stack, you would see that push, or at least have a byte reserved.
AFAICT the C++ standard itself does not specify the particulars of calling convention, which is a function of the platform, compiler and flags/attributes.
I'm not sure if it would work, cppreference has this to say about default arguments:
> The names used in the default arguments are looked up, checked for accessibility, and bound at the point of declaration, but are executed at the point of the function call
https://en.cppreference.com/w/cpp/language/default_arguments