il*****@gmail.com wrote On 05/09/06 13:36,:
I am writing code that uses two third-party libraries.
They both define same macro OP_ENCRYPT, and
luckily for me, they both define it to 0. (In one include,
it's '#define OP_ENCRYPT 0', in another include it's 0x0).
I cannot change contents of those two includes.
This generates comipler warning 'macro redefined'. It's easy
to suppress the warning with #ifdef. But I want to also
cross-check that those two macros have same value.
I am thinking about this:
#include <first-lib.h> // defines OP_ENCRYPT
#define FIRST_OP_ENCRYPT OP_ENCRYPT //(*1)
#undef OP_ENCRYPT
#include <second-lib.h> // defines OP_ENCRYPT again
#if OP_ENCRYPT != FIRST_OP_ENCRYPT // (*2)
#error definitions mismatch
#endif
The problem here is that he rhs of define (*1) is expanded at line
(*2) which is too late. As a result, this does not really check
two values. The condition will always be true even if one
.h defined OP_ENCRYPT to 0 and other .h defined OP_ENCRYPT to 1.
I cannot change contents of those two includes.
Is there better way to check equality of macros defined in
two different includes without changing the contents of includefiles ?
If you know the intended values, you can check the
two definitions separately:
#define OP_SHOULD_BE 0
#include <first-lib.h>
#if OP_ENCRYPT != OP_SHOULD_BE
#error "first-lib.h is broken"
#endif
#undef OP_ENCRYPT
#include <second-lib.h>
#if OP_ENCRYPT != OP_SHOULD_BE
#error "second-lib.h is broken"
#endif
If you know the values are both positive and not too
large, you can use a dirty trick:
#include <first-lib.h>
char fake_array[OP_ENCRYPT];
#undef OP_ENCRYPT
#include <second-lib.h>
/* If the following provokes an error about inconsistent
* array size or redeclared identifier or some such, the
* headers disagree about OP_ENCRYPT:
*/
char fake_array[OP_ENCRYPT];
This trick could be made to work for zero values by adding
1, or for small negative values by adding N. Unfortunately,
it also creates the useless fake_array[] ...
A run-time check is fairly easy to write:
#include <assert.h>
#include <first-lib.h>
static int first_value(void) {
return OP_ENCRYPT;
}
#undef OP_ENCRYPT
#include <second-lib.h>
...
int main(void) {
assert (first_value() == OP_ENCRYPT);
...
Most compilers will generate very little extra code for this;
some will even optimize the whole thing away (if the headers
agree).
The best approach, though, is to avoid using both libraries
in the same piece of code: You are begging for trouble. Try to
organize your code in such a way that some modules use library
A and some uaw library B, but no modules use both libraries.
Remember, the next version of library A might introduce a new
#define that completely bollixes library B ...
Separating the libraries may be easier than you think; even
in extreme cases it can often be handled through a "glue" layer
that "translates" between the two libraries' symbologies.
--
Er*********@sun.com