C++ headers extension

Some months ago @brecht, @sergey and I made the decision to use the .h extension for C++ header files (instead of .hpp or .hh). I think we should either reconfirm or change that decision.

The reason I’m bringing this up is that I was approached multiple times, because the C++ header files I added to blenlib added confusion and were a bit annoying. The issue is that when writing C code, you were able to include any file with a name like BLI_*.h. Now, you can’t. Since autocompletion and file browsers often only show the file name, you actually have to open the file to see whether you can include it in C code or not.

If I remember correctly, we made that decision, because it is convenient that C and C++ have the same extension, when writing C++ code. This argument works well for header files in e.g. depsgraph/intern/builder/, because there are no C headers in that directory. We did not really think about the fact that this adds inconvenience to writing C code. And since Blender is still mostly C code, it is probably better to make writing C++ code a bit less convenient instead.

Personally, I’m writing more C++ code than C code for Blender currently, so I’m not much affected by the issue. Therefore, it would be good if other developers can share their opinion on the topic. If we just use this thread to confirm our last decision again, that’s fine with me.

We also decided that new C++ files should use the extension .cc (instead of .cpp). However, I don’t feel like we have to discuss that again. Just wanted to mention it here.

CC: @LazyDodo @julianeisel @ideasman42 @sybren


Outcome of the discussion: Use .hh for C++ header files.

1 Like

If we want to keep this functionality in bf_blenlib rather than say a bf_blenlibxx then having there has to be a way to tell from the file name which header can be used in what situation. If the only ways to find out if you can use a certain header is to either manually open it up and look, or try to use it and see if the compiler has an aneurysm we are not doing it right.

However if we decide to keep the C++ headers in blenlib and keep them named .h the minimum we should have is something like this in the C++ based headers

#ifndef __cplusplus
#  error "This header is for C++ only"
#endif

Given the C compiler losing it’s mind on C++ code tends to be on the “chatty” side of things with warnings that at first sight do not make a whole lot of sense.

personally I’d prefer the blenlibxx route, C based code won’t add the include path to it in its CMakeLists.txt , won’t see any includes they can’t use in the code completion in the IDE, and at that point .h vs .hh meh… i’ll go with whoever has a strong opinion there.

I don’t have a strong opinion on whether we should go with blenlibxx, but here are two arguments against it:

  • This might fix the code completion issue in an IDE, but probably does not in every editor. E.g. in my current VS Code setup, I get autocomplete-suggestions for files that are certainly not in the include paths.
  • Should we also have blenkernelxx? We already have a couple of C++ files in blenkernel. So I guess, it is only a matter of time until there are pure C++ headers. Currently, BKE_volume.h is a C and C++ header.

I see more of the code gradually becoming C++ over time. Separating code by language rather than functionality is going to create a mess. I think the current split between intern/ and source/blender is already a problem.

Personally I don’t see these header extensions as a problem to be solved. You indeed have to look at the contents of the files to know if it’s C++ or C, but if you’re writing code using the C++ data structures in those headers you would already know.

It’s mostly about discover-ability, take this scenario: I’m a relatively new dev that is writing some c code and need an array that manages it’s own ram, I don’t know the blender codebase that well, but i have seen a lot of utility stuff starting with bli_* , so odds are, whatever i need it already exists in BLI_*. i add an #include "BLI_ and let the IDE show me what’s available (or just go check what headers are available on the filesystem, whatever floats your boat here)

in the drop down:
BLI_math_bits.h well that’s rubbish, nowhere close to what i’m looking for
BLI_array.h - oh hey, well that’s worth a closer look
BLI_array_cxx.h - cxx in the filename I can blindly ignore this
BLI_vector.h - Oh that sounds hopeful! i hope it’s a vector like type i can use form C, lets take a look NOPE! C++ only…

The files above are from the current blenlib, naming is already a mess and as you say, C++ usage is expected to grow over time, getting some standard naming conventions in place to deal with this is not a bad idea at all.

4 Likes

I agree with @LazyDodo that, regardless of the file’s name, it’s a good idea to have clear & early errors when using C++ headers in C. I also agree that discoverability is important.

When you’re already using code in certain headers and are familiar with the contents of each file, there is no need to put more information in the naming. However, there have been many complaints from many people about the understandability and discoverability of Blender’s source code. Opening files you think may be interesting, only to see that they’re of no use in your situation, is a distraction at best.

The only practical downside I see to naming C++ headers differently, in the light of the code gradually becoming C++, is that it becomes harder to track the history across renames. However, if we pick the naming scheme properly, that’s only one rename per file, max. In my opinion that’s a small price to pay for the advantage in discoverability.

Finally, I like .hh because in Dutch it’s pronounced ‘haha!’ and it makes me laugh.

6 Likes

I’d really like it if we could use a different extension for C++ code, *.hh is fine and avoids the odd instances of *_cxx.h we have.

@sybren I don’t think tracking changes across files over time is such an issue, and we get this with c/cc anyway. Git is quite good at tracking file renames.

1 Like

I prefer .hh/.hpp over .h for C++ headers as well. Especially in directories that contain C and C++ headers.

1 Like

While I didn’t state the reasons I’d prefer differentiating headers, here’s a few.

  • Editors/IDE’s don’t have a way to distinguish between C/C++.
    In some editors these are separate and can have different configurations.
  • Even if we move to most of Blender’s code to C++, there are almost certainly some areas of the code that will remain C-only for years to come, having to remember which headers you can use or not, which might not always be immediately obvious - is worth avoiding.
  • If we ever want to add C headers in the current code base we would end up with *_c.h or have to rename existing files to *_cxx.h.

I’m ok with using .hh extensions for headers if that is preferred by other developers.

1 Like

Thanks everyone, .hh it is. I update the initial post and will update the style guide now.

4 Likes

Is there a serious intention to move most of Blender’s code to C++? If so, perhaps the Blender coding style wiki page should be extended to talk more specifically about what style to follow in C++ code.

1 Like

There are tentative plans, this will be handled on a per-module bases.

I don’t think there is interest to devote time to porting a lot of existing code to C++ at the moment, instead, new areas or development that benefit from using C++ may do so.

1 Like

I have a question about the .h vs .hh thing.
Suppose one has a file that is intended to be included by both C and C++, and can be because it has proper guards based on __cplusplus. I think the name should be .h and not .hh, right?

To hang this question on a concrete case:
I have rewritten my blenlib function for delaunay triangulation in C++. But still want a C interface, for the rest of Blender to use. But also want a C++ interface for other code I am writing to use, so want to expose both the C and the C++ interface. I can see two choices:

  1. put both interfaces in BLI_delaunay_2d.h
  2. put the C interface in BLI_delaunay_2d.h and the C++ one in BLI_delaunay_2d.hh (or some other name ending in .hh)

I would prefer option 1, as it creates less clutter in the blenlib directory, and these interfaces are similar and related.

I also prefer option one. I think the rule should be like this: If it makes sense to include the file in C code, use .h, even if it contains some C++ code.

I also prefer option 1, unless the two interfaces are strictly separated. If C++ code only would need what would be put into the .hh file, and NOT also need the contents of the .h file, then I think separation would make sense. However, in that case the contents are not equivalent, so I’d also rename one of the files beyond the extension to reflect the contents.