By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,154 Members | 1,037 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,154 IT Pros & Developers. It's quick & easy.

preprocessor: checking for clashing #define

P: n/a
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 ?

Thanks
Yakov Lerner

May 10 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a

<il*****@gmail.com> wrote in message
news:11*********************@g10g2000cwb.googlegro ups.com...
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 ?


Have you drawn a picture of the logic? Joe
May 10 '06 #2

P: n/a


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

May 10 '06 #3

P: n/a
> 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


Nice. This is what I'm going to use.

Thanks
Yakov

May 10 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.