Home > Blockchain >  C - errors with generic type to display a string
C - errors with generic type to display a string

Time:12-14

My printG() function must be able to display an int or a char or a character string. I have to use the _Generic type in order to do this.

In my printG() function (see io.h), if I put only the integer or the char (without the character string), and comment printG("Hello\n") in main.c, my program works.

However, if I try to be able to display the string, I have several errors, I cannot compile. (see errors pic at bottom)

How can I be able to display all three types with my printG() function with generic type ?

My code :

io.c :

void printChar(char c)
{
    print(1, &c, 1);
}


void printString(char* str)
{
    char *ptr;
    ptr=str; //assign address of str to ptr

    while(*ptr!='\0'){
        print(1, ptr, 1);
        ptr  ;
    }
        
}

void printInteger(int i)
{
    // printInteger code
}

io.h :

#ifndef IO_H
#define IO_H

//HERE :
#define printG(T) _Generic( (T), char: printChar(T), int: printInteger(T), char*: printString(T), default: 0)


// declarations of printChar(), printInteger(), printString()...


#endif

main.c :

#ifdef TODO6
printG(123);
EOL;
printG((char)'C');
EOL;
printG("Hello\n");
#endif  

The errors : compilation errors

CodePudding user response:

Since you use _Generic inside a macro, please note that the preprocessor will expand every _Generic clause even if not used. (Macro replacement happens much earlier in the translation phases than compile-time evaluation of _Generic or other such compile-time constant expressions.)

So after preprocessing you'll get something like

_Generic( (123), char: printChar(123), int: printInteger(123), char*: printString(123), default: 0)

And that's where the compiler errors are coming from. To avoid this, move the function arguments outside of the _Generic:

#define printG(T) _Generic( (T), char:  printChar,    \
                                 int:   printInteger, \
                                 char*: printString,  \
                                 default: 0) (T)

Now depending on which type that was found, you just get a function pointer, instead of a whole function call including possibly mismatching arguments.

  • Related