Results 1 to 6 of 6

Thread: C++ compile-time constant detection

  1. #1
    Administrator Shelwien's Avatar
    Join Date
    May 2008
    Location
    Kharkov, Ukraine
    Posts
    3,134
    Thanks
    179
    Thanked 921 Times in 469 Posts

    C++ compile-time constant detection

    I wanted a macro for optimization of counter tables for
    masked contexts, like
    Code:
    Counter order1[(mask1<1)?1:CNUM][CNUM];
    But the problem here is that "mask1" might be variable
    in the case when parameter optimizer is used, so its
    necessary to avoid the compiler error somehow.
    Well, separating const from non-const is relatively trivial,
    but the problem is that a const value is not necessary constant %).
    But seems like I finally managed to make a working sample.

    However, its not exactly perfect, as the trick with 0 cast to void*
    doesn't work in gcc for some reason. Fortunately, gcc has an extension
    exactly for this purpose, but its not perfect either, as it produces
    different results depending on optimization level (X3 is considered non-const
    with -O0).

    So suggestions would be appreciated.

    Code:
    #include <stdio.h>
    
    struct chkconst {
    
      struct Temp { Temp( int x ) {} };
     
      static char chk1( const int& ) { return 0; }
      static int  chk1( int&  ) { return 0; }
    
      static char chk2( void* ) { return 0; }
      static int  chk2( Temp  ) { return 0; }
    };
    
    int X1 = 1;
    const int X2 = printf( "" );
    const int X3 = 2;
    enum{ X4=3 };
    #define X5 4
    
    #define TEST1(X) (sizeof(chkconst::chk1(X))<sizeof(int))
    
    #ifdef __GNUC__
    #define TEST2(X) __builtin_constant_p(X)
    #else
    #define TEST2(X) (sizeof(chkconst::chk2((X)*0))<sizeof(int))
    #endif
    
    int main( void ) {
      printf( "1. %i %i\n", TEST1(X1), TEST2(X1) );
      printf( "2. %i %i\n", TEST1(X2), TEST2(X2) );
      printf( "3. %i %i\n", TEST1(X3), TEST2(X3) );
      printf( "4. %i %i\n", TEST1(X4), TEST2(X4) );
      printf( "5. %i %i\n", TEST1(X5), TEST2(X5) );
    }

  2. #2
    Administrator Shelwien's Avatar
    Join Date
    May 2008
    Location
    Kharkov, Ukraine
    Posts
    3,134
    Thanks
    179
    Thanked 921 Times in 469 Posts
    1. Appears that I was wrong, and gcc _does_ cast 0 to void*.
    Its just that its too smart and thinks that variable*0 is constant,
    so I had to change the condition to something less certain.

    2. As expected, no compilers allowed to just write
    int a[ is_const(X1) ? X1 : 1 ];
    but this problem was easier.

    3. Now, this seems to work as expected in gcc 3.4, gcc 4.4,
    VS 2005, IntelC 9,10,11

    Code:
    #include <stdio.h>
    
    struct chkconst {
      struct Temp { Temp( int x ) {} };
      static char chk2( void* ) { return 0; }
      static int  chk2( Temp  ) { return 0; }
    };
    
    #define is_const_0(X) (sizeof(chkconst::chk2(X))<sizeof(int))
    #define is_const_0i(X) (sizeof(chkconst::chk2(X))>sizeof(char))
    #define is_const(X) is_const_0( (X)^((X)&0x7FFFFFFF) )
    
    #define const_bit( X1, bit ) (is_const_0i((X1)&(1<<bit))<<bit)
    #define const_nibl( X1, bit ) const_bit(X1,bit) | const_bit(X1,(bit+1)) | \
    const_bit(X1,(bit+2)) | const_bit(X1,(bit+3)) 
    #define const_byte( X1, bit ) const_nibl(X1,bit) | const_nibl(X1,(bit+4))
    #define const_word( X1, bit ) const_byte(X1,bit) | const_byte(X1,(bit+8))
    #define const_uint( X1 ) const_word(X1,0) | const_word(X1,16)
    
    #define const_switch_word( X1, X2 ) (is_const(X1) ? const_word(X1,0) : X2)
    #define const_switch_uint( X1, X2 ) (is_const(X1) ? const_uint(X1) : X2)
    
    const int X1 = 222;
    int X2 = 333;
    
    char Y1[ const_switch_word(X1,256) ];
    char Y2[ const_switch_word(X2,256) ];
    
    int main( void ) {
    
      printf( "%i %i %i\n", X1, is_const(X1), sizeof(Y1) );
      printf( "%i %i %i\n", X2, is_const(X2), sizeof(Y2) );
    
    }
    Last edited by Shelwien; 24th June 2009 at 11:44.

  3. #3
    Administrator Shelwien's Avatar
    Join Date
    May 2008
    Location
    Kharkov, Ukraine
    Posts
    3,134
    Thanks
    179
    Thanked 921 Times in 469 Posts

  4. #4
    Expert
    Matt Mahoney's Avatar
    Join Date
    May 2008
    Location
    Melbourne, Florida, USA
    Posts
    3,255
    Thanks
    306
    Thanked 778 Times in 485 Posts
    Result of first program:

    g++ 4.5.0, no optimization
    1. 0 0
    2. 1 0
    3. 1 0
    4. 1 1
    5. 1 1

    g++ -O (also -O2, -O3)
    1. 0 0
    2. 1 0
    3. 1 1
    4. 1 1
    5. 1 1

    Borland 5.5.1 (not affected by -O)
    1. 0 0
    2. 1 0
    3. 1 0
    4. 1 0
    5. 1 0

    Mars 8.42n
    printf( "4. %i %i\n", TEST1(X4), TEST2(X4) );
    ^
    a.cpp(32) : Error: need explicit cast for function parameter 1 to get
    from: int enum __unnamed
    to : void *
    printf( "5. %i %i\n", TEST1(X5), TEST2(X5) );
    ^
    a.cpp(33) : Error: reference must refer to same type or be const
    Had: int
    and: int &
    --- errorlevel 1

    Results for second program:

    g++ (not affected by -O)
    222 1 222
    333 0 256

    Borland (not affected by -O)
    222 0 256
    333 0 256

    Mars
    222 1 222
    333 0 256

  5. #5
    Administrator Shelwien's Avatar
    Join Date
    May 2008
    Location
    Kharkov, Ukraine
    Posts
    3,134
    Thanks
    179
    Thanked 921 Times in 469 Posts
    Thanks for testing, but
    1. "first program" is obsolete
    2. is_const = 0 is more general case (variable value) so its okay, that's the same as disabled optimization.
    I'd appreciate if you could help to simplify the thing, though, especially the bitwise reconstruction macros

  6. #6
    Administrator Shelwien's Avatar
    Join Date
    May 2008
    Location
    Kharkov, Ukraine
    Posts
    3,134
    Thanks
    179
    Thanked 921 Times in 469 Posts
    Found an interesting site: http://codepad.org/ngP7Kt1V

Similar Threads

  1. ECM linux compile
    By schnaader in forum Download Area
    Replies: 0
    Last Post: 27th November 2009, 17:46
  2. pbzip2 1.05 optimized compile
    By M4ST3R in forum Download Area
    Replies: 0
    Last Post: 2nd October 2009, 16:21
  3. Text Detection
    By Simon Berger in forum Data Compression
    Replies: 15
    Last Post: 30th May 2009, 09:58
  4. Better compression performance across time?
    By Trixter in forum Data Compression
    Replies: 16
    Last Post: 16th June 2008, 23:35
  5. TC 5.0dev11 is here - Time to gain compression!
    By encode in forum Forum Archive
    Replies: 38
    Last Post: 1st August 2006, 09:24

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •