Fizzbuzz but without if
char *
itoa(int n)
{
    static char out[WIDTH + 1];

    for(char *outp = out + WIDTH - 1; outp &gt;= out; --outp, n /= 10)
        *outp = '0' + n % 10;


Nice bounds-check (outp &gt;= out). This ensures that you don't overrun your buffer when given a very large integer. However, since out-1 is not a valid pointer value, outp &gt;= out is an incorrect bounds-check for the same reason that

int decr(int x) {
    int y = x - 1;
    if (y &gt; x) return 0;  // oops, overflow happened
    return y;
}


is an incorrect overflow-check.

Your bounds-check code also has another similarity to the above overflow-check code: When overflow happens, you return an in-range value that the caller might reasonably confuse for a valid result of the function. When itoa(x) returns "42", does it mean that x was 42, or does it mean that x was 1042 and overflow happened? It would be much better to say, if overflow happens, we return NULL.

Of course you'll have to express that "if" without if. ;)



itoa returns char*, but you don't expect the caller to modify the pointed-to chars, so you should declare it as returning a pointer to non-modifiable chars: const char*. Const is a contract.

Similarly, static char *FBSTR[4] should be static const char *FBSTR[4].



static const char *FBSTR[4] = {"", "Fizz", "Buzz", NULL};


would be much clearer to the human reader; it shows that you didn't miscount the number of array elements. In fact, you might even write

static const char *FBSTR[] = {"", "Fizz", "Buzz", NULL};


although the downside of that is that the number of indices is actually really important to your algorithm, so I can see a valid argument for keeping the 4 in this case.



fputs(FBSTR[1 * (n%3 == 0)], stdout);
fputs(FBSTR[2 * (n%5 == 0)], stdout);
fputs(FBSTR[3 * (n%3 &gt; 0 &amp;&amp; n%5 &gt; 0)], stdout);
putchar('\n');


I did puzzle this out, but printing all those empty strings feels like a strange way to go about it. Why not simply

int idx = 1*(n%3 == 0)
        + 2*(n%5 == 0)
        + 3*(n%3 != 0 &amp;&amp; n%5 != 0);
fputs(FBSTR[idx], stdout);
putchar('\n');


In which case you can combine the fputs and putchar into

puts(FBSTR[idx]);




If you think it would be easier to understand, you could even rewrite the index computation using bitwise operations:

const char *FBSTR[] = {itoa(n), "Fizz", "Buzz", "FizzBuzz"};
int idx = (n%3 == 0) + 2*(n%5 == 0);
puts(FBSTR[idx]);




To avoid reinventing the wheel, you could replace itoa(n) with snprintf(somelocalbuffer, sizeof somelocalbuffer, "%d", n). However, for this toy example, itoa does have a more ergonomic interface; and reinventing the wheel isn't necessarily a bad thing.