AaronBallman wrote:

> Thanks for the explanation, @AaronBallman . I think I am generally deeply 
> confused about what should be provided by the compiler and what should be 
> provided by the C Standard Library on any given platform. From your reply, it 
> looks like there's no clear rule and Clang basically provides anything that 
> seems "easy enough" to provide. I still don't understand how that works in 
> case you do end up including a header from the platform that (re)defines 
> `unreachable`, for example.

For C17 and earlier, the rule was that we provided everything required for 
freestanding by the standard, and anything else the user wanted had to come 
from a library the user supplied. For C23, which we're still in the process of 
implementing, the situation is different and we've not documented what the 
expectations are yet. I suspect we're going to end up requiring the user to 
provide their own freestanding library implementation and the compiler will 
provide only the bits that the compiler has to provide (things like `limits.h`).

The `unreachable` macro is interesting in that it could be provided by either a 
CRT implementation or the compiler. The whole point to the macro is "if the 
expansion is reached, you have undefined behavior", which fits naturally with 
`__builtin_unreachable()` which the backend knows how to do optimizations 
around. However, a CRT implementation could decide the macro expands to `*(int 
*)nullptr` or the likes, which also triggers undefined behavior.

> The same problem also applies today to e.g. `size_t` and anything else 
> provided by the Clang builtin headers. If a platform decides to define 
> `size_t` differently than what the Clang builtin headers define it to, I 
> guess we run into issues? I assume it's not something that happens often 
> because it's pretty unambiguous what these typedefs should be, but still.

If the platform defines `size_t` to be different from the Clang builtin headers 
define it to, there are Serious Problems™ because `sizeof()` suddenly returns 
strange things, interfaces like `printf` will find ABI issues with `%z`, etc.

> Anyway, this might turn out to be nothing more than a documentation issue, 
> but in any case I think it would be valuable to write down how this is 
> intended to work somewhere (even if only in a comment), since I suspect it's 
> not clear to most people. I work on the C++ Standard Library and I don't 
> understand how this works in our own implementation :-)

Definitely agreed that we need to document this, but we need to figure out what 
we want to document in the first place -- some of this is new-ish territory 
because of the additional interfaces. `unreachable` is morally similar to 
`offsetof` in that it's a macro interface where the implementation can give 
better results by expanding to a builtin than a library is likely to be able to 
give via a naive implementation, but the interfaces *can* be provided by a CRT. 
So which one *should* win? Today, if something else defined `offsetof` or 
`unreachable` before including `stddef.h`, Clang's headers won't bother 
re-defining the macro.

I think we may need to look at what existing freestanding CRTs and hosted CRTs 
expect to help give us a path forward?

https://github.com/llvm/llvm-project/pull/86748
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to