# 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. – vsz May 12 '12 at 21:23

## Get the length of a string with puts() instead of strlen()

According to the standard C specification, puts() returns a non-negative integer on success. In practice, most C libraries seem to treat puts(s) as equivalent to printf("%s\n", s), which returns an integer equal to the number of bytes written.

As a result, the return value of puts(s) is equal to 1 + strlen(s). If the additional console output can be ignored, this saves a few bytes.

# Use lambdas (unportable)

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 (llvm 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 quoted string 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


# 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.

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. – MD XF Feb 3 '18 at 1:24

# Boolean constant string selection when the selector's true value is guaranteed to be one larger than the second option's length

At its heart, this tip attempts to golf a ternary if of the form cnd?str_true:string_false when two conditions are met, namely that both str_true and string_false are constant strings and cnd is either 0 or strlen(string_false)+1.

If the above conditions are met, the expression cnd?"true":"false" can be golfed* by one byte to "false\0true"+cnd (here cnd == 0 || cnd == 6 always holds); another byte can be shaved off by not escaping the null byte (a compiler dependent feature).

### The tip in action

For this example, suppose the string selection's criterion is k%3's truthiness, where k-1 is never divisible by three. In this case the ternary if

k%3?"°@°":"_" // 13 bytes


can be golfed to:

"_\0°@°"+k%3 // 12 bytes


Which can be golfed down to eleven bytes if one does not escape the null byte.

### Application in obfuscation

As the above requirements are rather strict, this tip is most likely not widely applicable. Nonetheless, the shown technique can also be used to potentially obfuscate a program at no further byte cost.

Given e as a truly boolean expression -- (e) == 0 || (e) == 1 holds -- with the proper operator precedence regarding the upcoming factor, the following snippets are interchangeable* at the same byte count -- when not escaping the null byte.

e?"lifeless":"lychee"
"lychee\0lifeless"+e*7


Bare in mind that this obfuscation is only non-detrimental to the byte count if the second option's string is not longer than eight characters -- since else the factor spans more than one byte.

*: If interpreted as constant strings.

• If the strings to be selected are two or fewer octets in length, you can use wide characters. L"AB"+p will return "A" if p==0 and "B" if p==1. – ceilingcat Nov 24 '18 at 17:43

# Use for rather than while

Any while can be changed into a for of the same length:

while(*p++)
for(;*p++;)


On its own, that's not golf. But we now have an opportunity to move an immediately-preceding statement into the parens, saving its terminating semicolon. We might also be able to hoist an expression statement from the end of the loop; if the loop contained two statements, we could also save the braces:

a=5;while(*p++){if(p[a])--a;++b;}

for(a=5;*p++;++b)if(p[a])--a;

• Even do...while loops should be replaced with for loops. for(;foo,bar,baz;); is shorter than do foo,bar;while(baz); – ceilingcat Nov 24 '18 at 17:48

Use recursion over loops.

Recursive example

f(){printf("infiniteloop");f();}


For loop equivalent is 3 bytes longer.

f(){for(;;)printf("infiniteloop");}

• I think you are missing a semicolon in your recursive example. – Jonathan Frech Jul 9 '18 at 23:48
• Do you have an example for a terminating program which could be golfed in this way? Or does this tip only apply to infinite loops? – Jonathan Frech Jul 10 '18 at 0:11
• Yes, I actually have the shortest c solution in this example – Geo Jul 11 '18 at 17:03
• f(){f(printf("infiniteloop"));} would save a further byte in this example. Try it online! – Dennis Sep 23 '18 at 4:49

When your algorithm produces output in reverse order, take a pointer to the end of a buffer and write it in decreasing order, returning a pointer to the first element. It's up to the caller to supply a buffer large enough for any this input, or for any possible input.

Base conversion / int-to-string is a classic example where this interface is used in real life, such as glibc's internal _itoa, used by the printf family of functions as well as some other internal callers. The max buffer size is 65 bytes for a 64-bit integer -> base 2 string.

// takes a pointer to one-past-the-end, which is also a valid option.
char *itoa_end(unsigned long val, char *p_end) {
// does *not* zero terminate the buffer.  Use *--p_end = 0;
const unsigned base = 10;
char *p = p_end;
do {
*--p = (val % base) + '0';
val /= base;
} while(val);                  // runs at least once to print '0' for val=0.

// write(1, p,  p_end-p);
return p;  // let the caller know where the leading digit is
}


For golfing, it can be more compact to take the pointer by reference and modify it, instead of returning it. (return is a long keyword, and code depending on gcc -O0 evaluating expressions in the return-value register isn't even C.)

For example, I used this in ASCII art uncompression from a base-n number (i.e. int->string with a digit lookup table), where I already needed a char* arg, so it was very cheap to declare another as a char **.

Use *p everywhere you have p in the simple version. *--*p decrements the caller's pointer, then dereferences that to reference the actual character.

/* int n = the number
* int B = size of I = base
* char I[] = input table
* char **O = input/output arg passed by ref:
*    on entry: pointer to the last byte of output buffer.
*    on exit:  pointer to the first byte of the 0-terminated string in output buffer
*/
void semi_golfed_g(n,I,B,O)char*I,**O;
{
for(**O=0 ; n ; n/=B)
*--*O = I[n%B];
}


# Set an array of int to the same value (C99, Linux, BSD, OSX)

int a[n]=...,x=...;
for(int i=n;i--;)a[i]=x


Try something like

int a[n]=...,x=...;
wmemset(a,x,n);


On MSVC on Windows, wmemset() works on arrays of short instead of int.

• Iirc wchar_t is 32 bits wide with gcc on Windows as well, unless you specify the -fshort-wchar flag. – Dennis Jun 16 '18 at 4:41

d(x){return x*2;}
float r(float x){return 1/sqrt(x);}
...
printf( "%d %f\n", d(2), r(2) );


...declare one "function" that does different things depending on return and parameter types.

(*f)()=L"\xf33f048d\xc3c0520f"; // global
...
printf( "%d %f\n", f(2), ((float(*)(float))f)(2) );


Try it online! This works because some ABI's (Linux x86_64, in this example) use separate registers for floating point and integer arguments and return values.

The disassembly of the (*f)() "function"...

0:       8d 04 3f                lea    (%rdi,%rdi,1),%eax
3:       f3 0f 52 c0             rsqrtss %xmm0,%xmm0
7:       c3                      retq


On a x86_64 Linux machine, this function takes the first integer parameter, doubles it and places the result in %eax (char/short/int/long return value). It takes the first floating point parameter, computes a low precision reciprocal square root and places it in %xmm0 (float/double return value).

• This would be a better answer if you decoded the x86 asm in a comment or something, and also link to a method for turning hand-written asm into strings. I don't want to go look up an opcode table. I can see it ends with a c3 RET (x86 being little-endian), but I can only guess that the other bytes are lea eax, [rdi+rdi] and rsqrtps xmm0,xmm0 (with no Newton iteration? that's very inaccurate...), because that's what would make sense. – Peter Cordes Jun 14 '18 at 15:37

# Inverse flag update

Sometimes a challenge asks to determine a data set's specific boolean property. To avoid the unacceptably long return keyword, I often use a flag variable which gets updated in a loop and assign-returned at the end (I will refer to this tip for more detail on assign-returning).

When working with such boolean flags and boolean values, to update them I often use either f&=a|b or f*=a|b to align them with the result of a|b. This is equivalent to saying f = f && (a|b).

However, sometimes a flag needs to be inversely updated, meaning f = f && !(a|b). Naively, one would use f&=!(a|b) (9 bytes), or -- using fundamental logical equivalences -- one would golf it to f&=!a&!b (8 bytes).
For the case of an inverse flag update, though, one might be better off using the binary shift right operator >>, as the previous assignment is (when working with boolean values) equivalent to f>>=!(!a&!b), which simply golfs to f>>=a|b (7 bytes).

If the flag update in question does not involve parentheses due to negation (as in the previous example), inverse flag updating may still be shorter, as for example f&=!a|!b (8 bytes) is equivalent to f&=!(a&b) (9 bytes), which is equivalent to f>>=a&b (7 bytes).

Inverse flag updating may in certain cases also be used even though the values in question are not boolean (either 0 or 1).
If only one operand is boolean, bitwise and (&) can still be used, as the second operand's bits will all be cleared. When using bitwise or (|) or both operands are non-boolean, one should consider using logical and (&&) and logical or (||) to get a boolean result, even though they are one byte longer.

As a side node, these rules also apply when the expression is side-effect-dependent, meaning !f()&&!g() is equivalent to !(f()||g()) regarding the execution of g(), such that even in those cases inverse flag updating can be used.

For testing purposes, I wrote a simple truth table tester (TIO-link).

One recent real-world example of this technique in action would be for example my answer to Detect Rectangular Text.

Sometimes, albeit rarely, if your code contains many for loops, #define F for( may save a byte or two (especially if some of the loops have an empty init section).

If it is applicable to your situation, #define F;for( may save even more bytes.

Examples:

https://codegolf.stackexchange.com/a/153117/61405

https://codegolf.stackexchange.com/a/149629/61405

Whenever a certain function is called several times, it's common to #define it to something shorter. However, certain compilers (MinGW and clang as far as I know) allows for something even more compact by using function pointers:

(*P)()=printf;
P("Test: %d\n", 10);


Other compilers might require an #include of the proper header file for it to work.

# Try cpow() instead of cos()

double y=cos(M_PI*2*x);


try something like

double y=cpow(-1,x*2);


This uses Euler's formula, a little complex analysis and the observation that assigning a complex to a double yields the real part (careful with variadic function calls and other subtleties).

This type of trick can be used to reduce

double y=cpow(-1,x/2);


into

double y=cpow(1i,x);


because

# Inline arrays

If you need a non-int constant array and just use it once, you can do

float f(a){return (float[]){.3,.2,.7}[a];}


float z[]={.3,.2,.7};float f(a){return z[a];}


to save 3 bytes.

(In this case it can save one more byte since the blank after return can be omitted.)

## import if you have to

As noted in the very first answer, some compilers (notably, GCC and clang) let you get away with omitting #includes for standard library functions.

Even if you can't just remove the #include, there might be other ways to avoid it, but that's not always practical or particularly golfy.

In the remaining cases, you can use #import<header file> instead of #include<header file> to save a byte. This is a GNU extension and it is considered deprecated, but it works at least in gcc 4.8, gcc 5.1, and clang 3.7.

### Use s[i] instead of i<strlen(s) in string-handling loops

For example:

for(i=0;i<strlen(s);i++)s[i]=s[i+1];


can be shortened to:

for(i=0;s[i];i++)s[i]=s[i+1];

• Though in this case one would most likely not bother with indices and use pointer incrementation; for(;*s;)*s=*++s;. – Jonathan Frech Apr 30 '18 at 12:59

### Use #define instead of functions when possible

For example:

f(int i,char*s){/*do something with i and s*/;}


Using #define can eliminate the argument list type, curly-braces and closing semicolon:

#define f(i,s)/*do something with i and s*/


This is not really standard C, but works with every compiler and CPU that I know of:

int sqr(int a){return a*a;}


has the same effect as:

int sqr(int a){a*=a;}


Because the first argument is stored into the same CPU register as the return value.

Note: As noted in one comment, this is undefined behaviour and not guaranteed to work for every operation. And any compiler optimization will just skip over it.

### X-Macros

Another useful feature: X-Macros can help you when you have a list of variables and you need to do some operation which involve all of them:

https://en.wikipedia.org/wiki/X_Macro

• I quoted this and I was corrected, This is simply not true. It will only work with multiplications and divisions and when optimizations are turned off. This is because both operations happen to put their results in eax which is the common register for return. Parameters are stored either in the stack or ecx or edx. Try it yourself. – Gaspa79 Apr 9 '17 at 20:15
• You are right, it's undefined behaviour, it also depends on the compiler and on the architecture, I usually check with gcc on x86 and armv7 before posting any answer using this trick. And of course if you enable optimization, any smart compiler would just delete the unnecessary multiplication. – G B Apr 10 '17 at 6:25
• I've seen this work with GCC but not others – Albert Renshaw May 21 '17 at 7:10
• @Gaspa79: gcc with -O0 always chooses to evaluate expressions in the return-value register. I've looked at x86, ARM, and MIPS at least (on gcc.godbolt.org), and gcc seems to go out of its way to do that at -O0. But remember if you take advantage of this, the language you're programming in is gcc -O0, not C, and you should label your answer accordingly, not as C. It fails at any optimization level other than -O0 debug mode, and doesn't work with clang IIRC. – Peter Cordes Jun 14 '18 at 15:18

# Swap variables

If you ever need to swap variables, don't use the pattern with an extra variable or that addition-subtraction-method, just do some chained XORing:

a^=b^=a^=b;

• This is undefined behavior, due to a lack of sequence points in between two modifications of the same object. See here: stackoverflow.com/questions/9958514/… – 2501 Apr 23 '17 at 19:44

Use cursors instead of pointers. Snag the brk() at the beginning and use it as a base-pointer.

char*m=brk();


Then make a #define for memory access.

#define M [m]


M becomes a postfix * applied to integers. (The old a[x] == x[a] trick.)

But, there's more! Then you can have pointer args and returns in functions that are shorter than macros (especially if you abbreviate 'return'):

f(x){return x M;} //implicit ints, but they work like pointers
#define f(x) (x M)


To make a cursor from a pointer, you subtract the base-pointer, yielding a ptrdiff_t, which truncates into an int, losses is yer biz.

char *p = sbrk(sizeof(whatever)) - m;
strcpy(m+p, "hello world");


This technique is used in my answer to Write an interpreter for the untyped lambda calculus.

## Missing includes and return values

As noted in the very first answer, some compilers (notably, GCC anc clang) let you get away with omitting #includes for standard library functions.

While that usually goes well, it might cause problems in some cases, since the implicit declarations of standard library functions inside the source code will cause the compiler to treat return values as ints. For example, the code

char*p=getenv("PATH");


wont work as expected on a 64-bit platform since getenv returns a 64-bit memory address which doesn't fit into an int.

In this case, there are at least three ways to use getenv without errors.

• Include the header file as follows.

#include<stdlib.h>
char*p=getenv("PATH");


This is the right way™, but not very golfy; it costs 19 bytes.

• Declare getenv with the pointer as follows.

char*getenv(),*p=getenv("PATH");


This costs 10 bytes.

• Finally, unless your code wouldn't work on 32-bit platforms, compile your code on one of those or with the -m32 flag (gcc). This costs 0 bytes.

# Reverse Loops

If you can, try to replace

for(int i=0;i<n;i++){...}


with

for(int i=n;i--;){...}


## Go functional!

If you can reduce your problem to simple functions with the same signature and defined as single expressions, then you can do better than #define r return and factor-out almost all of the boilerplate for defining a function.

#define D(f,...)f(x){return __VA_ARGS__;}
D(f,x+2)
D(g,4*x-4)
D(main,g(4))


Program result is its status value returned to the OS or controlling shell or IDE.

Using __VA_ARGS__ allows you to use the comma operator to introduce sequence points in these function-expressions. If this is not needed, the macro can be shorter.

#define D(f,b)f(x){return b;}


When you have to walk a string you can walk the pointer instead of incrementing the index.

Code :

#include <stdio.h>

// print each char
void f(char* s) {
for (int i=0;s[i];i++) putchar(s[i]);
}

// same output than f;
void g(char* s)
{
for (;*s;) putchar(*s++);
}

int main(void) {
f("hello\n");
g("hello\n");
return 0;
}


Knowing basic logical equalities might be able to save a couple bytes. For instance, instead of if (!(a&&b)){} try instead using DeMorgan's law if (!a||!b){}. The same applies to bitwise functions: instead of ~(a|b) do ~a&~b.

for(int i=0;i<n;i++){a(i);b(i);} can be made shorter a few ways:

for(int i=0;i<n;){a(i);b(i++);} -1 for moving the ++ to the last i in the loop

for(int i=0;i<n;b(i++))a(i); -3 more for moving all but one statement into the top and out of the main loop, removing the braces

• Using the comma operator is another way to avoid braces in some cases. – Peter Cordes Jun 14 '18 at 15:22

Here are a few tips I've used to my advantage. I've shamelessly stolen them from others, so credit to anyone but me:

Combine assignment with function calls

r = /* Some random expression */
printf("%d", r);


Do this:

printf("%d", r = /* Some random expression */);


Initialize multiple variables together (when possible)

for(i=0,j=0;...;...){ /* ... */ }


Do this:

for(i=j=0;...;...){ /* ... */ }


Collapse zero/nonzero values

This is a neat trick I picked up from someone here (don't remember who, sorry). When you have an integer value and you need to collapse it to either 1 or 0, you can use !! to do so easily. This is sometimes advantageous for other alternatives like ?:.

Take this situation:

n=2*n+isupper(s[j])?1:0; /* 24 */


n=n*2+!!isupper(s[j]); /* 22 */


Another example:

r=R+(memcmp(b+6,"---",3)?R:0); /* 30 */


Could be rewritten as:

r=R+R*!!memcmp(b+6,"---",3)); /* 29 */

• maybe R*-~!!mxxxx – l4m2 Apr 18 '18 at 5:59

For scanning a string into an array, you can use

gets(str);


scanf("%s",str);

• Yeah, except you should never use gets. – MD XF May 13 '17 at 0:24
• @MDXF Welcome to code golf – Akshay L Aradhya Mar 31 '18 at 17:17
• @MDXF: ... for the exact same reason you should never use "%s" instead of "%256s" as your scanf format string. (Or whatever the buffer size is.) – Peter Cordes Jun 14 '18 at 15:31

Use bitwise and (&) when comparing boolean expressions to save one byte.

Example:

if(i^2&k/3) DoSomething;


Really, really useful when combined with the other tips

• The example if(i^2&k/3) seems like it would be equivalent to if(i != 2 && k >= 3), but it's not because & has higher precedence than ^. Also, even if(i-2&k/3) wouldn't work, because a bitwise and of two nonzero values could result in zero. On the other hand, if(i!=2&k>2) would work. – user59468 Sep 19 '16 at 23:44

for(i=1;i<12;i++){if(!i%3)printf("\n");printf("%d",i);}


just use

for(i=1;i<12;i++) printf("%c%d",!(i%3)*10,i);


it helps me so much .

@SamHocevar 's answer (shoretr by 2bytes)

for(i=1;i<12;i++) printf("\n%d"+!!(i%3),i);

• The second line is incorrect; it will actually print the null characters. – sam hocevar May 4 '15 at 23:16
• lol im not pinting them into char array , it is terminal console, and nul character doesnt mean space nor a newline:/ – Abr001am May 4 '15 at 23:39
• You can use this: printf("\n%d"+!!(i%3),i); which is 2 characters shorter. – sam hocevar May 5 '15 at 0:47

If you ever need to output a single newline character (\n), don't use putchar(10), use puts("").