1

I know macro can return value of custom type:

#define returnVal(type) ({ \
    type val;              \
    val;                   \
})

I am trying to create a macro which can return custom type pointer by input number. (So it can be dynamic)

// Pseudo code
#define returnPtr(number) ({              \
   // if number == 1, return int *val     \
   // if number == 2, return int **val    \
   // if number == 3, return int ***val   \
})

I tried some approaches but it doesn't work:

#define returnPtr(number) ({                             \
    type = number == 1 ? int * : number == 2 ? int **    \
                                             : int ***;  \
    type val;                                            \
    val;                                                 \
})

How to return custom type pointer by input number in a macro function?

kelvinwong
  • 103
  • 5
  • 1
    You might be able to use [_Generic](https://stackoverflow.com/questions/9804371/syntax-and-sample-usage-of-generic-in-c11) for this. – sj95126 Aug 23 '22 at 05:03
  • 3
    Why do you want to do this? It feels like an XY Problem. Macros are rarely a good answer to a problem. – Jonathan Leffler Aug 23 '22 at 05:22
  • 3
    If the purpose is to write bad and hard to read code, you are on the correct path.... If that isn't the purpose just drop the idea – Support Ukraine Aug 23 '22 at 06:57
  • Please note that `({` are so-called "expression statements", a gcc extension and not standard C. – Lundin Aug 23 '22 at 07:32

1 Answers1

1

If the macro argument is just a literal 0, 1, etc., this can be done by pasting it (with ##) to form a name (like TYPE0, TYPE1, etc.) that is defined as a macro to be replaced with a type name. The following code shows a way to do this. Note that writing code like this is generally bad practice absent compelling reason.

#include <stdio.h>    


#define TYPE1   int *
#define TYPE2   int **
#define TYPE3   int ***


#define Kludge(number)  (TYPE##number) {0}


#define Demo(number)                \
    _Generic(Kludge(number),        \
        int *:    "int *",          \
        int **:   "int **",         \
        int ***:  "int ***",        \
        default:  "something else")


int main(void)
{
    puts(Demo(1));
    puts(Demo(2));
    puts(Demo(3));
}

Output:

int *
int **
int ***
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312