preprocessor: checking for clashing #define

Discussion in 'C Programming' started by iler.ml@gmail.com, May 9, 2006.

  1. Guest

    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 9, 2006
    #1
    1. Advertising

  2. Joe Smith Guest

    <> wrote in message
    news:...
    >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
    Joe Smith, May 9, 2006
    #2
    1. Advertising

  3. Eric Sosman Guest

    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.

    --
    Eric Sosman, May 9, 2006
    #3
  4. Guest

    > 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 9, 2006
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Cronus
    Replies:
    1
    Views:
    643
    Paul Mensonides
    Jul 15, 2004
  2. Replies:
    3
    Views:
    384
  3. Preprocessor define concatenation

    , Jan 7, 2005, in forum: C Programming
    Replies:
    3
    Views:
    557
    Keith Thompson
    Jan 8, 2005
  4. rossum

    Clashing Interface methods

    rossum, Aug 26, 2007, in forum: Java
    Replies:
    10
    Views:
    597
    Daniel Pitts
    Aug 28, 2007
  5. Tim in Phoenix
    Replies:
    1
    Views:
    104
    Thomas 'PointedEars' Lahn
    Nov 29, 2007
Loading...

Share This Page