#include<iostream>
usingnamespace std;
#define z 10
#define z 15 // Same macro as above.
int main()
{
cout<<z; // why output is 15 instead of some error
}
I guess my question is, does the preprocessor read the entire file and then apply its changes or does it apply them as it goes along?
For example, did the second define override the first or was the first one applied and then the second? In the latter case, would it have changed the second one to #define 10 15 ?
Also, does the preprocessor ever give errors/warnings? I don't recall ever seeing one; or at least not recognizing that the message came from the preprocessor.
The preprocessor doesn't really have any steps that can have an error. Then only errors I've every gotten relating to preprocessor commands are "unable to open include file."
When you #define z again, it is consider from that point on to be 15. Just like changing a variable's value, all references to it after that point are now 15. If there had been code between the two #defines, then that code would have used z as 10.
If you want a constant, however, you naturally should just make a variable with the const qualifier rather than using #define.
Hmmm. Good question. I do wonder whether the preprocessor processes files before compilation or during.
Although this discussion only concerned preprocessing, not compilation, I do vaguely recall reading somewhere that preprocessing and compilation may be done in a single pass. That detail may be left up to the compiler implementation. If that is the case, during might be a possibility.
Well, yes, I suppose how the preprocessor is implemented is undefined, but I don't see that it would be practical to preprocess while compiling. I don't see that it could be done: how are you supposed to replace macros that haven't been defined yet? You can #define a macro anywhere you want to. What happens to a compiler that preprocesses as it goes with this code:
1 2 3 4 5 6 7
int main()
{
error("Uh-oh: %s", strerror(errno));
return 0;
}
#define error(STRING, ...) do {fprintf(stderr, STRING, __VA_ARGS__); } while (0);
With a preprocessor, error() is correctly replaced. With a, uh, duringprocessor, you get a compile error.
Edit: yes it would be stupid to do that, but my point is still valid.