Reputation: 355
I am writing linear list ADT as my practice in DS class. I use one header file, one function source code and a driver as a whole project. I defined macro "ELEMENT_TYPE" and "MAXSIZE" in the header file. My design is that I can #undef and immediately #define those two macros in the driver program to change "ELEMENT_TYPE" to any type the driver need. If I put these code:
#undef ELEMENT_TYPE
#define ELEMENT_TYPE char
#undef MAXSIZE
#define MAXSIZE 50
into the header file after the #define, then in the driver program, the functions can be recognized properly(For example, insertion() 's second augment was "ELEMENT_TYPE", use those code above, IDE shows that insertion() receive a char augment in driver program.) However, if I put those codes into the driver below #include "foo.h", then IDE cannot recognize what augments the fuction should receive and use the initial definition of "ELEMENT_TYPE", in this case, int. Who know what was wrong in my program so that preprocessing directives don't work properly?
Here are the original codes: driver.c https://paste.ubuntu.com/p/6B76vmk6nN/
linear_list.c https://paste.ubuntu.com/p/SHq4W5zkGM/
linear_list.h https://paste.ubuntu.com/p/VY8vcgFD89/
PS:I am not native English speaker, so maybe there are some places I didn't express clearly. Point them out and I'll add more details if needed.
Upvotes: 1
Views: 2152
Reputation: 223814
Macros in source code are replaced with the macro definition in effect at that point where the macro is used in the source code. So function declarations using ELEMENT_TYPE
use the macro definition that most recently precedes the declaration. Changing the macro later will not change the function definition.
An alternative is to define ELEMENT_TYPE
in the header only if it is not already defined:
#if ! defined ELEMENT_TYPE
#define ELEMENT_TYPE char
#endif
Then a source file can do either of:
Do not define ELEMENT_TYPE
itself. When the header is included, the default type of char
will be used.
Define ELEMENT_TYPE
, then include the header. If desired, #undef ELEMENT_TYPE
afterward. The type the source file provides in ELEMENT_TYPE
will be used.
The driver and the program that uses it must use the same type. You cannot compile the driver using one type and the program using another. Compiling the program with a different type will not change the driver.
Upvotes: 0
Reputation: 113
What it sounds like is happening is you're trying to #define
these values in the driver in the hopes that they will stay defined in linear_list.c.
The problem is that these files are compiled separately and then linked. The #define
s placed in driver.c cannot change those found in linear_list.c.
In order to have the effect I think you would like, you will need to change these values in linear_list.h. This is the best way to do this because that header is included in both the source files, and will presumably be #include
d in any file that works with the functions defined in linear_list.c. Please bear in mind that in order to see a change in the behavior of your program you will need to recompile not only driver.c but linear_list.c after changes to linear_list.h have been made.
As a side note, you should generally #include
local headers like linear_list.h after you #include
global headers like stdio.h and stdlib.h. In linear_list.c either of those headers could overwrite the values you've used in linear_list.h, if those identifiers are used. They look like they could be common enough, that it's not implausible that some header may use them, so it may be worthwhile to use a more unique identifier in the future. Which leads me to my final point: using #undef
on these identifiers without checking if they're used somewhere else could lead to some problems, so you should generally check with #ifndef
.
Hope that helps. If I've misunderstood please correct me.
EDIT: Clarification, additional information, credit to the other answer for reminding me of some important practices.
Upvotes: 1