As a possible solution to your problem: “write a macro and then discard it, replacing it with an equivalent function”, you can use prototyped macros similar to functions. They have some limitations and should be used with some caution. But they work almost the same as a function.
#define xxPseudoPrototype(RETTYPE, MACRODATA, ARGS) typedef struct { RETTYPE xxmacro__ret__; ARGS } MACRODATA xxPseudoPrototype(float, xxSUM_data, int x; float y; ); xxSUM_data xxsum;
I explained the details here (mainly section 4, for macros like functions):
Macro rigging features
- The first line defines a macro that can be used to declare pseudo-prototypes for macros.
- The second line uses this macro to provide such a pseudo-prototype. It defines the “formal” parameters of the desired types. It contains the desired type of "return" for the macro, the name of the structure where the macro parameters will be stored, and finally, the parameters (with types!) Of the macro. I prefer to call them pseudo-parameters.
- The third line is a mandatory statement that makes pseudo-parameters “real”. He announces the structure to be written. It defines a structure containing a "real" version of pseudo-parameters.
- Finally, the macro itself is defined as a chained list of expressions separated by commas. The first operand is used to "load" macro arguments into "real" typed parameters. The last operand is the "return value", which also has the desired type.
Please note that the compiler makes correct and transparent type diagnostics.
(However, it is necessary to have some relation to these constructions, as explained in the link).
Now, if you can collect all the sentences of your macro as a chain of function calls, separated by commas, then you can get the function macro as you need.
In addition, you can easily convert it to a real function, since the parameter list is already defined. Type checking has already been done, so everything will work fine. In the above example, you need to replace all lines (except the first) with the following:
#define xxPseudoPrototype(RETTYPE, MACRODATA, ARGS) typedef struct { RETTYPE xxmacro__ret__; ARGS } MACRODATA float SUM_intfloat(int x, float y) { xxPseudoPrototype(float, xxSUM_data, int x; float y; ); xxSUM_data xxsum; return ( xxsum = (xxSUM_data){ .x = x, .y = y }, xxsum.xxmacro__ret__ = xxsum.x + xxsum.y, xxsum.xxmacro__ret__) ; }
The replacement will follow the system procedure:
(1) The macro header has turned into a function header. Semicolons (;) are replaced by commas (,).
(2) The declaration lines move inside the function body.
(3) Added the word "return".
(4) Macro arguments X, Y, are replaced by functional parameters x, y.
(5) All trailing "\" s are deleted.
(6) All intermediate calculations and function calls remain intact.
(7) Added semicolon. (8) The body of the closing function.
Problem:. Although this approach solves your needs, note that the function duplicates its parameter list. This is not good: pseudotrotypes and duplicates should be removed:
float SUM_intfloat(int x, float y) { return ( x + y ) ; }