stewartmatheson / projectx

0 stars 1 forks source link

Memory header #83

Closed msbit closed 2 years ago

msbit commented 2 years ago

Include memory

Include the memory header for std::shared_ptr which is required for use by gcc (and is probably necessary under other compilers but sneaks in via a transitive include)

stewartmatheson commented 2 years ago

Transitive includes while not knowing what they are called until this point was something I was thinking about the other day. How did you pick this up? Looking at https://stackoverflow.com/questions/56596929/explicit-direct-include-vs-non-contractual-transitive-include and https://softwareengineering.stackexchange.com/questions/379424/detecting-header-inclusion-chains-and-dependencies-in-c it would seem there is no easy way of checking for this.

msbit commented 2 years ago

No magic bullet here, I just saw it when compiling with GCC :) The different include chains that the standard library implementations take is super annoying, I suppose the usual way is to check out compilation with a different one from time to time and address any issues.

The more C/C++ I write the more I've been trying to explicitly #include everything used in any file that uses it; I've started to think of it as "if it has a name in the file, it needs the import". So, while previous me would have thought it a bit verbose, if you have something like:

foo.h

#include <cstdint>  // for uint64_t

struct Foo {
  void Run(uint64_t);
};

foo.cc

#include <cstdint>  // for uint64_t
#include <cstdio>   // for printf

#include "foo.h"

void Foo::Run(uint64_t x) {
  printf("%llu\n", x);
}

I'd nowadays keep both mentions of <cstdint>, and keep the mention of <cstdio> in the implementation file. This matches with the majority sentiment of those SO discussions, I think. It keeps the header mentions as close as possible to their uses, so refactoring should be a bit nicer.

This is much clearer in C code as sometimes the functions are standalone enough that they don't need to know about their "peer" functions in the same file, so they don't include the header file that consumers of the functions would include. This means there isn't really a choice as to where header mentions go, as the files are compiled down to .o files at some point so they need all the definitions in place in the preprocessed C.

I've found that being relatively unfamiliar with the newer C++ stdlib stuff helps with getting the headers right in general; because I have to look them up I just get in a habit of grabbing the declaring header from the documentation. Once I've become more familiar that will likely happen less :)