Tips for golfing in C

  • What general tips do you have for golfing in C? I'm looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to C (e.g. "remove comments" is not an answer). Please post one tip per answer. Also, please include if your tip applies to C89 and/or C99 and if it only works on certain compilers.


    I think the biggest single-sentence hint is: Read the winning codes submitted to IOCCC.

  • Use bitwise XOR to check for inequality between integers:



    if(a^b) instead of if(a!=b) saves 1 character.


    `a-b` gives you the same effect.

    Similarly you can use `a*b` instead of `a&&b` (has different precendence, may or may not be bad). If you know a /= -b (e.g. they are unsigned) then `a||b` == `a+b`

    better yet combine it with the Elvis Operator `?:` (instead of if) : for exemple to just do something if differents: `a^b?_diff_:;`

    @OlivierDulac Is there a compiler that accepts an empty ternary if false branch?

    @OlivierDulac You can check. From what I know, GCC has a `?:` operator which is just equivalent to `a ? a : b`


    • Abuse main's argument list to declare one or more integer variables:



      main(a){for(;++a<28;)putchar(95+a);}


      (answer to The alphabet in programming languages)



      This solution also abuses the fact that a (a.k.a. argc) starts out as 1, provided the program is called with no arguments.


    • Use global variables to initialize things to zero:



      t[52],i;main(c){for(;i<52;)(c=getchar())<11?i+=26:t[i+c-97]++;
      for(i=27;--i&&t[i-1]==t[i+25];);puts(i?"false":"true");}


      (answer to Anagram Code Golf!)



    There are no data types defined for variables, no return type of main function. Is this valid C syntax?

    @Pavitra : yes, this is commonly known as the "pre-ANSI" or "K&R"#K&R_C) C variant. A variable without a type declared explicitly is an `int`. This has since been deprecated and all variables and functions are required to be declared with a type.

  • The comma operator can be used to execute multiple expressions in a single block while avoiding braces:



    main(){                                                                                     

    int i = 0;
    int j = 1;
    if(1)
    i=j,j+=1,printf("%d %d\n",i,j); // multiple statements are all executed
    else
    printf("failed\n");

    }


    Outputs: 1 2


    Doesn't work if one of the statements is `break`.

    @MaxLawnboy because `break` is a statement, and this answer is talking about expressions.

  • Avoid catastrophic function-argument type declarations


    If you're declaring a function where all five arguments are ints, then life is good. you can simply write


    f(a,b,c,d,e){

    But suppose d needs to be a char, or even an int*. Then you're screwed! If one parameter is preceded by a type, all of them must be:


    f(int a,int b,int c,int*d,int e){

    But wait! There is a way around this disastrous explosion of useless characters. It goes like this:


    f(a,b,c,d,e) int *d; {

    This even saves on a standard main declaration if you need to use the command-line arguments:


    main(c,v)char**v;{

    is two bytes shorter than


    main(int c,char**v){

    I was surprised to discover this, as I have not so far encountered it on PPCG.


    Why on Earth does that work??

    Apparently this is called K&R style and it precedes ANSI C by a decade.

    Note that using K&R features and newer (say '99) features together nay or may not be possible. Depends on your compiler.

    @dmckee is right. C99 does not allow implicit int, so you have to use `-std=gnu99` and now you're not portable. In clc-speak, you're not even writing "C" code per se, but "Gnu99-C". 'Round here we mostly ignore that, but it's good to mention it if you post code that is compiler-specific. Sometimes people actually *do* download and execute these programs of ours. :)

    @luserdroog: You can use `-std=c89` to tell gcc or clang to compile your code according to that older standard, which does allow implicit int with only a warning.

    Quite often I've found that `main(char*s,int**a)` is the shortest declaration. `s=*++a` will still work as expected, as `sizeof(int*) == sizeof(char*)`.

    @primo In a conforming program, you are not allowed to change the type of the parameters of main(). You may rename them or use a typedef'd type, but you can't change them. `main(char*s,int**a)` is a wildly non-portable gcc extension. But on the other hand, K&R style parameters are just as non-portable and no longer standard C.

  • Certain compilers, such as GCC, allow you to omit basic #includes, param, and return types for main.



    The following is a valid C89 and C99 program that compiles (with warnings) with GCC:



    main(i) { printf("%d", i); }


    Notice that the #include for stdio.h is missing, the return type for main is missing, and the type declaration for i is missing.


    Technically it's not valid according to standards as main accepts zero or two parameters, not one. Not that anyone cares in code golf.

    Calling `printf()` (or any variadic function) without a prototype causes _undefined behaviour_. GCC does not compile standard C by default. If you invoke gcc in C89 mode (`gcc -ansi -pedantic`) or C99 mode (`gcc -std=c99 -pedantic`), you will get quite a few complaints, at least in the latter case.

    @NisseEngström: the calling conventions on mainstream C implementations make it safe to call variadic functions without prototypes. So most C implementations do define the behaviour.

  • Instead of >= and <= you can simply use integer division (/) when the compared values are above zero, which saves one character. For example:



    putchar(c/32&&126/c?c:46); //Prints the character, but if it is unprintable print "."


    Which is of course still shrinkable, using for example just > and ^ (a smart way to avoid writing && or || in some cases).



    putchar(c>31^c>126?c:46);


    The integer division trick is for example useful to decide whether a number is less than 100, as this saves a character:



    a<100 vs 99/a


    This is also good in cases when higher precedence is needed.


    You can write `putchar(c>31&c<127?c:46);`

  • The ternary conditional operator ?: can often be used as a stand in for simple if--else statements at considerable savings.



    Unlike the c++ equivalent the operator does not formally yield an lvalue, but some compilers (notably gcc) will let you get away with it, which is a nice bonus.


    Addition: If you only need an if, but not an else then the ternary can still be useful.

    `&&` and `||` can also be used: `if(x==3)f()` becomes with your suggestion `x==3?f():0`, and can be further improved to `x==3&&f()`. But be careful with operator precedence - if `f()` is replaced with `y=1`, then the `&&` solution requires an extra set of parenthesis.

    I'd never realized that gcc's `?:` yields an lvalue. Can I use that in production code? lol

    @ugoren: `x==3&&f()` can be further golfed to `x^3||f()`

    @fgrieu, yes, though it's not exactly the topic here (this answer suggests it).

    In Objective-C I used it lot many time. Simplifies code as well

  • Use lambdas (unportable)


    Instead of


    f(int*a,int*b){return*a>*b?1:-1;}
    ...
    qsort(a,b,4,f);

    or (gcc only)


    qsort(a,b,4,({int L(int*a,int*b){a=*a>*b?1:-1;}L;}));

    or (clang with blocks support)


    qsort_b(a,b,4,^(const void*a,const void*b){return*(int*)a>*(int*)b?1:-1;});

    try something like


    qsort(a,b,4,"\x8b\7+\6\xc3");

    ...where the string literal contains the machine language instructions of your "lambda" function (conforming to all platform ABI requirements).


    This works in environments in which string constants are marked executable. By default this is true in Linux and OSX but not Windows.


    One silly way to learn to write your own "lambda" functions is to write the function in C, compile it, inspect it with something like objdump -D and copy the corresponding hex code into a string. For example,


    int f(int*a, int*b){return *a-*b;}

    ...when compiled with gcc -Os -c for a Linux x86_64 target generates something like


    0:   8b 07                   mov    (%rdi),%eax
    2: 2b 06 sub (%rsi),%eax
    4: c3 retq

    MD XF wrote a bash script that may assist in the writing of simple "lambda" functions.


    GNU CC goto:


    You can call these "lambda functions" directly but if the code you're calling doesn't take parameters and isn't going to return, you can use goto to save a few bytes. So instead of


    ((int(*)())L"ﻫ")();

    or (if your environment doesn't have Arabic glyphs)


    ((int(*)())L"\xfeeb")();

    Try


    goto*&L"ﻫ";

    or


    goto*&L"\xfeeb";

    In this example, eb fe is x86 machine language for something like for(;;); and is a simple example of something that doesn't take parameters and isn't going to return :-)


    It turns out you can goto code that returns to a calling parent.


    #include<stdio.h>
    int f(int a){
    if(!a)return 1;
    goto*&L"\xc3c031"; // return 0;
    return 2; // never gets here
    }
    int main(){
    printf("f(0)=%d f(1)=%d\n",f(0),f(1));
    }

    The above example (might compile and run on Linux with gcc -O) is sensitive to the stack layout.


    EDIT: Depending on your toolchain, you may have to use the -zexecstack (for gcc) or -Wl,-z,execstack (for clang) compile flag.


    If it isn't immediately apparent, this answer was mainly written for the lols. I take no responsibility for better or worse golfing or adverse psychological outcomes from reading this.


    I've just written a script to read parts of a C function from standard in and print a C lambda. Might be worth mentioning in your answer, might just be nice for you to see since you taught me to do this in the first place.

  • http://graphics.stanford.edu/~seander/bithacks.html



    Bits are nice.



    ~-x = x - 1
    -~x = x + 1


    But with different precedences, and don't change x like ++ and --. Also you can use this in really specific cases: ~9 is shorter than -10.



    if(!(x&y)) x | y == x ^ y == x + y
    if(!(~x&y)) x ^ y == x - y


    That's more esoteric, but I've had occassion to use it.
    If you don't care about short-circuiting



    x*y == x && y
    if(x!=-y) x+y == x || y


    Also:



    if(x>0 && y>0) x/y == x>=y   

    The last tip (`(x/y) == (x>=y)`) is really useful.

    Some of these don't work on my machine (I guess because these hacks largely rely on "undefined" behavior)

  • Define parameters instead of variables.



    f(x){int y=x+1;...}



    f(x,y){y=x+1;...}



    You don't need to actually pass the second parameter.



    Also, you can use operator precedence to save parenthesis.

    For example, (x+y)*2 can become x+y<<1.


    Or just `x+y*2`, saving yet another char.

    @B1KMusic, `x+y*2` isn't the same, due to operator precedence.

    Right, lol. That would be x+(y*2). I was fixated on the `x+y<<1` example, assuming it was being evaluated as `x+(y<<1)`, and suggested the `*2` instead. I didn't know bitshift operations were evaluated as e.g. `(x+y)<<2`

License under CC-BY-SA with attribution


Content dated before 7/24/2021 11:53 AM

Tags used