FS.L
FS.L

Reputation: 355

#undef not work as expected in my C program

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

Answers (2)

Eric Postpischil
Eric Postpischil

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

Newt Hoenikker
Newt Hoenikker

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 #defines 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 #included 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

Related Questions