Shih-Chan Huang
Shih-Chan Huang

Reputation: 209

How to design my macro to contain function return value

in order to prevent asking a X-Y problem, I'd like to describe my intention first. There are a lot of self-defined structs, all of them are static singleton variables. I'd like to design a macro ( or function ) to get the specific address to what I want. Here's what I do so far:

/* the struct of apple, banana and cherry have been defined somewhere above
 * BUT NOT YET DECLARED */

const char *fruit_name[3] = {
    "apple",
    "banana",
    "cherry"
};

What I expected is that the the user could obtain the pointer to struct simply by offering number, that is, 0 to get the ptr to struct apple, 1 to get the ptr to struct banana and so on.

And I declare the static variable by:

#define DEFSTRUCT(struct_name) \
    static struct struct_name my##struct_name(void)  \
    { \
        static struct strcut_name singleton;  \
        return &singleton; \
    }

Then I use it to generate 3 functions, which will return the pointer to structs:

DEFSTRUCT(apple)    // whenever calls myapple() I got the reference to static struct apple 
DEFSTRUCT(banana)
DEFSTRUCT(cherry)

Here comes the most frustrating part, I CANNOT to make a macro ( or function ) to transfer the string to get access to them

Here's what I did, but in vain:

#define GETSTRUCT(struct_name) my##struct_name()

void get_fruit(void *ptr, int num) {
    ptr = GETSTRUCT(fruit_name[num]);  // I expect that ptr would points to static struct apple if num is 0;
}

However hard I try, the fruit_name[num] WILL NOT be transferred into correct string name, Is there anyone could specify what mistake I've made ? Thx a lot

Upvotes: 0

Views: 75

Answers (1)

Eric Postpischil
Eric Postpischil

Reputation: 222486

It is not possible for a function parameter num to be expanded to its value in a macro expansion or for an element of an array of strings to be expanded to its string in a macro expansion. Both of those require evaluation that never occurs in the preprocessor.

A function to return a pointer to a structure can be:

struct struct_name *get_fruit(void *pointer, int index)
{
    static struct struct_name ArrayOfTheseThings[] =
    {
        { contents of "apple" struct },
        { contents of "banana" struct },
        { contents of "cherry" struct },
    };

    return &ArrayOfTheseThings[index];
}

or:

struct struct_name *get_fruit(void *pointer, int index)
{
    const static struct struct_name *ArrayOfPointers[] =
    {
        &NameOfAppleStructDefinedElsewhere;
        &NameOfBananaStructDefinedElsewhere;
        &NameOfCherryStructDefinedElsewhere;
    };

    return ArrayOfPointers[index];
}

Upvotes: 1

Related Questions