Hacker News new | past | comments | ask | show | jobs | submit login

Interesting that it passes/returns structs by value quite a lot which is not usual in C (in my experience.) I assume there's a reason for this? e.g.

static Hero spin(Hero hero, const uint8_t* key)

https://github.com/glouw/littlewolf/blob/339cb5624462d4f2301...




I do so to enforce a single return value from functions.

Given:

    static void damage(const Hero* hero, const Sprite* sprite);
The const can easily dropped later in production from both entities, potentionally creating two return values.

This is analougous to good use of privacy in C++ classes.

    hero = spin(hero, key);
Becomes:

    hero.spin(key);
Where external objects dictate the private state of the hero object.

Pointer aliasing is another thing. Inlining is easier with fewer pointers. A fun C++ experiment is to count your instruction and data cache points with valgrind's cachegrind with pod types both passed by value and by reference (&).


I think it's just for simplicity, since all that copying can't be faster than passing in a reference to it.


You might be surprised. For small structs, copying is very fast and may give you a result with better locality. Passing around structs by pointer means more pointer dereferencing, which has its own overhead and can cause cache misses.

Performance of modern CPUs is very nonobvious.


You are correct. On a much larger project with a similar software engine, if I change all structs I pass by value to pass by reference my instruction count shoots up by 40% according to cachegrind (flto + ofast).

Amazing how powerful pass by value can be when it comes to pod structs.




Applications are open for YC Winter 2021

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: