Digital Cabin

log whoami uses code feeds

#include "this.h"

by dweller - 2019-10-08

#dev #programming #c #python


So, I work with a couple of Python developers, and they really like their Pythonic way. Which is fine, it has many good ideas, but they keep making import this jokes, and I just had to do one for C. And, well, here we are.

First, let’s just see it in action.

// main.c
#include "this.h"


int main(int argc, char** argv)
{
    (void)argc;
    (void)argv;

    return 0;
}

The first ingredient is our regular C source file. It’s just a main function that does nothing. The 2nd one, is our secret sauce, we will discuss it later. And of course, the final ingredient, the C compiler, I’ll use gcc.

So, let’s compile and run it:

$ gcc -Wall -Wextra -pedantic main.c -o main
$ ./main
The Zen of C, by dweller

Code is better than cliché guidelines.
Working code is better than cute, but broken one.
Simple is better than complex, complex is better than broken.
Simple is not necessarily easy.
Zero cost abstractions is lack of abstractions.
Crash often.
There are usually multiple ways to do it.
Especially if it's multi-platform.
Avoid undefined behavior.
Know your tools, understand your platform.
Code, profile, optimize. In that order.
If the implementation is hard to explain, it may be a bad idea.
Or it may be hard to explain.
Delete more code than you write.

Magic, ain’t it? :) Well, needless to say the magic is in the this.h file. So let’s inspect it.

// this.h
#ifndef THIS_H
#define THIS_H

#include <stdio.h>


#define main                                                                 \
    __dummy(void) {return 0;}                                                \
    int __user_main(int, char**);                                            \
    int main(int argc, char** argv)                                          \
    {                                                                        \
        printf("The Zen of C, by dweller\n"                                  \
          "\n"                                                               \
          "Code is better than cliché guidelines.\n"                         \
          "Working code is better than cute, but broken one.\n"              \
          "Simple is better than complex, complex is better than broken.\n"  \
          "Simple is not necessarily easy.\n"                                \
          "Zero cost abstractions is lack of abstractions.\n"                \
          "Crash often.\n"                                                   \
          "There are usually multiple ways to do it.\n"                      \
          "Especially if it's multi-platform.\n"                             \
          "Avoid undefined behavior.\n"                                      \
          "Know your tools, understand your platform.\n"                     \
          "Code, profile, optimize. In that order.\n"                        \
          "If the implementation is hard to explain, it may be a bad idea.\n"\
          "Or it may be hard to explain.\n"                                  \
          "Delete more code than you write.\n"                               \
          );                                                                 \
        return __user_main(argc, argv);                                      \
    }                                                                        \
    int __user_main

#endif // THIS_H

This is the secret sauce. What it does is replaces any symbol main (which is usually your program entry) with this mess. First part is __dummy(void) {return 0;}, it simply closes the int that we assume comes before main. After that, it declares a function __user_main that has the same signature as regular main. Then, we actually declare and define actual main function, we print our little joke-ish Zen, call __user_main function with arguments from the shell and return whatever it returns. And finally, at the end, we simply start the actual definition of __user_main, as we expect the user’s main implementation after this.

Let’s see the output of C preprocessor, ignoring the stdio.h stuff:

$ cpp main.c
# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "main.c"
# 1 "this.h" 1

// tons of stdio.h stuff...

# 5 "this.h" 2
# 2 "main.c" 2

# 4 "main.c"
int __dummy(void) {return 0;} int __user_main(int, char**); int main(int argc, char** argv) { printf("The Zen of C, by dweller\n" "\n" "Code is better than cliché guidelines.\n" "Working code is better than cute, but broken one.\n" "Simple is better than complex, complex is better than broken.\n" "Simple is not necessarily easy.\n" "Zero cost abstractions is lack of abstractions.\n" "Crash often.\n" "There are usually multiple ways to do it.\n" "Especially if it's multi-platform.\n" "Avoid undefined behavior.\n" "Know your tools, understand your platform.\n" "Code, profile, optimize. In that order.\n" "If the implementation is hard to explain, it may be a bad idea.\n" "Or it may be hard to explain.\n" "Delete more code than you write.\n" ); return __user_main(argc, argv); } int __user_main(int argc, char** argv)
{
    (void)argc;
    (void)argv;

    return 0;
}

If we just massage the code to make it bit more readable, since all of it is on the same line, plus remove all the cpp stuff. We get:

// stdio.h stuff...

int __dummy(void) {return 0;}
int __user_main(int, char**);

int main(int argc, char** argv)
{
    printf("The Zen of C, by dweller\n"
           "\n"
           "Code is better than cliché guidelines.\n"
           "Working code is better than cute, but broken one.\n"
           "Simple is better than complex, complex is better than broken.\n"
           "Simple is not necessarily easy.\n"
           "Zero cost abstractions is lack of abstractions.\n"
           "Crash often.\n"
           "There are usually multiple ways to do it.\n"
           "Especially if it's multi-platform.\n"
           "Avoid undefined behavior.\n"
           "Know your tools, understand your platform.\n"
           "Code, profile, optimize. In that order.\n"
           "If the implementation is hard to explain, it may be a bad idea.\n"
           "Or it may be hard to explain.\n"
           "Delete more code than you write.\n");

           return __user_main(argc, argv);
}

int __user_main(int argc, char** argv)
{
    (void)argc;
    (void)argv;

    return 0;
}

And I think, that’s pretty self-explanatory if you know C. Needless to say, this has a lot of issues. It works only assuming you include it in the file that contains main function, and that its signature is int (*)(int, char**), which is not always true. So this is just a toy to generate a bit of airflow through some nostrils of a few programmers.

Have a nice one!


[Valid Atom 1.0] More…
If you can spare some $$$... Help Ukraine: Or me :P