473,480 Members | 1,957 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

preprocessor: checking for clashing #define

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
3 3061

<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


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
> 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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
1675
by: Jakob Simon-Gaarde | last post by:
Some project includes files from different libraries lib1,lib2 and lib3 all having each there own version header file. I need to be able to pick up these values in a single define value...
205
10440
by: Jeremy Siek | last post by:
CALL FOR PAPERS/PARTICIPATION C++, Boost, and the Future of C++ Libraries Workshop at OOPSLA October 24-28, 2004 Vancouver, British Columbia, Canada http://tinyurl.com/4n5pf Submissions
16
4461
by: Trying_Harder | last post by:
Is it possible to redefine a macro with global scope after undefining it in a function? If yes, could someone explain how? /If/ my question above isn't very clear you can refer to the...
18
2992
by: /* frank */ | last post by:
My teacher said that array in C is managed by preprocessor. Preprocesser replace all array occurences (i.e. int a ) with something that I don't understand/remember well. What's exactly happens...
9
6556
by: ccwork | last post by:
Hi all, We can define some magic number with #define: #define OPERATION_1 0x00000001 #define OPERATION_2 0x00000002 #define OPERATION_3 0x00000003 .... We can also do that with enum: enum...
2
6614
by: Paolo | last post by:
I imported a VC++6.0 project into VC++7.1. The conversion operation makes a mess with Preprocessor Definitions, adding a "$(NoInherit)" for each file. For example: I had a DLL project in VC++6.0...
1
378
by: Frank-René Schäfer | last post by:
Is there a way to write code like #include IMPLEMENT_THIS(my_class, my_member_type) for what looks currently like #define __C my_class #define __MT my_member_type #include...
25
7925
by: Gernot Frisch | last post by:
Hi, I want to build a encryption macro set, that can crypt: char secret = CRYPT("KungFu"); to anything unreadable, and then have a function: char* DECRYPT(char* str) { ...
36
2079
by: anon.asdf | last post by:
Hello! Can the proprocessor make conditional decisions. Here's an example of the functionality (not standard C!) #define PUT_BYTE(const_index, val) \ #preprocessor_if (const_index ==...
0
7044
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7084
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
6739
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
6929
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
4779
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4481
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
2995
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
2984
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1300
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.