0

I am trying to find a way to dynamically access a certain macro in C.

I tried to include the macro in the struct but then I get the "initializer element is not constant" error. Basically I just want to access the correct macro based on an index but I just don't know how. Is there a straight forward way of accomplishing this? Please note the code is not complete but only an illustration of what I want to do.

#define Data_CAN_SES_Enbl() (...)
#define Data_CAN_SAS_Enbl() (...)
#define Data_CAN_PEP_Enbl() (...)


struct CAN_Rx {
    const uint8 id;                     
    const uint8 bus;                    
    xx
};

static struct CAN_Rx CheckRx[] = {
    /* SES */
    {
        0,0,?
    },
    /* SAS */
    {
       1,0,?
    },
    /* PEP */
    {
       2,1,?
    }
};

void run(uint8 index)
{
    uint8 enabled = CheckRx[index].xx;
}
melpomene
  • 84,125
  • 8
  • 85
  • 148
Cecilia
  • 1
  • 1
  • 1
    Possible duplicate of [Array of macros in c -- is it possible](https://stackoverflow.com/questions/36493099/array-of-macros-in-c-is-it-possible) – Sander De Dycker Jul 30 '19 at 08:42

3 Answers3

0

Simply put: you won't. Dont think of macros as code: they're just chunk of text replaced by the preprocessor before compiling your code. If you need to embed code in a struct, you better look at function pointers.

--- EDIT ---

By the way, why you want to use macro in your code? Looking at it, it seems you cand do the same thing with a simple function returning a struct with a different content based on a parameter, like:

static struct CAN_Rx getCANrx(int index){
    switch(index)
    {
    case '0':
        struct CAN_rx res = /* initialize struct */;
        return res;
    case '1':
        /* as previous */
    default:
        /* manage default result or errors */
    }
}
Marco Sanfilippo
  • 293
  • 3
  • 11
  • Ok, is there another way achieving the same thing without using structs? The thing is I cannot change the macros (they are generated) and I would rather not have to call each macro individually. – Cecilia Jul 30 '19 at 08:28
0

Maybe you can go with function pointers?

#include <stdio.h>

int Data_CAN_SES_Enbl() { return 0; }
int Data_CAN_SAS_Enbl() { return 1; }
int Data_CAN_PEP_Enbl() { return 2; }

struct CAN_Rx {
    const int id;
    const int bus;
    int (*xx)();
};

static struct CAN_Rx CheckRx[] = {
    /* SES */
    {
        0,0,Data_CAN_SES_Enbl
    },
    /* SAS */
    {
       1,0,Data_CAN_SAS_Enbl
    },
    /* PEP */
    {
       2,1,Data_CAN_PEP_Enbl
    }
};

int run(int index)
{
    int enabled = (*CheckRx[index].xx)();
    return enabled;
}

int main() {
  printf("%d\n",run(0));
}
Oo.oO
  • 12,464
  • 3
  • 23
  • 45
0

If you are curious see below macro example.

For your case , macro cant be better than function pointers.

Using macro just for fun at your case.

#include <stdio.h>
#include <stdlib.h>
#define Data_CAN_SES_Enbl(Y,Z) Y+Z
#define Data_CAN_SAS_Enbl(Y,Z) Y*Z
#define Data_CAN_PEP_Enbl(Y,Z) Y-Z
#define Str(X) #X


#define Data_CAN_Enbl(X,Y,Z) Data_CAN_##X##_Enbl(Y,Z);

#define SES 1
#define SAS 2
#define PEP 3

struct CAN_Rx {
    int id;                     
    int bus;
    int Flag;
};

static struct CAN_Rx CheckRx[] = {
    /* SES */
    {
        0,100,SES
    },
    /* SAS */
    {
       70,20,SAS
    },
    /* PEP */
    {
       100,50,PEP
    }
};

void run(int index)
{
    int RRR=0;

    switch(CheckRx[index].Flag){
        case SES:
            RRR=Data_CAN_Enbl(SES,CheckRx[index].id,CheckRx[index].bus);
            printf("%s :%d\n",_Str(SES),RRR);
        break;
        case SAS:
            RRR=Data_CAN_Enbl(SAS,CheckRx[index].id,CheckRx[index].bus);
            printf("%s :%d\n",_Str(SAS),RRR);
        break;
        case PEP:
            RRR=Data_CAN_Enbl(PEP,CheckRx[index].id,CheckRx[index].bus);
            printf("%s :%d\n",_Str(PEP),RRR);
        break;
    }

}
int main(){



    run(0);
    run(1);
    run(2);


    printf("%d\n",CheckRx[0].Flag);

    return 0;
}
J CHEN
  • 494
  • 3
  • 9