[PATCH] D115169: Create a generic ABI document for _BitInt

Aaron Ballman via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 22 12:46:39 PDT 2022


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



More information about the cfe-commits mailing list