public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/113887] New: no support for %w128 length modifiers
@ 2024-02-12  9:07 jens.gustedt at inria dot fr
  2024-02-12  9:29 ` [Bug c/113887] " jakub at gcc dot gnu.org
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: jens.gustedt at inria dot fr @ 2024-02-12  9:07 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113887

            Bug ID: 113887
           Summary: no support for %w128 length modifiers
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jens.gustedt at inria dot fr
  Target Milestone: ---

With C23 and the %w length modifiers and `_BitInt(128)` literals, it will
finally be possible to have `[u]int128_t` types consistently as type aliases
for all architectures where gcc defines the `__int128` types. I am currently
implementing such a support on musl, but unfortunately the %w128 length
modifiers are diagnosed as being wrong.

```
#include <stdio.h>

int main() {
    unsigned __int128 x = 2;
    printf("%w128x\n", x);
}
```

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c/113887] no support for %w128 length modifiers
  2024-02-12  9:07 [Bug c/113887] New: no support for %w128 length modifiers jens.gustedt at inria dot fr
@ 2024-02-12  9:29 ` jakub at gcc dot gnu.org
  2024-02-12 16:52 ` jsm28 at gcc dot gnu.org
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: jakub at gcc dot gnu.org @ 2024-02-12  9:29 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113887

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org,
                   |                            |jsm28 at gcc dot gnu.org

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
AFAIK glibc doesn't support %w128d etc., it would require full
int128_t/uint128_t support, likely
int_least128_t/uint_least128_t/int_fast128_t/uint_fast128_t,
INT128_WIDTH/UINT128_WIDTH, {,U}INT_{LEAST,FAST}128_WIDTH, INT128_C, UINT128_C,
...

I'm not sure one can use wb/uwb literal suffixes because at least in GCC
_BitInt support is for now x86_64 only (with posted patches for ia32/aarch64)
and in clang the support is without stable ABI, so perhaps if enabled, it would
need to be limited to
__BITINT_MAXWIDTH__ >= 128 targets, because without some __int128 specific
suffixes or
__BITINT_MAXWIDTH__ >= 128 one can't support INT128_C or UINT128_C.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c/113887] no support for %w128 length modifiers
  2024-02-12  9:07 [Bug c/113887] New: no support for %w128 length modifiers jens.gustedt at inria dot fr
  2024-02-12  9:29 ` [Bug c/113887] " jakub at gcc dot gnu.org
@ 2024-02-12 16:52 ` jsm28 at gcc dot gnu.org
  2024-02-12 17:20 ` jens.gustedt at inria dot fr
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: jsm28 at gcc dot gnu.org @ 2024-02-12 16:52 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113887

--- Comment #2 from Joseph S. Myers <jsm28 at gcc dot gnu.org> ---
https://gcc.gnu.org/pipermail/gcc-patches/2024-January/643237.html has my notes
on things that need supporting, in <stdint.h>, <inttypes.h> and by implication
in printf and scanf, to support __int128 as an extended integer type for C23
and thus support int128_t, uint128_t, int_least128_t and uint_least128_t in
<stdint.h>.

I think we *should* add such support in GCC (thus, including GCC's <stdint.h>
for the freestanding case - header changes appropriately conditional on C23
mode) and glibc. Not of course in GCC 14 at the current development stage, as
it's clearly a new feature.

I think it should be done with an integer constant suffix (say i128 / I128 -
potentially confusing if used together with 'i' for complex integers, but not
ambiguous), rather than using wb/uwb together with the hack of making macros
expand to e.g. ((__int128) +123wb) to get the right type (the '+' together with
the cast, to a type name that's interpreted as 0 in the preprocessor, allows
such an expression to work in #if expressions as long as the value is within
the range of intmax_t which is all that's allowed there).

When adding such a feature to glibc we'd need to consider what user-visible
features are appropriate beyond the header changes and printf/scanf support.
That probably includes functions such as strotoi128 / wcstoi128 and the
unsigned and _l versions thereof (using C23 semantics unconditionally for 0b, I
suppose), maybe also i128abs, i128div. The type-generic macros in stdbit.h mean
we don't need extra type-specific functions there.

The default printf/scanf format checking in GCC is effectively for things that
are either standard or in glibc - and w128 is only standard when you have
support for int128_t and all the pieces that go along with that, at least on
the compiler side. (I'm supposing you don't want separate musl_printf format
checking support - although such a thing is possible, we do have separate
ms_printf support for Windows target.)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c/113887] no support for %w128 length modifiers
  2024-02-12  9:07 [Bug c/113887] New: no support for %w128 length modifiers jens.gustedt at inria dot fr
  2024-02-12  9:29 ` [Bug c/113887] " jakub at gcc dot gnu.org
  2024-02-12 16:52 ` jsm28 at gcc dot gnu.org
@ 2024-02-12 17:20 ` jens.gustedt at inria dot fr
  2024-02-13  7:26 ` jens.gustedt at inria dot fr
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: jens.gustedt at inria dot fr @ 2024-02-12 17:20 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113887

--- Comment #3 from Jens Gustedt <jens.gustedt at inria dot fr> ---
(In reply to Jakub Jelinek from comment #1)
> AFAIK glibc doesn't support %w128d etc., it would require full
> int128_t/uint128_t support, likely
> int_least128_t/uint_least128_t/int_fast128_t/uint_fast128_t,
> INT128_WIDTH/UINT128_WIDTH, {,U}INT_{LEAST,FAST}128_WIDTH, INT128_C,
> UINT128_C, ...
> 
> I'm not sure one can use wb/uwb literal suffixes because at least in GCC
> _BitInt support is for now x86_64 only (with posted patches for
> ia32/aarch64) and in clang the support is without stable ABI, so perhaps if
> enabled, it would need to be limited to
> __BITINT_MAXWIDTH__ >= 128 targets, because without some __int128 specific
> suffixes or
> __BITINT_MAXWIDTH__ >= 128 one can't support INT128_C or UINT128_C.

yes, sure, but checking that all planets align to provide int128_t is the task
of the headers, which should be provided by the C library, not the compiler. 

the compiler provides the feature test macros (for the __int128 types and
_BitInt at least for 128 bit) and with that information the library is able to
provide the remaining information in stdint.h and inttypes.h

The question for the %W flag is just not to confuse the user with wrong
information.

to be clear, all of this works with my current patches for musl without
problem, only the diag given by the compiler is wrong.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c/113887] no support for %w128 length modifiers
  2024-02-12  9:07 [Bug c/113887] New: no support for %w128 length modifiers jens.gustedt at inria dot fr
                   ` (2 preceding siblings ...)
  2024-02-12 17:20 ` jens.gustedt at inria dot fr
@ 2024-02-13  7:26 ` jens.gustedt at inria dot fr
  2024-02-13 15:50 ` jsm28 at gcc dot gnu.org
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: jens.gustedt at inria dot fr @ 2024-02-13  7:26 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113887

--- Comment #4 from Jens Gustedt <jens.gustedt at inria dot fr> ---
(In reply to Joseph S. Myers from comment #2)


This is not about the question if the C library supports these types
as `uint128_t`. This is primarily to provide `printf` etc *interface*
support for the builtin type by means of the new C23 specifiers.

C compiler and C library should be independent on this as much as
possible, because all combinations of old/new compile/library should
work without problems. The musl implementation of the length
specifiers does for example not rely any compiler support for the
types. It only uses a convention on how to pass 128 bit types as
`va_arg` and which of the two 64 halves is high and which is low.

For the format checker in the compiler this just asks:

- accept w128 and wf128 specifiers iff the platform supports 128 bit
  integer types
- check if the corresponding argument has such a type

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c/113887] no support for %w128 length modifiers
  2024-02-12  9:07 [Bug c/113887] New: no support for %w128 length modifiers jens.gustedt at inria dot fr
                   ` (3 preceding siblings ...)
  2024-02-13  7:26 ` jens.gustedt at inria dot fr
@ 2024-02-13 15:50 ` jsm28 at gcc dot gnu.org
  2024-02-13 19:43 ` jens.gustedt at inria dot fr
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: jsm28 at gcc dot gnu.org @ 2024-02-13 15:50 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113887

--- Comment #5 from Joseph S. Myers <jsm28 at gcc dot gnu.org> ---
Compiler and library are not in practice independent for this issue. GCC
typically provides <stdint.h> for freestanding compilations and forwards to a
libc version for hosted compilations, and in both cases it needs to know what
the types are for correct format checking (for example, whether int64_t is long
or long long) - and it needs to know that even in files that didn't include
<stdint.h>, and preferably the types should be the same for hosted and
freestanding. In fact it needs to know the types even when not compiling C or
C++ - Fortran ISO_C_BINDING supports those types (though the Fortran standard
has a specific list, not mentioning int128_t or general intN_t). And to
properly support <stdint.h> implementation - whether in GCC's <stdint.h> or one
provided by libc - any int128_t support should come with all the associated
predefined macros - including __INT128_C and __UINT128_C defined to use an
appropriate constant suffix.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c/113887] no support for %w128 length modifiers
  2024-02-12  9:07 [Bug c/113887] New: no support for %w128 length modifiers jens.gustedt at inria dot fr
                   ` (4 preceding siblings ...)
  2024-02-13 15:50 ` jsm28 at gcc dot gnu.org
@ 2024-02-13 19:43 ` jens.gustedt at inria dot fr
  2024-02-13 20:00 ` jens.gustedt at inria dot fr
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: jens.gustedt at inria dot fr @ 2024-02-13 19:43 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113887

--- Comment #6 from Jens Gustedt <jens.gustedt at inria dot fr> ---
(In reply to Joseph S. Myers from comment #5)
> Compiler and library are not in practice independent for this issue ...

For this particular issue they are indeed independent. As said, I have proof of
concept that it works with patches for musl, only gcc is whining because it
doesn't understand the `w128` flag. Otherwise, it is fully functional.

Again, I am not asking that gcc implements full support for the `int128_t` type
alias. I am only asking that `w128` is recognized if and only if the compiler
has `__int128` and if so, does the right diagnosis for the argument type. And
this has nothing to do with free standing, only with hosted environments.

This is not enabling `int128_t` but enabling C libraries to provide `int128_t`
on top of `__int128` if they are able to fill in the gaps.

And indeed, once there is `_BitInt(128)` in the compiler and then the library
provides the `w128` an `wf128` flags, everything is indeed easily filled. For
freestanding which doesn't need <stdio.h> things are even simpler, they only
need `_BitInt(128)` to provide the `.._C` macros if they know that they have
`__int128`.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c/113887] no support for %w128 length modifiers
  2024-02-12  9:07 [Bug c/113887] New: no support for %w128 length modifiers jens.gustedt at inria dot fr
                   ` (5 preceding siblings ...)
  2024-02-13 19:43 ` jens.gustedt at inria dot fr
@ 2024-02-13 20:00 ` jens.gustedt at inria dot fr
  2024-02-13 20:07 ` jakub at gcc dot gnu.org
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: jens.gustedt at inria dot fr @ 2024-02-13 20:00 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113887

--- Comment #7 from Jens Gustedt <jens.gustedt at inria dot fr> ---
(In reply to Joseph S. Myers from comment #5)
> ... including __INT128_C and __UINT128_C
> defined to use an appropriate constant suffix.

You don't need a specific suffix for these types if you have `_BitInt(128)`,
there is no need to invest thoughts or development time in this.
Something like

#define INT128_C(N) ((__int128)+ N ## W)

would do. If 128 is more than `INTMAX_WIDTH` the resulting constants are
exempted by C23 of being suitable for preprocessor arithmetic. But if it is
indeed 128, the expression still is an integer constant expression, even in the
preprocessor.

With that observation you easily also create `MIN` and `MAX` macros

#define INT128_MAX (INT128_C(1) << 126)
#define INT128_MIN (-INT128_MAX - 1)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c/113887] no support for %w128 length modifiers
  2024-02-12  9:07 [Bug c/113887] New: no support for %w128 length modifiers jens.gustedt at inria dot fr
                   ` (6 preceding siblings ...)
  2024-02-13 20:00 ` jens.gustedt at inria dot fr
@ 2024-02-13 20:07 ` jakub at gcc dot gnu.org
  2024-02-13 20:26 ` jens.gustedt at inria dot fr
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: jakub at gcc dot gnu.org @ 2024-02-13 20:07 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113887

--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Jens Gustedt from comment #7)
> (In reply to Joseph S. Myers from comment #5)
> > ... including __INT128_C and __UINT128_C
> > defined to use an appropriate constant suffix.
> 
> You don't need a specific suffix for these types if you have `_BitInt(128)`,
> there is no need to invest thoughts or development time in this.
> Something like
> 
> #define INT128_C(N) ((__int128)+ N ## W)

You mean WB?

> With that observation you easily also create `MIN` and `MAX` macros
> 
> #define INT128_MAX (INT128_C(1) << 126)

That is certainly not the right INT128_MAX.  The right value is
INT128_C (170141183460469231731687303715884105727)
while INT128_C(1) << 126 is just
INT128_C (85070591730234615865843651857942052864).

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c/113887] no support for %w128 length modifiers
  2024-02-12  9:07 [Bug c/113887] New: no support for %w128 length modifiers jens.gustedt at inria dot fr
                   ` (7 preceding siblings ...)
  2024-02-13 20:07 ` jakub at gcc dot gnu.org
@ 2024-02-13 20:26 ` jens.gustedt at inria dot fr
  2024-02-13 20:45 ` jakub at gcc dot gnu.org
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: jens.gustedt at inria dot fr @ 2024-02-13 20:26 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113887

--- Comment #9 from Jens Gustedt <jens.gustedt at inria dot fr> ---
(In reply to Jakub Jelinek from comment #8)

> > #define INT128_C(N) ((__int128)+ N ## W)
> 
> You mean WB?

Yes, probably ;-)

> > With that observation you easily also create `MIN` and `MAX` macros
> > 
> > #define INT128_MAX (INT128_C(1) << 126)
> 
> That is certainly not the right INT128_MAX.

Yes, again, sorry. I should not post these things when I am too tired.

But I hope you get the idea that some form of constant expression with some bit
operations will do the trick.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c/113887] no support for %w128 length modifiers
  2024-02-12  9:07 [Bug c/113887] New: no support for %w128 length modifiers jens.gustedt at inria dot fr
                   ` (8 preceding siblings ...)
  2024-02-13 20:26 ` jens.gustedt at inria dot fr
@ 2024-02-13 20:45 ` jakub at gcc dot gnu.org
  2024-02-13 22:43 ` jsm28 at gcc dot gnu.org
  2024-02-15 14:54 ` jens.gustedt at inria dot fr
  11 siblings, 0 replies; 13+ messages in thread
From: jakub at gcc dot gnu.org @ 2024-02-13 20:45 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113887

--- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
#if 42 == ((__int128) +42wb) && -35 == ((__int128) +-35wb)
#else
#warning warn
#endif

works with both gcc and clang if __BITINT_MAXWIDTH__ >= 128.  That said, for
UINT128_C
it would need to use __uint128_t rather than unsigned __int128, as the latter
doesn't work in preprocessor expressions, as that is interpreted as ((0 0)
+42wb) then.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c/113887] no support for %w128 length modifiers
  2024-02-12  9:07 [Bug c/113887] New: no support for %w128 length modifiers jens.gustedt at inria dot fr
                   ` (9 preceding siblings ...)
  2024-02-13 20:45 ` jakub at gcc dot gnu.org
@ 2024-02-13 22:43 ` jsm28 at gcc dot gnu.org
  2024-02-15 14:54 ` jens.gustedt at inria dot fr
  11 siblings, 0 replies; 13+ messages in thread
From: jsm28 at gcc dot gnu.org @ 2024-02-13 22:43 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113887

--- Comment #11 from Joseph S. Myers <jsm28 at gcc dot gnu.org> ---
As I said in comment#2, I prefer a constant suffix for __int128 to the wb/uwb
hack - I think it's cleaner, as well as allowing int128_t to work properly on
all the targets that support __int128 but have not so far had an ABI for
_BitInt defined, or not had such an ABI implemented in GCC.

(I also think it's time to chase up target maintainers for all the
architectures that don't yet have _BitInt support, which is almost all of them,
inviting them to sort out an ABI definition either locally in GCC, in
conjunction with other implementations or in an actual ABI document, as
appropriate depending on the extent to which GCC for that target tries to
interoperate with other implementations or externally defined ABIs, and then
add the support, but that's a separate matter.)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c/113887] no support for %w128 length modifiers
  2024-02-12  9:07 [Bug c/113887] New: no support for %w128 length modifiers jens.gustedt at inria dot fr
                   ` (10 preceding siblings ...)
  2024-02-13 22:43 ` jsm28 at gcc dot gnu.org
@ 2024-02-15 14:54 ` jens.gustedt at inria dot fr
  11 siblings, 0 replies; 13+ messages in thread
From: jens.gustedt at inria dot fr @ 2024-02-15 14:54 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113887

--- Comment #12 from Jens Gustedt <jens.gustedt at inria dot fr> ---
(In reply to Joseph S. Myers from comment #11)
> As I said in comment#2, I prefer a constant suffix for __int128 to the
> wb/uwb hack - I think it's cleaner, as well as allowing int128_t to work
> properly on all the targets that support __int128 but have not so far had an
> ABI for _BitInt defined, or not had such an ABI implemented in GCC.

Maybe. But that does not have much to do with the very specific question asked
here.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2024-02-15 14:54 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-12  9:07 [Bug c/113887] New: no support for %w128 length modifiers jens.gustedt at inria dot fr
2024-02-12  9:29 ` [Bug c/113887] " jakub at gcc dot gnu.org
2024-02-12 16:52 ` jsm28 at gcc dot gnu.org
2024-02-12 17:20 ` jens.gustedt at inria dot fr
2024-02-13  7:26 ` jens.gustedt at inria dot fr
2024-02-13 15:50 ` jsm28 at gcc dot gnu.org
2024-02-13 19:43 ` jens.gustedt at inria dot fr
2024-02-13 20:00 ` jens.gustedt at inria dot fr
2024-02-13 20:07 ` jakub at gcc dot gnu.org
2024-02-13 20:26 ` jens.gustedt at inria dot fr
2024-02-13 20:45 ` jakub at gcc dot gnu.org
2024-02-13 22:43 ` jsm28 at gcc dot gnu.org
2024-02-15 14:54 ` jens.gustedt at inria dot fr

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).