Thursday, September 20, 2018

An overview of "#" operator in C - The "C" Stringizing Operator

    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.

No comments:

Post a Comment