Upgrade to Pro — share decks privately, control downloads, hide ads and more …

C sytax gems

C sytax gems

Some C code snippets you may will see but should never use

fooker

May 20, 2012
Tweet

More Decks by fooker

Other Decks in Programming

Transcript

  1. C syntax gems Code you should see - but may

    not use Dustin Frisch <[email protected]> c4fd.org / mag.lab.sh April 14, 2012
  2. Disclamer THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF

    ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  3. Disclamer The snippets are tested using the following setup: gcc

    (Gentoo 4.5.3-r2 p1.1, pie-0.4.7) 4.5.3 Intel(R) Core(TM)2 Duo CPU (T5870) Linux 3.0.6-gentoo #6 SMP PREEMPT Compile using the following command: gcc -c -g snippet_*.c Warnings should be ignored gracefully
  4. An easy one - check if even /∗ ∗∗ Test

    i f i n t e g e r i s even ( the d e f a u l t way ) ∗/ i n t even ( i n t i ) { r e t u r n ( i % 2) == 0 ; } /∗ ∗∗ Test i f i n t e g e r i s even ( the b i t o p e r a t i o n way ) ∗/ i n t even ( i n t i ) { r e t u r n ( i & 1 ) ; }
  5. Start thinking - swapping variables The common way to swap

    the content of two variables /∗ ∗∗ Swap content of two v a r i a b l e s ( the lame way ) ∗/ void swap ( i n t a , i n t b ) { i n t t ; t = a ; a = b ; b = t ; }
  6. Start thinking - swapping variables Using register gives some performance

    boost /∗ ∗∗ Swap content of two v a r i a b l e s u si n g r e g i s t e r s ∗/ void swap ( r e g i s t e r i n t a , r e g i s t e r i n t b ) { r e g i s t e r i n t t ; t = a ; a = b ; b = t ; }
  7. Start thinking - swapping variables The XOR trick swaps the

    content without any temporary variable /∗ ∗∗ Swap content of two v a r i a b l e s ( the XOR way ) ∗/ void swap ( r e g i s t e r i n t a , r e g i s t e r i n t b ) { a ^= b ; b ^= a ; a ^= b ; }
  8. Start thinking - swapping variables We can use command chaining

    to avoid storing intermediate results /∗ ∗∗ Swap content of two v a r i a b l e s ( the chained XOR way ) ∗/ void swap ( r e g i s t e r i n t a , r e g i s t e r i n t b ) { a ^= b ^= a ^= b ; }
  9. Start thinking - swapping variables The hackorz way uses a

    single assembler instruction /∗ ∗∗ Swap content of two v a r i a b l e s ( the one−i n s t r u c t i o n −way ) ∗/ void swap ( r e g i s t e r i n t a , r e g i s t e r i n t b ) { __asm__ __volatile__ ( "XCHG %0, %1" : "=r " ( a ) , "=r " ( b ) : "0" ( a ) , "1" ( b ) ) ; }
  10. Nice syntax stuff The included URL is interpreted as a

    lable called “https” followed by a C++ style comment /∗ ∗∗ Putting URLs i n the code ; −) ∗/ void url ( ) { https : //mag . l a b . sh / w i k i /Geekend_Phase_3 r e t u r n ; }
  11. Nice syntax stuff Everybody loves the conditional operator /∗ ∗∗

    Leaf second parameter of c o n d i t i o n a l s empty ∗/ void cond () { i n t foo = 42; i n t bar = 23; i n t a = foo ? foo : bar ; i n t b = foo ? : bar ; }
  12. Nice syntax stuff Does anyone need pointers to labels /∗

    ∗∗ You can p o i n t to l a b e l s and goto us i ng p o i n t e r ∗/ i n t labels () { void ∗ ptr [ ] = { &&foo , &&bar }; goto ∗ptr [ 1 ] ; foo : r e t u r n 23; bar : r e t u r n 42; }
  13. Nice syntax stuff The switch statement allows ranges /∗ ∗∗

    You can use ranges i n switch case ∗/ void cases ( i n t foo ) { switch ( foo ) { case 0 . . . 23: break ; case 24 . . . 42: break ; d e f a u l t : break ; } }
  14. Nice syntax stuff If a nested structure or union has

    no name, the fields are reachabe directly /∗ ∗∗ Unions and s t r u c t s can be anonynmous . ∗/ void unnamed ( ) { s t r u c t { union { i n t i ; f l o a t f ; }; s t r u c t { i n t foo ; i n t bar ; }; } x ; x . foo = 23; x . bar = 42; x . i = x . foo ; }
  15. Nice syntax stuff The switch construct can be intermixed with

    almost all other instructions - leading to the famous Duff’s device #i n c l u d e <s t d i o . h> /∗ ∗∗ I n t e r m i x switch − The famous Duff ' s Device ∗/ void duff ( i n t count ) { i n t n = ( count + 7) / 8; switch ( count % 8) { do { case 0 : printf ( "42\n" ) ; case 7 : printf ( "42\n" ) ; case 6 : printf ( "42\n" ) ; case 5 : printf ( "42\n" ) ; case 4 : printf ( "42\n" ) ; case 3 : printf ( "42\n" ) ; case 2 : printf ( "42\n" ) ; case 1 : printf ( "42\n" ) ; } w h i l e (−−n > 0 ) ; } }
  16. Nice syntax stuff Array dereferencing is pointer arithmetic - a

    simple addition, indeed #i n c l u d e <s t d i o . h> /∗ ∗∗ D e r e f e r e n c i n g means a r i t h m e t i c ( a d d i t i o n ) ∗/ void deref ( i n t a , i n t b ) { i n t xxx [ ] = {1 , 2 , 3 , 4 , 5 , 6}; i n t i ; f o r ( i = 0 ; i < 5; i++) { i n t foo = xxx [ i ] ; i n t bar = ∗( xxx + i ) ; i n t baz = i [ xxx ] ; printf ( "%d\n" , foo ) ; printf ( "%d\n" , bar ) ; printf ( "%d\n" , baz ) ; } }
  17. Nice syntax stuff Converting integer to hex is easy -

    usefull for dumping data #i n c l u d e <s t d i o . h> /∗ ∗∗ A neat i n t 2 hex f u n c t i o n − based on the d e r e f t r i c k ∗/ void int2hex ( i n t i ) { char hex = " 0123456789 abcdef " [ i ] ; printf ( "%c\n" , hex ) ; }
  18. Nice syntax stuff Compound statements can be used in for

    loops - but they can be realy ugly #i n c l u d e <s t d i o . h> /∗ ∗∗ Compound e x p r e s s i o n ∗/ void compound () { i n t foo = (23 , 4 2 ) ; // foo == 42 i n t bar = ( printf ( " xxx \n" ) , 1337); // bar == 1337 }
  19. Nice syntax stuff Compound literals are realy usefull for inlining

    constant data as pointer /∗ ∗∗ Compound l i t e r a l s are r e a l l y u s e f u l l ∗/ void foo ( i n t ∗ bar ) ; void compound () { foo ( ( i n t [ ] ) { 42 , 23 , 0 } ) ; }
  20. Nice syntax stuff C allows array with length of zero

    - as you can access arrays out of bound, the can be usefull for mappings #i n c l u d e <s t d l i b . h> /∗ ∗∗ Zero l e n g h t a r r a y s can be u s e f u l l f o r s t r u c t u r e mapping ∗/ void zero () { s t r u c t foo { i n t len ; char data [ 0 ] ; /∗ C99 a l l o w s : char data [ ] ; ∗/ }; s t r u c t foo∗ bar = malloc ( s i z e o f ( s t r u c t foo ) + 4 2 ) ; bar−>len = 42; bar−>data ; /∗ Space f o r up to 42 chars ∗/ }
  21. Nice syntax stuff Array length can by dynamic in some

    way - leading to the only usefull usage of “parameter forward declaration” I have ever found /∗ ∗∗ Dynamic a r r a y l e n g t h & parameter forward d e c l a r a t i o n ∗/ i n t foo ( i n t len , char s [ len ] ) ; i n t bar ( i n t len ; char s [ len ] , i n t len ) ; void params ( ) { foo (10 , " abcdefwxyz " ) ; bar ( " zyxwvutsrq " , 1 0 ) ; }
  22. Nice syntax stuff Designators are usefull to initialize arrays (including

    ranges support) /∗ ∗∗ D e s i g n a t o r s are a l i t t l e b i t c r e a z y − but can be u s e f u l l ∗/ void designators ( ) { i n t i [ 1 3 3 7 ] = { [ 2 3 ] = 1337 , [ 4 2 ] = 1337 }; i n t j [ 1 3 3 7 ] = { [23 . . . 42] = 1337 }; s t r u c t { i n t foo ; i n t bar ; } k [ 1 3 3 7 ] = { [ 2 3 ] . foo = 23 , [23 . . . 4 2 ] . bar = 42 }; }
  23. Nice syntax stuff Operators can be really ugly - be

    carefull /∗ ∗∗ Some o p e r a t o r b r a i n f u c k − who can guess the v a l u e ∗/ void operators () { i n t a = 23; i n t b = 42; i n t c = 0 ; c = a++ + ++a − −b++ ∗ −−c + a++; }
  24. Nice syntax stuff Functions can be inlined - allowing some

    nifty helper functions /∗ ∗∗ C a l l o w s nested f u n c t i o n s ∗/ void nested ( ) { i n t foo ( i n t bar ) { r e t u r n bar + 23; } foo ( 4 2 ) ; } Indeed, access to variables in the outer scope is possible
  25. Nice syntax stuff Using compound statements, anonymous inline functions are

    possible /∗ ∗∗ You can b u i l d some lambda s t y l e anonymous f u n c t i o n s ∗/ void anonymous () { i n t (∗ fp )( int , i n t ) = ({ i n t f ( i n t foo , i n t bar ) { r e t u r n foo + bar ; } f ; } ) ; fp (42 , 2 3 ) ; }
  26. Nice syntax stuff Usefull to explain the relations between C

    and assembler - but I know a guy using this in productive software /∗ ∗∗ What happens i f you i g n o r e the return −missing −warnings ∗/ i n t foo ( ) { r e t u r n 42; } i n t bar ( ) { i n t i = 0 ; foo ( ) ; i = 23; } ; void nonvoidret ( ) { bar ( ) ; }
  27. My last hack Creating a double linked list using a

    single pointer containing the link to the next and the prevoius entry.
  28. My last hack void list () { s t r

    u c t l { s t r u c t l∗ p ; i n t i ; }; s t r u c t l∗ e , ∗ f , ∗ g ; s t r u c t l e1 = { . i = 23 } ; s t r u c t l e2 = { . i = 42 } ; s t r u c t l e3 = { . i = 0 } ; s t r u c t l e4 = { . i = 1337 }; s t r u c t l∗ head = &e1 ; s t r u c t l∗ tail = &e4 ; e1 . p = 0 ^ ( long ) &e2 ; e2 . p = ( long ) &e1 ^ ( long ) &e3 ; e3 . p = ( long ) &e2 ^ ( long ) &e4 ; e4 . p = ( long ) &e3 ^ 0; f o r ( e = head /∗ t a i l ∗/ , f = NULL ; e != NULL ; g = ( long ) f ^ ( long ) e−>p , f = e , e = g ) { printf ( "%d\n" , e−>i ) ; } }