Hacker News new | past | comments | ask | show | jobs | submit login
“:-!!” what is it in c code? (stackoverflow.com)
141 points by Arkid on March 11, 2012 | hide | past | favorite | 13 comments



The actual line is #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))

The guy asking the question just misread the code, the colon is part of the struct definition and the key part is -!! which coerces an integer to 0 if the value is zero, or -1 if the value is anything other than 0.


You do have to know about the bitfield struct syntax which, as C features go, seems to be one of the more obscure.


They're all key parts. Note that the sizeof is there to avoid polluting the namespace. Otherwise you'd have to declare something that used that anonymous struct. And likewise the parentheses so it can be used in all contexts in an expression. Every byte of that macro is needed. It's pretty elegant, honestly.


The sizeof is there so it returns a value so it can be used as an expression. See the comment above the code (reproduced in the original question).


These machinations were always necessary to get compile-time asserts. Luckily C++11 and C11 are both providing static_assert so there will be real compiler support instead of having to trick it into dumping an error.

edit: Another common one is using __LINE__ or __COUNTER__ in an array symbol name and having the test value result in an array size of -1.


Reminds me of the 'goes to' operator:

  for (int i = 42; i --> 0;) { foo(); }


That's really cute, but it's also buggy. The loop will start at i == 41.


You are right about it starting on 41, but chances are that that is its intended behavior, with a bit of context that is more clear:

  #define ARRAYSIZE 42

  int array[ARRAYSIZE];

  void f() {
     for (i=ARRAYSIZE; i --> 0;) {
       printf("%d\n", array[i]);
     }
  }
If it were to start at 42 you'd be referencing the array outside of its bounds.


In C you're used to less-than-one loops though. for(i = 0; i < 5; i++) terminates on 4. And it's what you want if you're going through an array.


The observant (yeah, newbies aren't so much, typically) will note that it really shouldn't be called "goes to" because it doesn't work the other way:

   for(int i=0; i --> 42;) { bar(); }


This has been posted before during the past 2 months.


For those wondering http://news.ycombinator.com/item?id=3577205 (29 days ago)

Didn't get much attention back then. (+8 at time of writing)


I know I didn't notice it back then but did notice it now (and it's a neat trick which I didn't encounter before), so for me reposting worked.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: