Can I use "(" in preprocessor concatenation in C? - c

The following gives this error in GCC: pasting "func_x" and "(" does not give a valid preprocessing token
#include <stdio.h>
#define LOG_FUNC(fname) printf( #fname " %d\n", fname ## ())
int func_x(){
return 0;
}
int main(){
LOG_FUNC(func_x);
return 0;
}
However, when I hover the mouse on top of the function, it shows that the macro expands to following expression that works without a problem
printf("func_x" " %d\n", func_x())
Is it because the parenthesis is not allowed in pre processor string concatenation?

If you want to get your code to compile, change LOG_FUNC to:
#define LOG_FUNC(fname) printf( #fname " %d\n", fname())
If you want to concatenate two strings together, just write them next to each other, separated by whitespace. It is OK if they contain parens. You don't have to use the preprocessor for this, but you can:
#include <stdio.h>
#define MY_STR(f) f "(\n"
int main() {
puts(MY_STR("hi")); // outputs "hi("
return 0;
}

Related

C: Is there a way to define a macro AND output some code in a single statement?

I would like to define a macro that would generate program text for me AND also set some non-string macro value. I know that including #define in another #define is not going to work so I'm trying to find a different way.
A simple example:
#include <stdio.h>
#define START_SYNTHETIC int SYNTHETIC_FUNCTION() {
#define END_SYNTHETIC return 0;}
#define SYNTHETIC_FUNCTION my_function
START_SYNTHETIC
printf("Hello from %s", "SYNTHETIC_FUNCTION");
END_SYNTHETIC
int main() {
my_function();
}
This code kinda works, it produces the following output:
Hello from SYNTHETIC_FUNCTION
There are two problems with it:
function name is not expanded and I just have "SYNTHETIC_FUNCTION" in the output. This is currently not critical but might be needed later on.
I dislike having three lines to start my synthetic function. The empty line inserted by autoformatter is especially irritating. Can I reduce this to just a single macro invocation?
Is there a way to define a macro AND output some code in a single statement?
No, in C macros can't define other macros.
function name is not expanded and I just have "SYNTHETIC_FUNCTION" in the output.
Sure it doesn't - it's inside a string literal. Macro replacement is not done inside a string literal.
Can I reduce this to just a single macro invocation?
I do not understand the point at all of this code. Just use __func__.
int my_function(void) {
printf("Hello from %s\n", __func__);
return 0;
}
or pass the name as a macro parameter:
#define SYNTHETIC(name) \
int name(void) { \
printf("Hello from %s\n", #name); \
printf("but really, just use __func__ anyway...: %s\n", __func__); \
return 0; \
}
SYNTHETIC(my_function)

How can I use variable width specifiers defined by a macro in sscanf()

I am trying to specify the width of variables in a sscanf() call based on a #define that calculates its values based on another #define.
It works when the TEST define is just a single number, but when it becomes a calculation, the code fails. Have TEST call another function that contains the calculation does not work either.
The code I am working with:
#include <stdio.h>
#define A 3
#define TEST FUN()
#define FUN() (A + 2)
#define STR(X) _STR(X)
#define _STR(x) #x
int main()
{
char input[] = "Test123";
char output[10];
sscanf(input, "%" STR(TEST) "s\n", output);
printf("%s\n", output);
return 0;
}
What am I missing here?
You cannot realize an arithmetic operation as happened in your question. So, it is evaluated as (3 + 2) in string form while compiling.
My two cents reminiscent of the post,
#define STRING_LENGTH 20
#define STR(x) _STR(x)
#define _STR(x) #x
{
...
fscanf(input, "%" STR(STRING_LENGTH) "s", output);
...
}
Two macros are required because if you tried to use something like _STR directly you would just get the string "STRING_LENGTH" instead of its value.
For more click here and an example.
Just build the scanf format string during execution. For example:
const int width_modifier = FUN();
char fmt[100] = {0};
snprintf(fmt, sizeof(fmt), "%%%ds\n", width_modifier);
sscanf(input, fmt, output);
What am I missing here?
Preprocessor does text replacement, it doesn't calculate things. So "%" STR(TEST) "s\n" expands to a string containing "%" "3 + 2" "s\n", which after concatenation is "%3 + 2s", which is an invalid scanf format string.
Alternatively you can use other program to prepare the source file for compilation. A popular use is a preprocessor that preprocesses the file before compilation and that is able to calculate arithmetic. A popular choice is m4:
m4_define(`A', 3)
m4_define(`FUN', `eval(A + 2)')
#include <stdio.h>
#define STR(X) #X
int main() {
printf("%s", STR(FUN()));
}
preprocessed with m4 and compiled would output 5.
#include <stdio.h>
#include <string.h>
#define MAX_LENGTH 5
int main()
{
// specify format
char formatStr[20] = {0};
snprintf(formatStr, 20-1, "%s%d%s", "%", MAX_LENGTH-1, "s%u");
printf("%s\n", formatStr);
// example to use that format
char *input = "programming 123";
char dataStr[MAX_LENGTH] = {0};
int dataVal;
sscanf(input, formatStr, dataStr, &dataVal);
printf("%s-%d\n", dataStr, dataVal);
return 0;
}
output:
%4s%u
prog-21942

why the macro definition "#define yyparse ol_parser_parse" can work?

Before, I did't read the generated code from yacc carefully. Now I saw one snippet of code like this:
#define yyparse ol_parser_parse
I know yyparse's definition as follows:
int yyparse (void)
so, this macro definition should be interpreted as: every "ol_parser_parse" in code will be replaced by "yyparse". And I wrote some code for testing that:
#include <stdio.h>
#define yyparse ol_parser_parse
void yyparse()
{
printf("hello world\n");
}
void main()
{
ol_parser_parse();
}
It worked!
But according to the definition about "macro definition":
#define <identifier>(<parameter list>) <replacement token list>
I am confused by this. Who can help me explain this? Thanks in advance!
Here's your code as seen by the compiler after the substitution is performed:
#include <stdio.h>
void ol_parser_parse()
{
printf("hello world\n");
}
void main()
{
ol_parser_parse();
}
There's nothing mysterious about it at that point. Every instance of "yyparse" becomes "ol_parser_parse" on every line following the #define.
In the documentation identifier means the thing being substituted and replacement token list is what you're substituting it with. You can also have parameters, like:
#define TIMES_TWO(n) ((n) * 2)
Where you can then do:
int x = TIMES_TWO(3);
Where that's equivalent to:
int x = ((3) * 2);
Where the extra brackets are so you can do this and not mess up order of operations:
int x = TIMES_TWO(1 - 5);
Without the brackets it'd show up as this:
int x = 1 - 5 * 2;
Which evaluates to 1 - 10 which is not what you want.
There's an art to using #define effectively to hide otherwise ugly implementation details. The name ol_parser_parse isn't something you need to worry about if you can use the yyparser macro. That gives the implementers the freedom to rename that function and the corresponding macro without breaking all your code.

C preprocessing multi pass

I'm a littlebit confused about the behaviour of preprocessing in c.
#include <stdio.h>
#define myMacro anotherMacro
#define anotherMacro 6
int main()
{
int dummy = myMacro;
printf("dummy = %d", dummy);
return 0;
}
in the above code snippet, the result will 6. however the the macro expansion in the initial pass will replace "myMacro" by "anotherMacro".
this is means that preprocessor will make a second pass to resolve "anotherMacro" to value 6.
The preprocessor will make a second pass. He works through the source file line per line.
So if he reaches the first define
#define myMacro anotherMacro
he will replace all occurrences of myMacro with the string anotherMacro.
The file will look like this after the line is handled:
#include <stdio.h>
#define anotherMacro 6
int main()
{
int dummy = anotherMacro;
printf("dummy = %d", dummy);
return 0;
}
Now the preprocessor could continue with the next #define
and replace every anotherMacro with the text 6

Why "vsprintf" is getting stuck when calling a function from a macro using __VA_ARGS__?

I have the following macro:
#define TRACE__LOW(str, col, ...)\
TR_Trace("\r\e[" COLOR(col) "%s :: %s():%d; LOW - " str "\e[0m\r\n",\
##__VA_ARGS__);
And the function TR_Trace looks like this:
void TR_Trace(const char *const string, ...)
{
va_list aptr;
size_t stringSize = 0;
char tempString[250];
va_start(aptr, string);
vsprintf(tempString, string, aptr);
va_end(aptr);
}
And I'm using it like this:
TRACE__LOW("Led[%d] toggled every %d milliseconds (%5d)", GREEN
init_parameters.led, delay_time, counter++);
The problem here is that once the execution gets to vsprintf(tempString, string, aptr); it gets stuck there.
Do anybody know what is happening or if I'm not using correctly the VA_ARGS?
Regards.
You adding %s :: %s():%d; to format string, but don't adding extra arguments to fill these patterns.
I suppose it meant to be
#define TRACE__LOW(str, col, ...)\
TR_Trace("\r\e[" COLOR(col) "%s :: %s():%d; LOW - " str "\e[0m\r\n",\
__FILE__, __func__, __LINE__,\
##__VA_ARGS__);
Random thoughts:
Your use of __VA_ARGS__ appears to be correct.
The TRACE__LOW macro adds a superfluous semi-colon to the output (could cause problems for conditional statements that don't have curly braces).
I don't know what COLOR(GREEN) expands to, so that may be the source of the problem.
Suggestion:
Your compiler should have an option to output the results from the preprocessor. On the compiler I'm using that option is -E. If you have the compiler output the results from the preprocessor, you can see precisely what your macro expands to.
For example, compiling the following code with -E
#include <stdio.h>
#define TRACE__LOW(str, col, ...)\
TR_Trace("\r\e[" COLOR(col) "%s :: %s():%d; LOW - " str "\e[0m\r\n",\
##__VA_ARGS__);
int main( void )
{
TRACE__LOW( "test", 3, a, b, c );
}
produces this output (after about 5 million other lines ;) )
int main( void )
{
TR_Trace("\r\e[" COLOR(3) "%s :: %s():%d; LOW - " "test" "\e[0m\r\n", a, b, c);;
}

Resources