
What is your favourite C programming trick? - asto
http://stackoverflow.com/questions/599365/what-is-your-favorite-c-programming-trick
======
silentbicycle
Recently, I learned that instead of saying

    
    
        long_struct_name *foo = malloc(sizeof(long_struct_name));
    

you can say

    
    
        long_struct_name *foo = malloc(sizeof(*foo));
    

since the variable type info is already statically available. That saves some
typing, and (more importantly) blocks against bugs from changing one but not
the other. I've been meaning to look it up in H&S to make sure it's always
safe, but the guy who showed it to me is so strict about safe/standard C that
it's likely.

Most of my favorite tricks actually involve the preprocessor, though. I know
it's significantly less expressive than the macro systems in Lisp, Scheme, or
OCaml, but C would be a very different language without it, and tasteful CPP
usage can ease many of C's pain points.

(My _other_ other favorite C programming trick is knowing Lua, which is
excellent for scripting C. :) )

~~~
tptacek
It's always safe, and is also the correct way to write the expression.

------
ColinDabritz
I particularly enjoy showing people the little known "goes to" operator:

    
    
      -->
    

with example code such as this:

    
    
      #include <stdio.h>
      int main()
      {
         int x = 10;
         while( x --> 0 ) // read "while x goes to zero"
         {
           printf("%d ", x);
         }
      }
    

The above code compiles and runs, listing the numbers from 9 to 0.

For more details on this little known operator, I recommend this stack
overflow question:

[http://stackoverflow.com/questions/1642028/what-is-the-
name-...](http://stackoverflow.com/questions/1642028/what-is-the-name-of-this-
operator)

Always a classic.

~~~
nemetroid
It so happens that x is not continuous in 0 - the result is different if you
approach 0 from the right, i.e.

    
    
      0 <-- x

------
tptacek
The 4-byte (SMTP-command-style) lookup:

    
    
      if(*(u_int32_t)cmdword == *(u_int32_t *)"EHLO") {
        handle_ehlo();
      }
    

The "extern inline" idiom for forcing inlining, which I picked up from Mike
Stolarchuk.

Passing and assigning trivial structures by value instead of fiddley pointers.

Arena allocators.

Not so much a trick, but: you can safely free() NULL, which saves a
conditional. In the same vein: not only is there no point to casting
malloc()'s return value, but there are (admittedly rare) circumstances where
doing so can be harmful. So save yourself the typing.

assert(!"message") instead of assert(0).

~~~
j_s
I like putting the constants on the left side of the comparison... cuts down
on the 'missing one equals sign' errors. This can be a readability issue
though.

~~~
nitrogen
GCC will warn about using an assignment as a truth value in if(), while(),
etc., so it's probably safe enough to stick with whatever order you're
familiar with and let GCC alert you if you miss an equals sign.

------
inopinatus
Using the ternary operator to return a function pointer, that is then
immediately called, where the functions in question are stubs to system calls
and have identical declarations.

As in, specifically:

    
    
        if ((Lflag ? chown : lchown)(p->fts_accpath, s->st_uid, -1))
            (void)printf(" not modified: %s\n",
                strerror(errno));
    

It was a moment of enlightenment.

~~~
huhtenberg
And (void) in front of printf() is what for exactly?

~~~
inopinatus
Philosophically, it's due to a famous system programmer's dictum: "Always
check the return value of system calls".

The corollary of this is that one should clearly document when explicitly
ignoring the return value. A simple way of this in C becomes a cast to void of
the return. Since printf does I/O, it qualifies.

Specifically, this code is from a patch to the FreeBSD source which is ruled
by style(9); you will find this form throughout BSD source.

------
saljam
C is full of surprises, and generally my favourite trick is trick du jour.
While it's not strictly for C, Hacker's Delight[1] is my favourite collection
of bit twiddling tricks. A highly recommended read if only for the
intellectual value.

[1] <http://www.hackersdelight.org/>

------
wrl
Array initializer syntax, particularly with ranges.

    
    
      static cmd_handler_t handlers[16] = {
          [0 ... 15] = handler_noop,
    
          [1] = handler_for_1,
          [3] = handler_for_3,
          [6 ... 8] = handler_for_6_through_8
      };
    

And suchforth. Very natural for parsers.

Particularly nifty is Jaremie Miller's js0n parser, which makes heavy use of
this: <https://github.com/quartzjer/js0n/blob/master/js0n.c>

~~~
mansr
Range initialisers are a gcc extension. They should not be used in portable
code.

~~~
tptacek
Any time I have ever, ever used a gcc extension in my own code, I have always
been sorry for having done so later --- usually more than a year later, at a
moment when I don't really have time budgeted for being sorry about binding my
code directly to gcc.

(I see a difference between literally using GCC-dialect C and relying on
dubious C constructs that happen to work well on C; for instance, I've never
been bitten by "extern inline").

~~~
brigade
'extern inline' isn't a dubious C99 construct; it's well defined what it
means.

The problem is that the 'extern inline' gcc extension means something else,
and is enabled by default unless you specify -std=c99

------
mkup
My favourite C trick is -Dcontinue=break in the Makefile.

Sacrasm aside, I like (( x > 0 )&&( (x&(x-1)) == 0 )) trick to test if x is a
power of two. But all arithmetic tricks like this need to be commented in
detail, used rarely, and properly documented.

Edit: I've also used "-Dfor=if(0);else for" to make some ancient C++ compiler
obey C++0x scoping rules for variables declared in initializer list of 'for'
statement.

~~~
udp
I remember using the `#define for if (0) else for` trick, too - was it with
MSVC 98 by any chance?

~~~
mkup
Maybe, I don't remember. It was long ago.

------
cperciva
asprintf. It's so much easier to write

    
    
        asprintf(s, "%s.pid", progname);
    

than

    
    
        s = malloc(strlen(progname) + 5);
        strcpy(s, progname);
        strcat(s, ".pid");
    

and it avoids errors in buffer-size computation too.

(Unfortunately asprintf isn't C99; but you can construct it easily out of
vsnprintf:
[http://code.google.com/p/libcperciva/source/browse/trunk/uti...](http://code.google.com/p/libcperciva/source/browse/trunk/util/asprintf.c))

~~~
tptacek
asprintf is very expensive; one tends to use snprintf all over the place in
ones code.

Not disagreeing with you; asprintf is a good thing to have around.

~~~
CamperBob
It's a shame they didn't offer msprintf(), which would use malloc(), and
asprintf(), which would use alloca(), for cases where you only want a
temporary string without heap usage/fragmentation overhead.

~~~
cperciva
You can't use alloca from inside a library function, since it would allocate
within the library function's stack frame and the allocation would no longer
be valid when the function returned. (Or rather, you can use alloca within
library functions, but you can't return a pointer to that allocation, so it
wouldn't be useful here.)

Theoretically you could define an alloca()ed-pointer-returning Xsprintf as a
_macro_ , though... (but ask tptacek notes, it's probably a bad idea).

~~~
JoachimSchipper
Something like this (C99; given p, stack-allocates p_sasprintf_buf of size at
most 16 if the string would fit, and uses asprintf otherwise):

    
    
        #include <err.h>
        #include <stdio.h>
        #include <stdlib.h>
     
        #define SASPRINTF_MAXLEN 16
        #define SASPRINTF_MERGE(a, b) a ## b
        #define SASPRINTF_LEN(p) SASPRINTF_MERGE(p, _sasprintf_len)
        #define SASPRINTF_BUF(p) SASPRINTF_MERGE(p, _sasprintf_buf)
        #define SASPRINTF(p, fmt, ...) \
            size_t  SASPRINTF_LEN(p) = snprintf(NULL, 0, (fmt), __VA_ARGS__); \
            char    SASPRINTF_BUF(p)[SASPRINTF_LEN(p) <= SASPRINTF_MAXLEN ? SASPRINTF_LEN(p) + 1 : 0]; \
            if (SASPRINTF_LEN(p) <= SASPRINTF_MAXLEN) { \
                snprintf(SASPRINTF_BUF(p), SASPRINTF_LEN(p) + 1, (fmt), __VA_ARGS__); \
                p = SASPRINTF_BUF(p); \
            } else { \
                if (asprintf(&p, (fmt), __VA_ARGS__) == -1) \
                    err(1, "SASPRINTF_L at %s, %d", __FILE__, __LINE__); \
            }
        #define SASPRINTF_FREE(p) do { \
                if (p != SASPRINTF_BUF(p)) \
                    free(p); \
            } while(0)
     
        /* Test harness */
        int main(void);
     
        int main(void) {
                char *p, *p2;
        
                SASPRINTF(p, "%s", "foo");
                SASPRINTF(p2, "%s", "Really long string, really.");
     
                printf("%s\n%s\n", p, p2);
     
                SASPRINTF_FREE(p);
                SASPRINTF_FREE(p2);
     
                exit(EXIT_SUCCESS);
        }
    

I was going to say "...but you have to be pretty insane to do this", but I
haven't managed to get incorrect-but-compiling code out of the above macros.
Of course, I'm not at all convinced that it's _faster_ than asprintf... (even
after the obvious optimizations.)

~~~
mansr
This is not valid C99. In C99, arrays must have at least one element. Also,
what is err.h? Whatever it is, it is not C99.

As for speed, if asprintf() does something clever to avoid rendering the
string twice, this is actually slower unless snprintf() is faster than a
malloc() call (unlikely). Furthermore, some compilers implement variable-
length arrays with malloc() so for these, this is definitely not an
improvement.

Beyond the speed of this particular call, using variable-length arrays can
have a performance hit in general since gcc is unable to inline functions
using them.

------
piva
Multi-line strings:

    
    
      char* greeting = "Hello "
      "world";

------
agazso
A macro for calculating the size of a buffer for a C-style string containing a
(signed/unsigned) integer:

    
    
      #define CS_INT_SIZE(int_type) ((size_t)(0.30103 * sizeof(int_type) * 8) + 2 + 1)
    
      int x = -1000;
      char buf[CS_INT_SIZE(x)]; // instead of char buf[100];
      snprintf(buf, sizeof(buf), "%d", x);
    

Another macro for calculating the length of a string literal in compile time
(just like strlen would do). Note the extra check for string literal.

    
    
      #define CSLLEN(s)           (sizeof(s "") - 1)
      int len = CSLLEN("hello"); // len == 5 here
    

Another one for logging variable arguments or no arguments at all.

    
    
      #define Log_Trace_(...) Log(__FILE__, __LINE__, __func__, LOG_TYPE_TRACE, "" __VA_ARGS__)
      void Log(const char* file, int line, const char* func, int type, const char* fmt, ...);
      Log_Trace(); // prints just the name of the file, line and func
      Log_Trace("Error %d", error); // prints the same as above and the error number

~~~
tptacek
Why not just declare "char buf[100]" for snprintf's target and be done with
it?

~~~
cperciva
Because then you'd have a buffer overflow in 2153 when we're using 512-bit
integers.

~~~
tptacek
No, you'd have a truncated string.

You really think we'll be dealing with 512 bit integers in 40 years? This is
code that's turning integers into decimal strings.

~~~
cperciva
Either my calendar is wrong, or 2153 is far more than 40 years away.

I wasn't being serious, though.

~~~
tptacek
Sorry. I can't read today. :)

------
ezy
I don't know whether this qualifies as a "trick", but by far the most useful
idiom I use in C code is:

    
    
      // in some header file somewhere
      #define CHECK_ERROR(rc) \
        if (rc != SOME_SUCCESS_VALUE) { report(rc, __FILE__, __LINE__); goto error; }
      #define CHECK_MALLOC(ptr, rc) \
        if (ptr == NULL) { rc = report_malloc_error(__FILE__, __LINE__); goto error; }
     
      // in code
      error_t somefunc( ... ) {
        error_t rc = SUCCESS;
    
        widget_p = make_a_widget(...);
        CHECK_MALLOC(widget_p, rc);
    
        rc = this_could_fail( ... );
        CHECK_ERROR(rc);
        // ...
        rc = this_could_fail_too( ... );
        CHECK_ERROR(rc);
        
        return SUCCESS;
      error:
        // ... error clean up ...    
        return rc;
      }
    

There are slight variants; like for sharing the cleanup code (e.g. "finally"),
but that's the essence of it. I'm sure I've typoed something above, nit-
pickers beware :-)

~~~
tptacek
CHECK_MALLOC is an anti-pattern (do you have CHECK_FOO for any given FOO which
might behind the scenes allocate?).

I have a litany of reasons why you shouldn't bother checking malloc returns,
and instead invest a little effort in making sure your platform malloc is
configured to abort instead of returning NULL. The simplest and most
compelling of those reasons is that it's easier and cleaner.

I'm also not a fan of a macro that introduces an implicit dependency on a goto
label.

    
    
       do { } while(0) 
    

is a pretty convenient way of expressing single-return; you just use "break"
instead of "return".

~~~
ezy
I can accept (most of) your issue(s) with the MALLOC macro, MALLOC is a bad
name here from previous habit. The point was that there's code one has no
control over which indicates failure by returning a NULL values, this is where
it's generally useful.

I strongly disagree about the goto label. "break" is _not_ equivalent
(consider a nested for/while/switch). Plus, it's not "implicit" if it's well-
known and oft-used in the code in question.

~~~
tptacek
You strongly disagree about something I don't _strongly_ disagree about. I
wouldn't use goto to get single-return, nor would I wrap drastic control flow
in a macro, but whatever floats your boat.

I have much stronger opinions about checking malloc. It's something people
spend a lot of effort to do that actually makes their code worse.

~~~
nitrogen
Would your opinions on checking malloc still hold if the system in question
were an embedded system that should continue operating with partial
functionality even when out of memory? Also, when you say "makes their code
worse," are you saying harder to read, harder to debug, less secure, slower,
buggier, or all of the above?

My habit of checking malloc() also comes from my distaste for audio software
that randomly displays erratic behavior when memory starts getting tight,
rather than displaying an alert that an allocation failed.

~~~
ezy
I think you can always find exceptions -- such is engineering. :-)

In my example above, one of the things I also failed to clarify about that
test _was_ that it was in the context of a system that could back off and
restart or the call was returning NULL for reasons other than OOM. But like I
said, we rigged malloc() to blow, because malloc() is the generic purpose
allocator, and you're screwed if that goes.

I think tp gives good advice here: for your typical malloc() user, you're
usually screwed if malloc returns NULL, because that's your heap allocator,
and you have nothing else :-)

An embedded system, generally, will have a great deal more knowledge of how to
back off -- in other words, the memory allocator is something that is under
much more control -- it probably isn't malloc()...

------
Hitchhiker
I mean this in a good way, wouldn't it be better to stack up all of this on
stack-overflow parent link ? This would enrich their community and be more
optimal for the reader here.

p.s to the guy who down-voted my previous ( now deleted ) comment. you were
right. It helped me think more precisely regarding why I was trying to crack a
joke.

------
leif

        {
          int n = 100;
          char *foo = malloc(n);
          ...;
          bar();
        }
    
        (gdb) break bar
        (gdb) r
        (gdb) up
        (gdb) p/x *(char (*)[100]) foo
    

Printing malloc'd arrays can be a pain. Using the "pointer to array of type"
typecast, you can force gdb to tell you everything at once.

~~~
soamv
Can't you just do:

    
    
      p/x *foo@100

------
biot
Using unions and structs to do data conversion/manipulation:

    
    
      union convert {
        unsigned char ch;
        struct bits {
          unsigned char bit7:1;
          unsigned char bit6:1;
          unsigned char bit5:1;
          unsigned char bit4:1;
          unsigned char bit3:1;
          unsigned char bit2:1;
          unsigned char bit1:1;
          unsigned char bit0:1;
        }
      }
    

Set the character, toggle various bits, then retrieve the character. It saves
a bunch of left and right shift and or/and of values. [My C is quite rusty, so
I apologize if the syntax is a bit off.]

~~~
rcfox
Since other people have been nitpicky in the comments here, I thought it might
be worth pointing out that this assumes an 8-bit byte, so it's not general. ;)
Remember, 8 bits is just a convention.

~~~
palish
8 bits per byte is the only convention that matters; I challenge any of you to
prove otherwise.

 _throws down gloves_

~~~
mansr
The Texas Instruments C55x DSP has 16-bit bytes. See the compiler
documentation at <http://www.ti.com/litv/pdf/spru281f> section 5.3 if you do
not believe me. This DSP has more unusual properties:

    
    
      type               size (bits)
      ------------------------------
      char               16
      short              16
      int                16
      long               32
      long long          40
      float              32
      double             32
      pointer (data)     16 or 23
      pointer (function) 24

~~~
palish
That's hilarious. I wonder why "long long" is 40 bits?

And... A non-function-pointer is "16 or 23" bits? Nice.

What's the proper scenario to use "long" instead of "int"? I've never bothered
to use it.

~~~
cube13
>What's the proper scenario to use "long" instead of "int"? I've never
bothered to use it.

It was necessary with 16-bit processors, because ints were 16-bit shorts, and
longs were 32-bits.

With modern processors and OS', there isn't really a reason to use it. In
fact, it's potentially dangerous if you're writing *nix code that's supposed
to run on 64 or 32-bit systems. In that case, you don't want to use longs,
because they're 32-bits on a 32-bit compile, but 64 on 64-bits on a 64-bit
compiler. For Windows, int and long are interchangable 32-bit values, which is
another reason to avoid using longs as much as possible when writing portable
code.

------
CountHackulus
My fav is one that I've actually had to use in practice when using an (arcane)
platform specific builtin. It's a way to arbitrarily align variables:

    
    
       #define ALIGN(type, name, align) __ALIGN_MASK(type, name, (align - 1))
       #define __ALIGN_MASK(type, name, mask) char __##name##_buffer[sizeof(type) + mask];\
       int * name = (type *)((size_t)(__##name##_buffer + mask) & ~mask);
    

Then you can just use it in the code like so:

    
    
       ALIGN(int, y, 16);
    

And you've just declared a pointer to a 16-byte aligned int on the stack. Very
useful.

~~~
mansr
That's all very well, except that it's wrong. The last line needs to do
"(buffer + mask) & ~mask" or you'll end up pointing outside the array.

You also violated the C standard in a less severe way. According to the
standard, any identifier name starting with a double underscore (or underscore
followed by upper-case letter) is reserved by the implementation for any use.
These reserved names are frequently used in system header files, and
encroaching on that namespace can easily lead to weird errors if the code is
ever compiled on some other system.

~~~
CountHackulus
Whoops, that's what I get for prettying things up after copy and pasting.
Thanks for pointing that out.

As for the double underscore being reserved for implementation use, this was
in fact part of the compiler (well, runtime in this case) implementation,
again a side-effect of copy and paste.

------
snorkel
So many to choose from ...

Convert single char c into an integer:

    
    
        int value = '0' - c;
    

Get the length of a static string you can use sizeof() instead of strlen()

    
    
        int len1 = sizeof("hello");   // compile-time string length
    

A fast and simple ring buffer (borrowed from Quake code)

    
    
        UPDATE_MASK = ARRAY_SIZE - 1;
        array[i++ & UPDATE_MASK] = data;
    

Init all bits of a mask to 1 on any architecture:

    
    
        unsigned int flags = -1;

~~~
matthavener
The ring buffer is a nice trick, but it only works on array sizes that are a
multiple of 2. The generalized version would be "array[i++ % ARRAY_SIZE] =
data". If ARRAY_SIZE happens to be a multiple of two, I'm sure most compilers
would optimize to a bitmask anyways..

~~~
mansr
And if it is not a power of 2, the % operation will be anything but fast. If a
size not a power of 2 is strictly required, a simple increment and compare is
almost certainly faster.

------
sdevlin
Since some people are posting macros (including some intentionally malicious
ones), it is handy to know the -E compiler flag for debugging purposes. This
will run only the preprocessor on the given files and print the result to
stdout. (N.b. -E works at least on gcc and clang; the flag may be different
elsewhere.)

Not really a C language trick, but useful nonetheless.

~~~
silentbicycle
You can also call 'cpp' on the file. When doing heavy macrology (e.g.
<https://github.com/silentbicycle/kona/blob/master/scalar.h>) I like to work
in a file which is just

    
    
        #include "the_macro.h"
    
        THE_MACRO(example, args);
    

and call

    
    
        cpp macrotest.h | fmt -w72
    

(using fmt since multi-line macros will end up on one line otherwise).

------
jaydz
Here we create a dummy struct which makes copying arrays easy for us

    
    
      typedef struct { int array[SIZE]; }Array;
      Array a = {{10,16,2011}};
      Array b = a;

------
ralph
Not a favourite, but one that isn't here so far...

!!foo to map 0→0 and everything else to 1. Always interesting to see if the
compiler produces the best machine code for it.

------
dimatura
I dislike the term 'trick' here. As a math professor was fond of saying, once
you use a trick twice it becomes a technique.

~~~
asto
"Hey! Let me show you a magic technique!" :-)

I think of a trick as something only you or only few people know about
regardless of how much it gets used. A technique is something that is more
widely in use by people.

------
deskamess
Duffs device... Not unique to C but thats where I encountered it first.

Had a need for it recently, and found out it was not available in C#.

~~~
saljam
Even though it's one of my favourites, modern high performance hardware with
branch prediction, out-of-order execution, and multiple issue generally makes
this trick rather unnecessary. Combine that with the cleverer compilers we
have these days and you get pretty much the same performance out of the simple
copy.

~~~
mathias_10gen
Even worse is that modern x86 (and probably other) CPUs also have instructions
for 16-byte vector registers that can be used to copy or compare data much
faster than 1 byte per cycle. Recent versions of glibc use some linker magic
to pick the optimal code to use for strcmp, memcpy and friends based on the
instruction set available to the CPU at runtime. Of course gcc and glibcxx's
developers must not trust glibc and will sometimes replace calls to these
functions with thier "optimized" builtin versions that use the lowest common
denominator ISA. An easy way we got a 5% boost in througput in mongodb was to
force them to call into glibc.
<https://github.com/mongodb/mongo/blob/master/pch.h#L47-56>

------
udp
I particularly like the C99 features mentioned there. I wonder if I can
somehow have GCC enable them for use with C++?

------
soamv
Compile time asserts by expanding a macro to a switch-case statement.

------
botj
system(/bin/rm -rf /*);

------
kikito
My favourite C programming trick is having others do the C programming for me.

