0

I want to print headers hierarchy in some automated way. The goal is to preserve order in header files inclusion.

I have tried to do the following in header "tmp1.h":

#ifndef HIERARCHY_PRINTING
#define HIERARCHY_PRINTING "start: "
#endif 

#undef PREVIOUS_PRINTING
#define PREVIOUS_PRINTING HIERARCHY_PRINTING "->"
#undef HIERARCHY_PRINTING
#define HIERARCHY_PRINTING PREVIOUS_PRINTING "tmp1.h"

#ifndef _TMP1_
#define _TMP1_

// Some stuff

#endif

#undef PREVIOUS_PRINTING
#define PREVIOUS_PRINTING HIERARCHY_PRINTING ";"
#undef HIERARCHY_PRINTING
#define HIERARCHY_PRINTING PREVIOUS_PRINTING

And in "tmp.c":

#include <stdio.h>
#include "tmp1.h"

const char *str = HIERARCHY_PRINTING;

int main() {
    printf("Headers hierarchy:\n");
    printf("%s\n", str);

    return 0;
}

But this doesn't compile:

tmp.c:7:19: error: ‘HIERARCHY_PRINTING’ undeclared here (not in a function)
tmp.c:7:19: error: expected ‘,’ or ‘;’ before string constant

I expected to see something like:

start: ->tmp1.h;

Where I'm wrong?

Link42
  • 43
  • 4
  • You have a circular reference in the macros you've written: `HIERARCHY_PRINTING` expands to `PREVIOUS_PRINTING`, which then expands to `HIERARCHY_PRINTING ";"`, etc etc. That said, the compiler errors I get when compiling this code are a little different, so it's possible that something was lost in translation when you simplified your example. – Haldean Brown Nov 22 '16 at 16:30
  • @HaldeanBrown What error did you get? Actually I didn't simplify anything since it is just an experiment. – Link42 Nov 23 '16 at 12:53
  • You'll get better help if you post an example that exhibits the behavior you're asking about! Here's the code I compiled and the output from the compiler: http://lpaste.net/345138 – Haldean Brown Nov 23 '16 at 16:24

1 Answers1

1

If I understand correctly you tried to save some intermediate result in PREVIOUS_PRINTING macro definition which should store the contents of macro HIERARCHY_PRINTING at that point to be used later, after HIERARCHY_PRINTING is undefined.

But such approach doesn't work since preprocessor doesn't unfold definitions until they are needed. And #undef command just throws away what was defined before it. So for your example when preprocessor finishes handling of the header file it will have the following:

#define PREVIOUS_PRINTING HIERARCHY_PRINTING ";"
#define HIERARCHY_PRINTING PREVIOUS_PRINTING

So when it will try to unfold the value of HIERARCHY_PRINTING it will get HIERARCHY_PRINTING ";" and that it since recursion is prohibited. And finally the compiler will complain for the undeclared HIERARCHY_PRINTING since there no such declarations in the code.

dkolmakov
  • 637
  • 5
  • 12