15

I am looking into if_link.h in the Linux kernel headers and it contains this enum:

enum {
        IFLA_UNSPEC,
        IFLA_ADDRESS,
        IFLA_BROADCAST,
        IFLA_IFNAME,
        IFLA_MTU,
        IFLA_LINK,
        IFLA_QDISC,
        IFLA_STATS,
        IFLA_COST,
#define IFLA_COST IFLA_COST
        IFLA_PRIORITY,
#define IFLA_PRIORITY IFLA_PRIORITY
        IFLA_MASTER,
#define IFLA_MASTER IFLA_MASTER
....
}

The defines look useless; what is their purpose? And why do only some of the items have defines?

Boann
  • 48,794
  • 16
  • 117
  • 146
Zaboj Campula
  • 3,155
  • 3
  • 24
  • 42
  • 6
    Maybe the code uses `#ifdef IFLA_COST` somewhere – M.M Feb 18 '17 at 13:06
  • What is really puzzling is, Why to define the macros there. Because indeed, perhaps there is a use for them elsewhere that expect them to be macros. – Iharob Al Asimi Feb 18 '17 at 13:10
  • 3
    Maybe there used to be a `define` which was changed to an enum, and this is just for backward compatibility. Did you try `git blame`? – coredump Feb 18 '17 at 13:10
  • 1
    My guess is those enum valurs were added later so the defines are so code can use an ifdef to see if they are present. – John Hascall Feb 18 '17 at 13:14
  • @JohnHascall - could be but then an empty macro is sufficient - like `#define IFLA_COST`. – Zaboj Campula Feb 18 '17 at 13:17
  • 3
    http://stackoverflow.com/q/8588649/124319 – coredump Feb 18 '17 at 14:00
  • 1
    https://stackoverflow.com/questions/12688702/defines-inside-enum – coredump Feb 18 '17 at 14:00
  • 1
    @ZabojCampula if the macro was empty, you'd be screwed if you wanted to use the enum value as an enum value `if (blah == IFLA_COST) ...` would end up as `if (blah == ) ...` – John Hascall Feb 18 '17 at 21:00
  • 3
    Does this answer your question? [What does it mean by "#define X X"?](https://stackoverflow.com/questions/62355395/what-does-it-mean-by-define-x-x) – PiRocks Jun 19 '20 at 03:24
  • @PiRocks The answer "https://stackoverflow.com/questions/62355395/what-does-it-mean-by-define-x-x" does contain a generic answer to my question. But the accepted answer from coredump is better from my point of view. – Zaboj Campula Jun 24 '20 at 09:03

2 Answers2

11

As Matthew Slattery mentioned in another answer, the GCC manual has a section, namely §3.10.5 Self-Referential Macros, which describes the possible uses of such macros.

One possible use is to avoid infinite expansion when a macro expands into a call to itself, but this is a discouraged practice. The other use is to define both preprocessor macros and enums:

You might do this if you want to define numeric constants with an enum, but have `#ifdef' be true for each constant.

So this is basically what M.M said in the above comment.

This seems to be confirmed by this patch:

<rant> Why do the kernel developers behave so inconsistently? I much prefer interfaces where an enum value is ALSO added as a define to itself, to make it easy to probe which features are available in the current set of headers.

The really frustrating part is the some of the enum values in this set have #defines, and some of them don't.

coredump
  • 37,664
  • 5
  • 43
  • 77
1

This macros used in IPv4 protocol for provides the ability to create, remove, or get information about a specific network interface. See man page.

msc
  • 33,420
  • 29
  • 119
  • 214
  • 2
    This does not really explain why there is a mix of macros and enums. I did not find anything about this in the link, but maybe I missed it. Can you quote the relevant part of the man page? – coredump Feb 18 '17 at 15:39