C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Revising #pragma once

From: Thiago Macieira <thiago_at_[hidden]>
Date: Mon, 02 Sep 2024 09:57:38 -0700
On Monday 2 September 2024 05:24:29 GMT-7 Tiago Freire via Std-Proposals
wrote:
> I have given you a detailed explanation of the minimum set of complexity
> that is required of a project to even hit such a problem. And have showed
> you how that minimum set must include doing things that are considered bad
> practice.

Bad practice or not, they exist.

Here's a simple one that has one such bad practice: vendoring content.

I have a project that has two vendored libraries I need, and one of them
vendors the other one to. We can call them libpng and zlib, or oneDNN and
Xbyak, or some other pair.

if, during the compilation of one of my files, both sets of headers are found
by -I options and at least one copy uses #pragma once, my build will fail.

I could solve the problem with this other bad practice: using the vendored
copy's vendored copy of what I need, but that's yet another bad practice. It
might disappear in a new version, or it might have been only recently added.
My project should not need to know what they're using it for or where such
headers are in their sources. Not to mention the location inside the vendored
content can change from version to version too.

Worse, the vendoring of the second project may have patched the first's copy to
only supply what they need, in an attempt to minimise namespace pollution,
meaning I couldn't use it even if I wanted to.

So I have to supply my own copy of the header that I need, which means there
are two files by the same name, supplying mostly or entirely the same content,
but cannot be both included in the same translation unit's compilation. Using
symlinks or hardlinks is not an option, because this project must be compiled
on Windows too.

Now, the correct solution to this is to stop vendoring content. That's what
I've since done to my project in question: I moved all the vendored content's
build to a Docker container and *installed* them system-wide to /usr/local,
with the added benefit of improving my build times (oneDNN and OpenBLAS are not
trivial to build). But this is not an option that will be readily received by
other projects, because vendoring content is too convenient.

And I really don't think the C++ language could afford to mandate it either.

In case it isn't clear: this happened to me. This is a first-person relating of
the problem and no strange filesystems were harmed in the process. Fortunately,
in our case, it broke the build for the developer who attempted to import the
third-party library. He did need to ask me for help because the error messages
weren't clear (I applied my rule of thumb "when the error message makes no
sense, look at the preprocessor output"). I don't remember exactly which
vendored content it was -- I thought it was Xbyak+oneDNN, but their header[1]
has had include guards since "first commit". I may be mis-remembering some
other details too.

[1] https://github.com/herumi/xbyak/blob/master/xbyak/xbyak.h
-- 
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
  Principal Engineer - Intel DCAI Platform & System Engineering

Received on 2024-09-02 16:57:42