Using a generated header file as a dependecy

Someone asked me today about how to use a generated header as a C++ dependency in Bazel, so I figured I’d write up a quick example.

Create a BUILD file with a genrule that generates the header and a cc_library that wraps it, say, foo/BUILD:

genrule(
    name = "header-gen",
    outs = ["my-header.h"],
    # This command would probably actually call whatever tool was generat
    cmd = "echo 'int x();' > $@",
)

cc_library(
    name = "lib",
    hdrs = ["my-header.h"],
    srcs = ["lib.cc"],
    visibility = ["//visibility:public"]
)

Now you can depend on //foo:lib as you would a “normal” cc_library:

cc_binary(
    name = "bin",
    srcs = ["bin.cc"],
    deps = ["//foo:lib"],
)

And bin.cc would look like:

#include "foo/my-header.h"

// ...
int main() {
   x();  // Uses x defined in my-header.h.
}

Smart Pointers and Heirloom Underpants

batman

I’ve seen a lot of descriptions of scoped_ptr and unique_ptr, but often they don’t give clear examples of when to use one vs. the other. Hopefully this will clear things up.

unique_ptr is like an heirloom ring: you might purchase it, have it all your life, and end up being buried with it. For example, something like:

void Human::Life() {
  std::unique_ptr ring(new Ring());
  // Leaving the scope is "dying" and the ring is destroyed
}

However, you could also pass it on to a child. For example:

void Human::Life() {
  std::unique_ptr ring(new Ring());
  // Allocates a new child on the heap that will outlive this
  Kid *kid = CreateChild(this, GetSpouse());
  kid->Inherit(ring.release());
}

Now the parent’s life can end and the ring will survive.

On the other hand, scoped_ptr is more like “my underpants will die with me.” There is no passing them on. The intended use is something like:

void Human::Life() {
  scoped_ptr underpants(new Underpants());
  for (int i = 0; i < 1000; i++) {
      SendToCleaners(underpants.get());
  }
}

You might lend them out, but you retain ownership. Say you try to pass it on anyway with something like:

void Human::Life() {
  scoped_ptr underpants(new Underpants());
  Kid *kid = CreateChild(this, GetSpouse());
  kid->Inherit(underpants.get());
}

At the end of Life(), the underpants will be destroyed and any pointers to them will now point to garbage. Which makes sense, since they’re pointing to a dead guy’s underpants.

Finally, there’s shared_ptr, which is more like your award-winning chili recipe. If you tell a bunch of people about it then you’re sharing ownership of the chili recipe. Eventually all of you will die and the knowledge will be gone but you don’t know who’s going to the big chili pot in the sky in what order, so the data isn’t destroyed until you’re all gone.