7

Inside linux kernel sources i see that, inside enums, is there also a define with the same name of enum element. Example in linux/rtnetlink.h we have:

enum {
        RTM_BASE        = 16,
#define RTM_BASE        RTM_BASE

        RTM_NEWLINK     = 16,
#define RTM_NEWLINK     RTM_NEWLINK
        RTM_DELLINK,
#define RTM_DELLINK     RTM_DELLINK
...

What is the reason for this? I can't figure out how this is used.

Thanks

MirkoBanchi
  • 2,173
  • 5
  • 35
  • 52

3 Answers3

5

One thing I could think of is that you can check for the very existence of the enum by means of the macro:

#ifdef RTM_BASE
int flag = RTMBASE;
#else
int flag = 0;
#endif

No idea if that's what's going on, though.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Yes, that's exactly what I was going to write after I finished my sandwich. It's the only purpose I can see this really serving – Keldon Alleyne Oct 02 '12 at 10:39
  • Useful! But looking at the sources, it seems that defines are not used in this way. Thank you. – MirkoBanchi Oct 02 '12 at 12:14
  • 1
    It wouldn't make sense to do this in the kernel sources, but it does make sense in user-space applications that might need to work on multiple kernel versions, where capabilities may or may not be present. – Lance Richardson Oct 02 '12 at 13:54
  • 1
    You can find examples in e.g. ISC ntpd sources at http://www.isc.org/software/ntp. – Lance Richardson Oct 02 '12 at 14:06
4

Another thing these #defines achieve, besides allowing old code to continue the old names should the enum constant names be changed, and checking whether they are defined, is to prevent other code to define these symbols.

#include <linux/rtnetlink.h>
// for some reason, the author thinks
#define RTM_BASE 17.3f
// is a good idea

would not compile.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
  • This answer is in my opinion the right one. The 2 other answers look rather contrived to me. This one has the potential to uncover real, hard to find, name clashes, which are quite easy to make. – Patrick Schlüter May 13 '15 at 13:59
2

Another guess: this macro could allow renaming an entry of the enum without breaking other code. Change

enum {
        RTM_BASE        = 16,
#define RTM_BASE        RTM_BASE

to

enum {
        RTM_BASE_NEW_NEW_NEW        = 16,
#define RTM_BASE        RTM_BASE_NEW_NEW_NEW

A user could still use RTM_BASE.

evnu
  • 6,450
  • 2
  • 27
  • 38