1

I'm aware of multiple Q&As [1, 2]that touch closely on this subject, and I've tried to implement their solutions but the fact that I need to use the . in my concatenation seems to be causing me trouble.

This is what I want:

#include <stdio.h>

#define PROPERTY .value1
#define MAKE_PROP(var) var##PROPERTY

typedef struct {
    int value1;
    int value2;
} Node;

int main(void) {

    Node node;
    node.value1 = 1;
    node.value2 = 2;

    // MAKE_PROP(node) should evaluate to "node.value1".
    printf("%d", MAKE_PROP(node));

    return 0;
}

However it's giving me all sorts of errors. If I try the PASTER-EVALUATE idea from [2] then it tells me "pasting "." and "PROPERTY" does not give a valid preprocessing token".

Anyone know how to accomplish what I need? It's essential that it stays general and that I can use the var as this is something I'd like to call multiple times on different variable names.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Alexander Terp
  • 199
  • 2
  • 12
  • Unrelated to your problem, but unless better named and well-documented using macros like this obfuscates the code and will make it harder to read, understand, and (most importantly) *maintain*. You will also need many `MAKE_PROP` and `PROPERTY` macros, one for each of the members of the structure. – Some programmer dude Mar 12 '17 at 06:39
  • How to concatenate strings with C preprocessor with dots in them. http://stackoverflow.com/questions/10085594/how-to-concatenate-strings-with-c-preprocessor-with-dots-in-them – Xu Han Mar 12 '17 at 06:46

1 Answers1

6

It's not working for two reasons:

  1. The token concatenation operator suppresses the expansion of macros that are used as its operands. So you get nodePROPERTY. The solution to that is to add a level of indirection:

    #define PROPERTY .value1
    #define CONCAT(a, b) a##b
    #define MAKE_PROP(var) CONCAT(var, PROPERTY)
    

    Now PROPERTY is expanded before being fed as an argument to CONCAT.

  2. The result of concatenating tokens must be a single valid token, but node.value1 is 3 tokens (node, . and value1).

Now, it just so happens that you don't need concatenation at all, you just need to build the expression (node .value1) which can be done with following simple macros1:

#define PROPERTY value1
#define MAKE_PROP(var) ( (var).PROPERTY )

1: simplified with the help of Lundin.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458