Bug 27596 - bits/libc-header-start.h is C++ header-unit unfriendly
Summary: bits/libc-header-start.h is C++ header-unit unfriendly
Status: RESOLVED NOTABUG
Alias: None
Product: glibc
Classification: Unclassified
Component: build (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-03-17 13:35 UTC by Nathan Sidwell
Modified: 2021-03-18 11:35 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nathan Sidwell 2021-03-17 13:35:17 UTC
bits/libc-header-start.h is, IIUC, morally glibc's config.h.  It has protection in it so that it is only included from within glibc:

#ifndef __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
# error "Never include <bits/libc-header-start.h> directly."
#endif

#undef __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION

This makes it unfriendly to being compiled as a stand-alone C++ header unit, unless you add -D__GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION on the command line.  But that does raise some questions:
a) does it ever do more than define/undefine macros?
b) does it ever produce differing sets of macro definitions *within a single (consistent) build*.

#b breaks a header-unit requirement, which would be unfortunate.

We can work around this issue by textually including it, so it is not a header-unit.  But that leads to:

1) inefficencies in building, as now each includer, built as a header unit, will end up providing the macros and the ultimate importer will check all those macro definitions are the same, lazily at the point of expansion.

2) If #b above is true, those sets of definitions/undefinitions could conflict, leading to compilation errors at the point of expansion.  We have not observed this, but we've only done minimal testing right now.
Comment 1 jsm-csl@polyomino.org.uk 2021-03-17 20:36:47 UTC
The handling of __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION is a check 
to discourage external users from using something that's not a public API, 
rather than something strictly required.

bits/libc-header-start.h will produce different macro definitions when 
included with different feature test macros defined.  It's valid for that 
to occur within the compilation of a single translation unit - for one of 
the ISO C feature test macros to be defined after some headers have been 
included and before others are included.  The peculiarities of how those 
ISO C feature test macros are defined are why this header is separate from 
features.h and can't have multiple-include protection.

If the rules that the definitions from a header depend on what feature 
test macros were defined when *that header* is first included (as opposed 
to it being required to define feature test macros before including any 
standard header, as in POSIX) are problematic for C++, that seems like a 
good thing to raise on the C/C++ liaison mailing list.  Or is the issue 
only with the particular approach to implementing that requirement, rather 
than with the requirement itself?
Comment 2 Nathan Sidwell 2021-03-18 11:35:03 UTC
thanks Joseph, Yeah I noticed the lack of #if guarding, but forgot to mention.  This is indeed a 'non-importable header', and must be treated as text on each inclusion.  We'll mark it so in our builds.