views:

93

answers:

3

Hi,

First off, if this question has already been asked or way too naive, I apologize. I searched for it and could not find it.

Are they (preprocessor definitions) compiled into a static/dynamic library? For example, the FBX SDK needs KFBX_DLLINFO. A library that makes use of FBX SDK must include that. Now the client application, as far as I can tell from my limited experimentation, does not need to declare the definition again.

Now I can't think of a more practical scenario, but what if the client application 'needs' the definition to excluded (for example _CRT_SECURE_NO_WARNINGS compiled with a library, but what if I need those warnings?

+12  A: 

In short: no.

In long: For the most part, you can think of preprocessor definitions as a textual substitution mechanism. They are processed before compilation occurs (pre-compilation), so they transform the source code just before the compiler translates it to machine code, intermediate files, or whatever its target is. By the time you have a binary lib/obj/dll/exe/so file, the preprocessor definitions are long gone.

If you include a header in your code that was packaged as part of the library (e.g. in order to reference methods, types, enums, etc. defined by the library), then you are including preprocessor definitions that the library defines in that header.

In your case, if you include an FBX header, you might also be pulling in the preprocessor definition of KFBX_DLLINFO. The FBX binary library you're linking against was almost certainly built with that same header, so you are building against the same definition. This is a common pattern with libraries written in C/C++: common, shared header files along with a static or dynamic lib to build against.

Chris Schmich
+1 for the accessible explanation instead of a Yes/No.
Matthieu M.
Thanks for the detailed answer, that hit the nail on the head!
Samaursa
+2  A: 

Preprocessor definitions only exist during the compilation. They don't exist anymore in the compiled binary, be it static or dynamic library, or executable.

Didier Trosset
+2  A: 

As Chris explains, #defines are a textual substitution mechanism. The expansion was traditionally performed as a pre-compilation step, with the main C++-language compiler not having (or wanting) access to the pre-substitution text. For this reason, #defines can do things that aren't possible with the language-based constraints of C++, such as concatenate values to form new identifiers. These days, compilers tend to embed the macro processing functionality, and may include some information about pre-processor symbols in the debugging symbol tables compiled into executables. It's not very desirable or practical to access this debug information for some client usage, as debug formats and content can change between compiler versions, aren't very portable, may not be terribly well debugged :-/, and accessing them may be slow and clumsy.

If I understand you correctly, you're wondering whether #defines from some lower-level library that your library is using will be automatically available to an "application" programmer using your library. No, they won't. You need to either provide your own definitions for those values that your library's API exposes to the application programmer (mapping to the lower-level library values internally if they differ), or ship the lower-level library header as well.

For an example of remapping:

Your library.h:

#ifndef INCLUDED_MY_LIBRARY_H
#define INCLUDED_MY_LIBRARY_H

enum Time_Out
{
    Sensible,
    None
};

void do_stuff(Time_Out time_out);

#endif

Your library.c:

#include "my_library.h"
#include "lower_level_library.h"

void do_stuff(Time_Out time_out)
{
    Lower_Level_Lib::do_stuff(time_out == Sensible ? Lower_Level_Lib::Short_Timeout,
                                                   : Lower_Level_Lib::No_Timeout);
    LOWER_LEVEL_LIB_MACRO("whatever");
}

As illustrated, usage of the Lower_Level_Lib hasn't been exposed in my_library.h, so the app programmer doesn't need to know about or include lower_level_library.h. If you find you need/want to put lower_level_library.h into my_library.h in order to use its types, constant, variables, or functions therein, then you will need to provide the app programmer with that library header too.

Tony
"You need to either provide your own definitions for those values that your library's API exposes to the application programmer (mapping to the lower-level library values internally if they differ), or ship the lower-level library header as well." - Exactly what I was confused about. Thank you both for the excellent explanations.
Samaursa