Alex
Alex

Reputation: 434

What is the Action of #define in this Instance?

As part of my homework, I've been given this code to help with the task they've given us... to create a basic shell that supports piping, background processes, and a number of builtin commands, etc. I've read through the code they've given us for parsing...

I'm familiar with the #define keyword in C, however, I've not seen it used like in the below code: namely, what is c for? I'm guessing it has been assigned to mean a character but I'm not sure:

#define PIPE  ('|')
#define BG    ('&')
#define RIN   ('<')
#define RUT   ('>')

#define ispipe(c) ((c) == PIPE)
#define isbg(c)   ((c) == BG)
#define isrin(c)  ((c) == RIN)
#define isrut(c)  ((c) == RUT)
#define isspec(c) (ispipe(c) || isbg(c) || isrin(c) || isrut(c))

Any help or advice much appreciated.

Upvotes: 0

Views: 285

Answers (2)

Amadan
Amadan

Reputation: 198294

#define is not a function, it is a preprocessor directive.

c could be anything. If you write ispipe(42), then the preprocessor will change it into ((42) == PIPE). If you write ispipe(while(1);), then the preprocessor will change it into ((while(1);) == PIPE), which will dumbfound the compiler when it reads it.

The preprocessor is blind, and does not know much about C syntax, and nothing of its semantics; the only way to understand what c is supposed to be is either to reverse-engineer the intended usage, or to ask whoever wrote the code without comments to tell you what they meant.

After the edit, it is rather reasonable to expect that c should be a char, in order to be meaningfully compared to '|' and similar. But even passing 0xDEADBEEF should compile correctly (returning FALSE).

Upvotes: 3

Adrian Mole
Adrian Mole

Reputation: 51815

The last five #define statements you give define macros, each taking an argument, which is here always called c. Your first four #define statements are also, technically, macros, but they don't need an argument - they are simply substituted for their 'values' when encountered; frequently, programmers refer to macros with no argument as tokens, with the PIPE token here having a token value of ('|').

Later on in the file (possibly) there will be cases where one or more of these macros is called, and that call will have a value for the actual argument, like this, for example:

if (ispipe(test_arg)) ++npipes;

This macro "call" will be replaced (by the pre-processor) with the following expansion:

if (((test) == ('|')) ++npipes;

And, similarly, for the other #define XXX(c) macros.

Note: It is quite common to add (lots of) parentheses in macro definitions, just to be sure that the code does what you 'think' it will after the pre-processor has done its stuff.

Feel free to ask for further explanation and/or clarification.

Upvotes: 4

Related Questions