Thread: conditional definition?

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    159

    conditional definition?

    Hi,
    I got the source code of a library. Its header file has following lines:
    Code:
    typedef int	coord;  
     #define SIZE 8; 
     #define MYPOW(v)  fabs(v)
    I like to modify these definitions in a new function added to the header and recompile the library, so that I can call this function from my program to make "coord", "SIZE" and "MYPOW" defined in another way depending on some condition, something like
    Code:
    void definition(int i){
    if (i > 0) { 
    typedef int coord; 
    #define SIZE 8
    #define MYPOW(v)  ((v)*(v)) }
    else {
    typedef double	coord; 
    #define SIZE 16
    #define MYPOW(v)  fabs(v) }
    }
    I know this is not correct. Does C/C++ have something like conditional definition not using directives? Even if they do, how to make the symbols "coord", "SIZE" and "MYPOW" global, instead of being only effective within the function and not exiting outside?

    For example, "coord" in the following code will not exist outside the function definition() and will not be available to use.
    Code:
    void definition(int i){
        if (i>0) {typedef int coord ;}
        else {typedef float coord ;}
    }
    For the function-like macro MYPOW, I can think of a way as
    Code:
    double (*MYPOW) (double);
    double square(double v) {return ((v)*(v));}
    void definition(int i){
        if (i > 0) {MYPOW = &fabs;}
        else {MYPOW = □}
    }
    Really appreciate your help!
    Thanks and regards!
    Last edited by lehe; 06-20-2009 at 12:37 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    I suppose the C++ way would be to create a coord template, and create two instances of that (one int, one double)

    A C way might be to create a union, like
    Code:
    typedef union {
      int iCoord;
      double dCoord;
    } coord;
    
    coord square(int i, coord c) {
      coord result;
      if ( i > 0 ) {
        result.dCoord = fabs(c.dCoord);
      } else {
        result.iCoord = c.iCoord * c.iCoord;
      }
      return result;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    You can do some template trickery.

    Code:
    template<int x> struct X {};
    
    template<> struct X<1>
    {
        typedef int coord;
        static coord pow(coord p) {return p*p;};
    };
    
    template<> struct X<2>
    {
        typedef double coord;
        static coord pow(coord p) {return fabs(p);};
    };
    
    int main()
    {
        X<1>::coord p = X<1>::pow(2);    //  use the int version
        X<2>::coord p = X<2>::pow(2.0);    //  use the double version
    
        X<3>::coord p = X<3>::pow(2);    //  compiler will complain bitterly, as X<3> not instantiated
    }
    Yes, I realise there is no obvious "if" statement. But instantiated a template using a value is logically the same thing .... the only difference is that the compiler evaluates the condition, not your program.

  4. #4
    Registered User
    Join Date
    Jan 2009
    Posts
    159
    Thanks!
    But using either template or union will mean that modification is inevitable wherever the original symbols appear in the implementation of the library. Can I just leave the rest of code intact?

    Now the function-like macro MYPOW can be replaced by global functional pointer that can be assigned in the function, and the numerical macro SIZE can be replaced by global integer that can also be assigned in the function. How can I do similarly to the type alias "coord"?

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    You miss the point. If you want to do selection of types within a library based on some conditions, your library code needs to be modified to handle new cases. There is no way around that, as C++ is a statically typed language.

    Using a global function pointer to address this is, to put it gently, an ugly hack.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Errors including <windows.h>
    By jw232 in forum Windows Programming
    Replies: 4
    Last Post: 07-29-2008, 01:29 PM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM
  5. gcc problem
    By bjdea1 in forum Linux Programming
    Replies: 13
    Last Post: 04-29-2002, 06:51 PM