I’m going to break from my usual style (again) and go for a more ranty style with more blatent product placement.
If you like this kind of content, remember to smash that like button and catch me live over on Twitch. (I’m just kidding, I don’t blog or program live on Twitch, although maybe I should?)
Anyway. C/C++ includes. Love them, hate them, but we’ve all seen (and written) code like this:
// chars.h
#include <string>
int num_chars(const std::string& s);
// words.h
int num_words(const std::string& s);
// main.cpp
#include <chars.h>
#include <words.h>
num_chars(...);
num_words(...);
And everything’s perfect. Years pass. People retire, change groups, interns come and go. And then you add a new file to the codebase:
// fancy_new_file.h
#include <words.h>
num_words(...);
Oops! Compiler error, because words.h
uses but does not include the string
header. Inconvenient, takes time out of your day, have to make a pull request against the words.h
file even though you really weren’t planning on it and your boss wants you to do this other feature preferably yesterday. And sometimes it takes time out of the customer’s day, too.
I have no fix. I have no magic sword I can pull out of a stone and tell you “hey, just do this and you’re good.”
If you can run clang on your codebase, include-what-you-use can fix this problem, at least in some instances.
C++ modules, if you have a sufficiently new compiler, mitigate this issue somewhat (I think it fixes the issue if you use exclusively modules).
Likewise, languages like Python and Rust (and Golang and etc. etc.) solve this problem, by not having these transitive includes. If you need to use something in Rust, you have to import the module, end of story - you won’t accidentally get it for free by including something else.
The moral of today’s story is thus: Language features go beyond just “does it work,” and even a seemingly innocuous and arbitrary change in a language (includes vs. imports) can have even customer-facing consequences.
This blog series updates every week at Programming for Maintainability