hegendroffer hegendroffer - 1 month ago 8
C Question

A complicated syntax over preprocessor in C

I am trying to figure out code in C and I am stuck at trying to understand what the part of preprocessor actually does. The part of code I do not understand is following:

#define ERR(source) (perror(source),\
fprintf(stderr,"%s:%d\n",__FILE__,__LINE__),\
exit(EXIT_FAILURE))


whole code is very short, and looks as follows:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ERR(source) (perror(source),\
fprintf(stderr,"%s:%d\n",__FILE__,__LINE__),\
exit(EXIT_FAILURE))

int main(int argc, char** argv) {
char name[22];
scanf("%21s",name);
if(strlen(name)>20) ERR("Name too long");
printf("Hello %s\n",name);
return EXIT_SUCCESS;
}

Answer

The backslash in the macro means you can read the next line as if it is one line, so it boils down to this:

 #define ERR(source) (perror(source), fprintf(stderr,"s:%d\n",__FILE__,__LINE__), exit(EXIT_FAILURE))

A #define preprocessor statement is used to replace code with other code, for example

#define SOMECONSTANT 5

will replace SOMECONSTANT in your code with 5, before compiling the code. The preprocessor also understands function-like syntax, which is what you have here.

Your macro results in the following main body:

int main(int argc, char** argv) {
    char name[22];
    scanf("%21s",name);
    if(strlen(name)>20) (perror("Name too long"), fprintf(stderr,"s:%d\n",__FILE__,__LINE__), exit(EXIT_FAILURE));
    printf("Hello %s\n",name);
    return EXIT_SUCCESS;
}

The macro in your case uses the comma-operator to put a few statements together, so you can use it as one statement. Usually, your code would be written as:

int main(int argc, char** argv) {
    char name[22];
    scanf("%21s",name);
    if(strlen(name)>20) {
          perror("Name too long");
          fprintf(stderr,"s:%d\n",__FILE__,__LINE__);
          exit(EXIT_FAILURE);
    }
    printf("Hello %s\n",name);
    return EXIT_SUCCESS;
}

Hopefully you understand what is going on now.