aaron.ballman added a comment.

In D115169#3808463 <https://reviews.llvm.org/D115169#3808463>, @gustedt wrote:

>>> Also discussing consequences for `va_arg` functions such as `printf` would 
>>> be nice.
>>
>> Does the information in the `Passing and Returning an Object` section 
>> suffice, or are there more details you're looking for there?
>
> The narrow `_BitInt` types are not promoted to `int` for arithmetic.
>
> For the function call ABI we would need to know if the same strategy holds 
> for `va_arg` parameters. For each of these types with representing standard 
> integer type `T` two scenarios would be possible
>
> - When passed to a `va_arg` function the same rules for `T` as an argument 
> for a prototyped function parameter apply.
> - When passed to a `va_arg` function the value is promoted as if it where a 
> `T`, that is in general there is a promotion to `int`.
>
> This has in particular implications to whether or not the `wN` length 
> modifier for `printf` and `scanf` can be used for narrow `_BitInt` types or 
> not: in the first scenario that would not be possible in the second in would 
> be possible without problems.
>
> I would be much in favor of the second choice, `va_arg` functions usually are 
> not made to handle narrow input well.

Thanks for pointing out that the current docs aren't clear enough about the 
varargs case!

My strong preference is for the first choice.

My understanding of WG14 sentiment is that integer and default argument 
promotions are not for new types. It's even spelled out in DR206 
(https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_206.htm): "This was 
intentional because real float promotion to double is in Standard C purely for 
compatibility with K&R. Since complex is new, that compatibility is not an 
issue, and having it behave like real float would introduce undesired overhead 
(and be less like Fortran)." _BitInt is similarly new and there is potential 
for overhead. Also, C2x did not change default argument promotion rules for 
`_Decimal32` or `_Float32`, so `_BitInt` is consistent with the rest of the new 
fundamental types.

What worries me about what you'd like to see changed is that it strengthens the 
guarantees users have in that it's now *well defined* to pass in a `_BitInt(4)` 
at the call site of a variadic parameter, but pull it out as a `_BitInt(32)` 
when default argument promotions happen; we don't want users to be able to rely 
on that guarantee. This is our chance to have an integer type which makes a 
clean break from the K&R C days and given the positive user feedback I've 
received about *not* promoting, I'd want a pretty strong motivation for why 
`_BitInt` should undergo default argument promotions.

My recommendation for library authors who want to supply a `printf` or `scanf` 
implementation is to implement 
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2858.pdf with the caveat that 
WG14 has not formed an official stance on the paper. As C2x is currently 
specified (which could still change due to NB comments), I don't think the `wN` 
format specifier can support bit-precise integers because of the promotion 
behavior (https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2680.pdf). An 
`int8_t` is not the same as a `_BitInt(8)` despite both being eight bits wide.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115169/new/

https://reviews.llvm.org/D115169

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to