In this post, I am going to talk about the stringizing operator in C. We know that the symbol "#" is used in C preprocessor directives (#define statements). In addition, it has special functionality. The # is used as stringizing operator in C.This operator generates a double quoted string when it is preceded by some multi-word string. This multi-word string can have variable name, random string, numbers, etc. This operator can be used only in the macro expansions.
Sample Program:
#include <stdio.h>
#include <string.h>
#define MAXVALUE 10
#define LOG_FAILURE(x) if(x) \
/* Condition Met; no need to log*/; \
else \
LogFn (#x,__func__,__LINE__)
void LogFn(const char *logstr, const char *FnName,unsigned int line)
{
printf ("LOG: FAILED CONDITION -> %s : In FUNCTION -> %s: In LINE -> %u\n",
logstr, FnName, line);
}
int main ()
{
int testval = 5;
char name[] = "NAMETEST";
LOG_FAILURE ((testval > MAXVALUE) && "Comparing testval and MAXVALUE"); // This will log the statement as the test result fails.
testval = 15;
LOG_FAILURE ((testval > MAXVALUE) && "Comparing testval and MAXVALUE"); // This will not be logged as the test result passes
testval = 2;
LOG_FAILURE ((strlen(name) > MAXVALUE) && "Comparing string length and MAXVALUE"); // This will be logged as the test result fails.
return 0;
}
Output:
LOG: FAILED CONDITION -> (testval > MAXVALUE) && "Comparing testval and MAXVALUE" : In FUNCTION -> main: In LINE -> 20
LOG: FAILED CONDITION -> (strlen(name) > MAXVALUE) && "Comparing string length and MAXVALUE" : In FUNCTION -> main: In LINE -> 28
Expanded source code after Macro Expansion:
# 9 "stringize_oper1.c"
void LogFn(const char *logstr, const char *FnName,unsigned int line)
{
printf ("LOG: FAILED CONDITION -> %s : In FUNCTION -> %s: In LINE -> %u\n",
logstr, FnName, line);
}
int main ()
{
int testval = 5;
char name[] = "NAMETEST";
/* The macro is expanded after preprocessing; Note that the argument preceded by # has now been converted into double-quoted string */
if((testval > 10) && "Comparing testval and MAXVALUE") ; else LogFn ("(testval > MAXVALUE) && \"Comparing testval and MAXVALUE\"",__func__,20);
testval = 15;
if((testval > 10) && "Comparing testval and MAXVALUE") ; else LogFn ("(testval > MAXVALUE) && \"Comparing testval and MAXVALUE\"",__func__,24);
testval = 2;
if((strlen(name) > 10) && "Comparing string length and MAXVALUE") ; else LogFn ("(strlen(name) > MAXVALUE) && \"Comparing string length and MAXVALUE\"",__func__,28);
return 0;
}
As highlighted above, we can know that the multi-word argument "x" passed to the macro has been converted into single double quoted string by # operator. Consider the below statement.
LOG_FAILURE ((testval > MAXVALUE) && "Comparing testval and MAXVALUE");
In this statement, we have multi-word string. i.e. testval, > , MAXVALUE, etc. All of them are concatenated and one single double quoted string is created which is getting printed.
Sample Program:
#include <stdio.h>
#include <string.h>
#define MAXVALUE 10
#define LOG_FAILURE(x) if(x) \
/* Condition Met; no need to log*/; \
else \
LogFn (#x,__func__,__LINE__)
void LogFn(const char *logstr, const char *FnName,unsigned int line)
{
printf ("LOG: FAILED CONDITION -> %s : In FUNCTION -> %s: In LINE -> %u\n",
logstr, FnName, line);
}
int main ()
{
int testval = 5;
char name[] = "NAMETEST";
LOG_FAILURE ((testval > MAXVALUE) && "Comparing testval and MAXVALUE"); // This will log the statement as the test result fails.
testval = 15;
LOG_FAILURE ((testval > MAXVALUE) && "Comparing testval and MAXVALUE"); // This will not be logged as the test result passes
testval = 2;
LOG_FAILURE ((strlen(name) > MAXVALUE) && "Comparing string length and MAXVALUE"); // This will be logged as the test result fails.
return 0;
}
Output:
LOG: FAILED CONDITION -> (testval > MAXVALUE) && "Comparing testval and MAXVALUE" : In FUNCTION -> main: In LINE -> 20
LOG: FAILED CONDITION -> (strlen(name) > MAXVALUE) && "Comparing string length and MAXVALUE" : In FUNCTION -> main: In LINE -> 28
Expanded source code after Macro Expansion:
# 9 "stringize_oper1.c"
void LogFn(const char *logstr, const char *FnName,unsigned int line)
{
printf ("LOG: FAILED CONDITION -> %s : In FUNCTION -> %s: In LINE -> %u\n",
logstr, FnName, line);
}
int main ()
{
int testval = 5;
char name[] = "NAMETEST";
/* The macro is expanded after preprocessing; Note that the argument preceded by # has now been converted into double-quoted string */
if((testval > 10) && "Comparing testval and MAXVALUE") ; else LogFn ("(testval > MAXVALUE) && \"Comparing testval and MAXVALUE\"",__func__,20);
testval = 15;
if((testval > 10) && "Comparing testval and MAXVALUE") ; else LogFn ("(testval > MAXVALUE) && \"Comparing testval and MAXVALUE\"",__func__,24);
testval = 2;
if((strlen(name) > 10) && "Comparing string length and MAXVALUE") ; else LogFn ("(strlen(name) > MAXVALUE) && \"Comparing string length and MAXVALUE\"",__func__,28);
return 0;
}
As highlighted above, we can know that the multi-word argument "x" passed to the macro has been converted into single double quoted string by # operator. Consider the below statement.
LOG_FAILURE ((testval > MAXVALUE) && "Comparing testval and MAXVALUE");
In this statement, we have multi-word string. i.e. testval, > , MAXVALUE, etc. All of them are concatenated and one single double quoted string is created which is getting printed.
No comments:
Post a Comment