Thread: Static assert of define

  1. #1
    Registered User MartinR's Avatar
    Join Date
    Dec 2013
    Posts
    200

    Lightbulb Static assert of define

    Hi,

    I was wondering how can we extend simple macro like
    Code:
    #define TOGGLE_BIT(x,y) \
    	(x) ^= (1 << (y))
    with static assertion - i.e verify if y is within 32 bits as shifting beyound is undefined. However this simple task seems to impossible in C. First, naive attempt would be sth like

    Code:
    #define TOGGLE_BIT(x,y) \
    #if (y < 32)
    	(x) ^= (1 << (y))
    #else 
    #error Requested bit out of integer bouds
    #endif
    But this won't work because preprocessor does only one pass, IOW it won't allow for other directives in #define

    Other apprach would be:
    Code:
    #define TOGGLE_BIT(x,y) \
    static_assert((y > 31),"Out of integer bound")
    	(x) ^= (1 << (y))
    but then the macro is preatty much useless - you can't use t in the assignment or inside if() condition.

    So how can we cope with that?

  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
    How do you expect the compile time pre-processor to deal with run-time values?

    If you want to do this, make it an inline function rather than a macro.
    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 MartinR's Avatar
    Join Date
    Dec 2013
    Posts
    200
    This is not about real time values but constants like IS_BIT_SET(255,8)

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    What examples of use in context do you have?
    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.

  5. #5
    Registered User MartinR's Avatar
    Join Date
    Dec 2013
    Posts
    200
    The usage is as I mention - the programmer will always use the macro with constants known at compile time. Now the question is if we can verify them inside that #define ?

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The inline function idea might be worth a try: while inlining isn't guaranteed, if it does happen (and the code does look like a good candidate for inlining), it may be possible that the compiler will do constant propagation and then eliminate the branch that it can determine will never be executed.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Quote Originally Posted by MartinR View Post
    The usage is as I mention - the programmer will always use the macro with constants known at compile time. Now the question is if we can verify them inside that #define ?
    Usage - like
    Code:
    if ( IS_BIT_SET(255,8) ) {
      // do something
    }
    Really limits your options as to what is syntactically valid inside your macro.

    Things which can exist as statements have more scope.
    Code:
    #define STATIC_ASSERT(COND,MSG) typedef char static_assertion_##MSG[(COND)?1:-1]
    
    #define TOGGLE_BIT(x,y) do {          \
      STATIC_ASSERT((y<32),out_of_bound); \
      (x) ^= (1 << (y));                  \
    } while ( 0 )
    
    int main ( ) {
      int x = 0;
      TOGGLE_BIT(x,44);
    }
    
    
    $ gcc foo.c
    foo.c: In function ‘main’:
    foo.c:1:46: error: size of array ‘static_assertion_out_of_bound’ is negative
     #define STATIC_ASSERT(COND,MSG) typedef char static_assertion_##MSG[(COND)?1:-1]
                                                  ^
    foo.c:4:3: note: in expansion of macro ‘STATIC_ASSERT’
       STATIC_ASSERT((y<32),out_of_bound); \
       ^
    foo.c:10:3: note: in expansion of macro ‘TOGGLE_BIT’
       TOGGLE_BIT(x,44);
       ^
    foo.c:5:13: warning: left shift count >= width of type [-Wshift-count-overflow]
       (x) ^= (1 << (y));                  \
                 ^
    foo.c:10:3: note: in expansion of macro ‘TOGGLE_BIT’
       TOGGLE_BIT(x,44);
       ^
    But note that gcc already knows how to warn you about these things if the shift is known at compile time.
    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.

  8. #8
    Registered User MartinR's Avatar
    Join Date
    Dec 2013
    Posts
    200
    @Salem, thanks for extended answer!

    The trick with
    Code:
    typedef char static_assertion_##MSG[(COND)?1:-1]
    is nice and I saw it before in some legacy code. But shouldn't compiler complain about redefinition of a typedef?

    But note that gcc already knows how to warn you about these things if the shift is known at compile time.
    Yes I know, I was just theoretically considering own assertion method.

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > But shouldn't compiler complain about redefinition of a typedef?
    Well each is scoped by the braces of the do-while, so no.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how to define a static member in a template class
    By wanziforever in forum C++ Programming
    Replies: 3
    Last Post: 10-08-2009, 04:44 AM
  2. Can you define a static member function in a class?
    By meili100 in forum C++ Programming
    Replies: 2
    Last Post: 06-22-2008, 09:23 PM
  3. static const VS #define
    By meili100 in forum C++ Programming
    Replies: 5
    Last Post: 12-04-2007, 12:18 PM
  4. Assert
    By Shamino in forum C++ Programming
    Replies: 8
    Last Post: 01-24-2006, 11:02 AM
  5. How to use assert?
    By jjbuchan in forum C Programming
    Replies: 2
    Last Post: 11-11-2005, 01:40 PM

Tags for this Thread