2

I'd like to get a C macro (or several) that could serve two purposes:

  • Declare a const variable.
  • Add that variable to an array.

I.e , if I have this

typedef struct {
  int port;
  int pin;
} pin_t; 

A macro like this

#define DEFINE_PIN(name, port, num)   

should expand to something like this

#define NAME port, num
const pin_t[] = {
    {NAME}
};

And each definition should append the new defined variable to the array.

I know that a #define cannot expand to #defines but is just an illustration. What I want to accomplish is, on one hand, to define the pin be used wherever necessary and, on the other hand, have an easy way to traverse all the pins, i.e for configuring the hardware gpios.

3
  • In case you are using gcc, gcc -E <file.c> is a good way to test your macro expansions, since it does only runs the preprocessor step on file <file.c>. Just beware that includes are also expanded, so you might temporary remove them. Commented Apr 1, 2020 at 16:32
  • 1
    I can suggest a variant of my answer to this question. I could tailor that solution to your scenario, in case you need, but probably it is not necessary. Pros: compared to the answer below it doesn't need the position field. And the population is done at initialization time. Cons: someone might not find it elegant. But it is currently used in big projects. Commented Apr 1, 2020 at 17:16
  • 1
    If you have a smart compiler, you can do something that looks stupid: just make a big const array of pins, with each entry having a string member giving its name, and write a function that, given a string, searches the array and returns the pin with that name. If you enable inlining and call the search function with a string literal, a good compiler like gcc will optimize the whole thing out and reduce it to the appropriate constant. Example. Commented Apr 1, 2020 at 20:15

1 Answer 1

3

Below is the header file containing the defines so that they can be used in other compilation units:

#include <stdio.h>

#ifndef header_constant
#define header_constant

typedef struct {
  int port;
  int pin;
} pin_t;

pin_t pinArray[100];

#define DEFINE_PIN(name, port, num,arrayPos) \
  const pin_t name = {port, num};\
  pinArray[arrayPos]= name;


#endif

Note: the \ character tells the compiler to continue using the next line as part of the macro.

Below is the main program:

# include "headername.h"

void main(){
  DEFINE_PIN(pin1,1,2,0);
  DEFINE_PIN(pin2,3,4,1);
  DEFINE_PIN(pin3,6,5,2);
  printf("%d",pin2.pin);
}
Sign up to request clarification or add additional context in comments.

13 Comments

Note: the \ character tells the compiler to continue using the next line as part of the macro
@perencia Edited the answer. The above code compiles on gcc. Could you elaborate the problem?
I'd like to be able to reference the const variable and the array on other source files. With your code all is local to the method in which the define is used.
I suggested an edit. When a new requirement is shown in comments don't write edit:; just incorporate it in your answer. Remember that comments can be deleted after a certain amount of time, and your answer might be useful also to other users, not only the OP. ;)
@perencia would it work if you created a text file into which you read and write the array elements? Also, I'm not sure but maybe you could somehow use extern to share the variables
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.