JoshuaWise.com

A small list of C brainteasers


A small list of C brainteasers

Here's a small list of C brainteasers that a few friends and I came up with and/or found. (All problems, except where specified, in C99.)

  • Can you write some C of the form sizeof ( ... printf(“hey!\n”) ... ) which results in hey! being printed?
    • No, you may not put a close paren in the first ....
    • sizeof comes in two forms in C – sizeof ( TYPENAME ), and sizeof EXPRESSION. Can you do it with both forms?
    • Can you do it without emitting any warnings?
  • Can you write some C that has the tokens [ * ] in a row?
  • How about the tokens restrict 5?
  • Can you write an a.c that results in:
    jwise@jwise-lt-linux:~$ grep '#' a.c
    jwise@jwise-lt-linux:~$ grep '{' a.c
    jwise@jwise-lt-linux:~$ cc -std=c99 -pedantic -Wall -o a a.c && ./a
    hey!
    • ... portably?
  • Can you write an a2.c that results in:
    jwise@jwise-lt-linux:~$ grep '#' a2.c
    jwise@jwise-lt-linux:~$ grep '{' a2.c
    jwise@jwise-lt-linux:~$ grep '\[' a2.c
    jwise@jwise-lt-linux:~$ grep '"' a2.c
    jwise@jwise-lt-linux:~$ grep "'" a2.c
    jwise@jwise-lt-linux:~$ gcc -std=c89 -pedantic -o a2 a2.c && ./a2
    hey!
    • ... portably?
  • Can you write a program a3.c that results in:
    jwise@jwise-lt-linux:~$ grep '"' a3.c
    jwise@jwise-lt-linux:~$ grep "'" a3.c
    jwise@jwise-lt-linux:~$ grep ';' a3.c
    jwise@jwise-lt-linux:~$ gcc -std=c99 -pedantic -Wall -o a3 a3.c && ./a3
    hey!
    • Portably?
  • Can you write a program a4.c that results in:
    jwise@jwise-lt-linux:~$ grep '"' a4.c
    jwise@jwise-lt-linux:~$ grep "'" a4.c
    jwise@jwise-lt-linux:~$ grep ';' a4.c
    jwise@jwise-lt-linux:~$ grep -E '{[^}]|{$' a4.c
    jwise@jwise-lt-linux:~$ gcc -std=c99 -pedantic -Wall -o a4 a4.c && ./a4
    hey!
    • Without using the tricks from a or a2?
    • The only implemenation I know of requires the compiler to take a specific view of the specification; you'll need gcc's view of the specification, not clang's.
  • (taken from elsewhere on the Web) Without running it, what is the output of the following program?
    int main(void) {int n = sizeof(0)[“abcdefghij”]; printf(”%d\n”, n); return 0; }
    • It is not machine-specific.
  • A common idiom in C is assert(!”That's not gone well”). Unfortunately, a common idiom in C amongst careless programmers is assert(“That's not gone well”), or the potentially even more amusing assert(”!That's not gone well”). Can you write a macro that chokes with a compile time failure on the latter two cases?
    • More concretely: it is easy to write a static assert macro that fails to compile if a given expression is either a) false, or b) not compile-time constant. Your task is to write a static assert macro that fails to compile if a given expression is a) true and b) a compile-time constant!
    • Here are some test cases, if you care:
      ASSERT_CHECKER(time());
      ASSERT_CHECKER(0);
      ASSERT_CHECKER("abc"[2]);
      ASSERT_CHECKER(!"biteme");
      ASSERT_CHECKER("biteme");
      ASSERT_CHECKER(2 + 2);

      The last two should fail, by the C99 specification. There is an easier way to do it with a GCC extension, but you do not need any GCC extensions to do this.

  • (C++11-only) Find a use for the token sequence .......

I've enabled comments below, but please don't post spoilers.