does not give SOMETHING a value but it causes SOMETHING to become defined. Later you can test if SOMETHING is defined with: #ifdef SOMETHING
or #if defined(SOMETHING)
By not giving SOMETHING a value and simply defining you provide a clue to expect SOMETHING to be used in this manner.
That response reminds me of the day I decided I wasn't cut out to be a Math Major. In my Linear Algebra class, my Professor said "There is something in the vector space. That something is nothingness."
Okay, so now, let me get this right.
When I go #define SOMETHING
Something is being defined, but we aren't too sure what that something is? And then later on, when I see
One of two things will happen as a result of the above code.
case 1.
Somewhere earlier we encountered a "#define JOB_CONTROL" line. If so we will get that signal line.
case 2.
We never encountered any "#define JOB_CONTROL" line. If so we get nothing.
So now we can control whether or not the program supports job control by the presense or absence of the "#define JOB_CONTROL" line. Choosing a name like SOMETHING would have been bad. But JOB_CONTROL is a good choice for this macro.
i is defined as an integer here. It's value is unspecified, which is a bad idea for variables by the way.
#define I
I is defined but the value is unspecified. The difference here is that #define merely defines something that is a unique series of characters. It has no real meaning.
int i; has more meaning for humans, because integers are a class.
When we are up to our knees either in alligators or learning a new language, we don't usually look at all of the details -- for the latter, we're usually just interested in getting results. I'll risk bludgeoning the topic to death with my view.
I see the macro and inclusion facility as a piece separate from the compiler itself. One may place standard c code in a file name.i and use gcc to compile it without running the separate preprocessor, cpp. One, could, in fact, use a separate macro facility like m4 to do the work.
The function of cpp is quite limited, but like most symbol manipulators, it will keep track of symbols and their properties. You can test for the property of existence of a symbol in its memory -- that's really what ifdef and ifndef do. One could argue that the name of the query should be if_in_symbol_table, but the existence is often less important than the value, which is simply another property.