2

So, to start off, here's the code, with actual names switched for generic ones to limit confusion.

/* Get the list of Hotkey commands */
#define A_COMMANDS_MACRO(a, b, c, d) a = b ,
enum {
#include "commandsFile.def"
} ;
#undef  A_COMMANDS_MACRO

This is a snippet from some source code I have been looking over and considering forking as a way to familiarize myself with the intricacies of the C programming language. So, to my untrained eye, this appears to do nothing. To my brain, defining something and then immediately undefining it would seem to cancel each other out.

Obviously, I realize that I'm wrong. But why am I wrong?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Ken Bellows
  • 6,711
  • 13
  • 50
  • 78

3 Answers3

5

The "commandsFile.def" file probably uses the "A_COMMANDS_MACRO" macro somewhere internally.

Remember that "#include" essentially pastes the included file into the including one, so the #define is still in effect when "commandsFile.def" is processed.

Cameron Skinner
  • 51,692
  • 2
  • 65
  • 86
4

The commandsFile.def should contain many lines:

A_COMMANDS_MACRO(A_COMMAND, 10, na, na)
A_COMMANDS_MACRO(OTHER_COMMAND, 23, na, na)

So that the code would create an enum with available commands and their codes.

It could be useful when this .def file is used by a program written in other language, so that instead of implementing text parsing, it uses C preprocessor to do this.

ruslik
  • 14,714
  • 1
  • 39
  • 40
4

What you see there is usually called X-MACRO. The technique consists in defining macros via #define, and then including a file that makes use of them with #include.

As a very simple example, you could have a header (say myheader.h) that declared 2 functions in the form of:

int foo(MYTYPE a, MYTYPE_PTR b);
void bar(MYTYPE a, MYTYPE_PTR b);

And then, in your code:

#define MYTYPE int
#define MYTYPE_PTR int*
#include "myheader.h"
#undef MYTYPE
#undef MYTYPE_PTR

The #undefs are sometimes in the included file as well.

For more information, take a look at this Wikipedia link.

salezica
  • 74,081
  • 25
  • 105
  • 166
  • This is awesome. Next question though: How is that enum referenced since it doesn't have a name? For that matter, what is the point in the enum? Why not just include the file straight out? – Ken Bellows Dec 18 '10 at 20:58
  • 1
    @KenB: it could be just a way to check that command names are unique and to "syntax check" the .def file. – ruslik Dec 19 '10 at 09:41