ian-twilightcoder wrote:

> > Sure, but if you can't include `<assert.h>` from a modular header, then 
> > that basically means `<assert.h>` can't itself be a modular header.
> 
> What do you mean by "modular header" here? The terminology I'm familiar with 
> considers textual headers and modular headers to be mutually exclusive -- 
> modular headers are the ones that don't (intend to) depend on the state of 
> translation at the point at which they're entered, and textual headers are 
> the ones that do. I agree (using that definition) that `<assert.h>` can't (or 
> at least, shouldn't) be a modular header.

We've (Apple) found `textual header`s to be very limited in practice. Basically 
they can't cause a declaration to exist in multiple modules. Swift will see 
those declarations as distinct because the module name is part of the 
type/function name, and as distinct things they're by definition incompatible. 
Sometimes it kind of works out through the type merging that clang does, but 
mostly it doesn't.

What even _should_ happen if modules A and B include <assert.h>, but B defines 
NDEBUG before doing so? If I just import A and B and don't include <assert.h> 
myself, which definition of `assert` do I see?


> The purpose of `textual header` declarations is to associate a header with a 
> module so that it is found and its inclusion is permitted by strict `use` 
> checking rules. (There was an idea that we might also store a pretokenized 
> form of textual headers, but that never actually happened.) We want a `use 
> LibC;` to permit including `assert.h`, and don't want it to be a modular 
> import, so it should be listed as a textual header.

I thought even strict `use` checking rules don't complain about headers that 
aren't covered by any module, it only flags module imports that aren't listed?

> > `<modular_header_that_has_an_assert.h>` doesn't usually start its life as a 
> > modular header, it just has an inline function with an assert in it, and 
> > doesn't expect its behavior to change and start ignoring NDEBUG when it 
> > becomes a modular header. In a single module world, fine `<assert.h>` can 
> > function the same as textual, but when you add in a second world it starts 
> > behaving differently with and without modules.
> 
> I'm not following something here -- I think you're suggesting that you'd see 
> some kind of difference when `<assert.h>` is listed as a textual header 
> versus when it's not listed at all (in a simple world without any `use` 
> checking, I assume). What difference do you have in mind?

I'm trying to say that `<modular_header_that_has_an_assert.h>` doesn't have a 
good way to know that using `assert` will be a bit weird with modules. If 
`<assert.h>` wasn't a modular header (textual or otherwise), then 
`<modular_header_that_has_an_assert.h>` could get a 
`-Wnon-modular-include-in-module` to let it know. Since the owner of 
`<modular_header_that_has_an_assert.h>` probably isn't aware of the subtle 
behavior difference, and probably never really thought about picking up 
`NDEBUG`, it's just what happens to happen in regular C without modules. Wheras 
if `<assert.h>` is textual modular, the behavior changes but it's not obvious.

https://github.com/llvm/llvm-project/pull/165057
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to