Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

printf specifications

1,479 views
Skip to first unread message

jacob navia

unread,
Nov 10, 2011, 11:48:25 AM11/10/11
to
Microsoft has proposed using

%I64d to print a long long.

Lcc-win has adapted this to

%I32d, %I64d, %I128d

or
%I32u, %I64u, %I128u

This specifications would be an addition to the "h" or "l"
(lower case L) specifications

Is there anything planned in this directionby the standards committee?

Thanks in advance for any answers

jacob

tea bag

unread,
Nov 10, 2011, 12:29:59 PM11/10/11
to
jacob navia writes:

> Microsoft has proposed using
>
> %I64d to print a long long.

this would be quite misleading on machines where long long is 128 bits

> Lcc-win has adapted this to
>
> %I32d, %I64d, %I128d
>
> or
> %I32u, %I64u, %I128u

why not aspire to make a solid compiler that adheres to international
standards instead of chasing after every passing butterfly? and why not
make it free software while you're at it?

> This specifications would be an addition to the "h" or "l" (lower case
> L) specifications
>
> Is there anything planned in this directionby the standards committee?
>
> Thanks in advance for any answers

there are already macros in stdint.h to provide format specifiers for
fixedwidth integer types, and standard specifiers for the basic types
like int and long, so what would this add?

Hans-Bernhard Bröker

unread,
Nov 10, 2011, 3:51:08 PM11/10/11
to
On 10.11.2011 17:48, jacob navia wrote:

> Microsoft has proposed using
>
> %I64d to print a long long.

Given that long long has had a perfectly fine, ISO-standard *printf
format length specifier ever since it's been an ISO standard data type
itself, they couldn't have stated much more clearly than by that
"proposal" that they're not intending ever to follow any standard other
than their own.

> Lcc-win has adapted this to
>
> %I32d, %I64d, %I128d

By my book that means it seriously needs to pick better role models to
follow.

Keith Thompson

unread,
Nov 10, 2011, 4:10:17 PM11/10/11
to
Hans-Bernhard Bröker <HBBr...@t-online.de> writes:
> On 10.11.2011 17:48, jacob navia wrote:
>> Microsoft has proposed using
>>
>> %I64d to print a long long.
>
> Given that long long has had a perfectly fine, ISO-standard *printf
> format length specifier ever since it's been an ISO standard data type
> itself, they couldn't have stated much more clearly than by that
> "proposal" that they're not intending ever to follow any standard other
> than their own.

Since long long is at least 64 bits, but needn't be exactly 64 bits,
"%I64d" would be a poor choice.

But if the proposal is to use "%I64d" to print an int64_t, then it's
not a bad idea. It's a lot more convenient than the (IMHO ugly)
macros defined in <inttypes.h>.

On the other hand, it does raise some questions. Suppose that long
and long long are both 64 bits (not uncommon these days). Then would
"%I64d" be expected to work for both types? That would impose
a requirement that currently doesn't exist in the standard, that
integer types of the same size and signedness are interchangeable
as variadic arguments.

I wouldn't mind seeing new formats for the (u)int*_t, (u)intleast*_t,
and (u)intfast*_t types defined in <stdint.h>, just to avoid the
ugliness of the <inttypes.h> format macros. I wouldn't want to see a
requirement that those formats are usable with the predefined types.
(That wouldn't be necessary anyway, since as you point out we
already have perfectly good formats for the predefined types.)

On the other hand, I'm not sure it would be worth the cost of updating
all printf implementations (and making new code quietly fail on older
implementations).

Converting arguments to to (u)intmax_t is another solution.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Antoine Leca

unread,
Nov 11, 2011, 9:37:01 AM11/11/11
to
jacob navia a écrit :
> Microsoft has proposed using
>
> %I64d to print a long long.

That is not quite the way I see it.

Some time ago (around 1993), Microsoft introduced in its compiler a new
integer types named __int64, and support for it (only in the 32-bit
compiler IIRC.) The compiler knew how to parse a 64-bit constant when it
was followed by I64, too. The plan then also contemplated using __int128
(try it, you'll see it is still parsed in nowadays compilers), but AFAIR
there were no implementation for it then -- nor now.

In a first try, there were no support for those new types using
*printf() [it was the time when the use of the "CRT" was not always seen
as the way to go by Microsoft.]
Some years later (sorry, I do not have all the Microsoft compilers at
hand, and the web is not precise enough to crop informations about
16-year old compilers, I assume many people consider it somewhat
obsolete or useless), the CRT was enhanced to allow using %I64d to
format the objects. It was certainly before 1996 though. Around the same
time frame, support was also added for __int8, __int16 and _int32.

_Then_ (NOT before), in 1997-99, the C committee introduced in the C99
standard the long long integer type; note the 1998 C++ standard, which
was aligned to the C90 standard, did not have the long long type then.

Since at the same moment there have been a noticeable delay between
Visual C++ 6.0 (1998, without any support for long long) and the next
version (stabilized around 2003), people which had need to manage and
format 64-bit values learned that with the Microsoft (and Borland)
compilers you had to use the __int64 and %I64, while C99-enhanced tools
preferred using long long and %ll --which was much more successful than
the alternate int64_t and %"PRIi64" solution, also available with C99.
Of course, the reactive people at GCC quickly provided a bridging
solution to continue compiling Windows-targeting programs, in the form
of support of the __int64 data type; yet most programmers learned
(incorrectly) that "long long means 64 bits."

Furthermore, and here this is Microsoft's mistake, while the 2002-2003
"Visual C++ for .NET" (VC++ 7.x or v.12 of the compler) had support for
the long long integer type, the accompanying runtime library (MSVCRT7*)
did not have support for the %ll prefix for *printf formatting; this
'defect' is corrected with the next version, "Visual C++ 2005."

Meanwhile, other products like Mingw or lcc-win relied on a mix: they
provided a compiler which is kept up to date, but for the runtime they
rested on the DLL provided with the operating system by Microsoft; this
makes the deployment tasks much easier, but it also locks the program to
use only the features available with the installed runtime; and for a
long time, until 2005, we saw above that this runtime was based on the
C90 set of features, and did not have support for %lld; this is also
true for the Microsoft-compiled programs linked against the always
available msvcrt.dll (a working solution for the major headaches
produced by the "DLL hell" in the years 1994-1996 by slightly
incompatible versions of distributed runtimes erasing themselves in the
system directory of Windows.)
This boils down that, while the compilers happily support long long (and
this idiom is much used by programmers), printf on Windows happens to be
more picky here, and many programmers learned (again incorrectly) to use
%I64 in order to format a long long value. Particularly sneaky since it
works on all the Windows platforms you can reasonably test on.


However, to come back to your sentence, it is NOT "Microsoft proposal."
Quite the reverse: the regular documentation from Microsoft says that to
format __int32 and __int64 values you have to use %I32 and %I64 prefixes
(and also often remark it as Microsoft extensions); and that (since
2005) to format a long long value you have to use %ll prefix.


What has been proposed IIRC (and defeated IISRC) was to standardise the
use of %I64d --and the rest of the crowd-- to be part of the standard,
with the meaning of PRId64; this would be the same as having "jd" being
effectively the same as PRIdMAX. An objection that might raised is about
some lack of existing practice: Microsoft runtime support is limited to
I32 and I64, it is lacking I8 and I16 prefixes, while the integer types
__int8 and __int16 are supported by the compilers.


Antoine

jacob navia

unread,
Nov 11, 2011, 3:51:34 PM11/11/11
to
Le 10/11/11 21:51, Hans-Bernhard Bröker a écrit :
Sure:

%llld for 128 bit integers?

or

%lllld ?

128 bit integers are very cheap to implement in x86 architectures, or in
64 bit architectures in general. lcc-win implements them, and I wondered
what printf specification should I use.

lcc-win of course accepts the %lld for 64 bit integers (long long) since
it supports C99.

jacob navia

unread,
Nov 11, 2011, 3:55:08 PM11/11/11
to
Le 10/11/11 18:29, tea bag a écrit :
> jacob navia writes:
>
>> Microsoft has proposed using
>>
>> %I64d to print a long long.
>
> this would be quite misleading on machines where long long is 128 bits
>

Yes, but happily there are no such machines.

>> Lcc-win has adapted this to
>>
>> %I32d, %I64d, %I128d
>>
>> or
>> %I32u, %I64u, %I128u
>
> why not aspire to make a solid compiler that adheres to international
> standards instead of chasing after every passing butterfly? and why not
> make it free software while you're at it?
>

Give you my compiler for free? Sure!

And, by the way, why you do not give me US$ 1000
while you are giving everything for free?

I could use that money. Just give it to me OK?

:-)


>> This specifications would be an addition to the "h" or "l" (lower case
>> L) specifications
>>
>> Is there anything planned in this directionby the standards committee?
>>
>> Thanks in advance for any answers
>
> there are already macros in stdint.h to provide format specifiers for
> fixedwidth integer types, and standard specifiers for the basic types
> like int and long, so what would this add?

int128 specifications, the main interest of this.

jacob navia

unread,
Nov 12, 2011, 8:31:36 PM11/12/11
to
Thanks for your detailed explanations Antoine. Actually however, my main
interest would be how to implement int128 support into the compiler.

I support already I64 and I would find it only natural to include
I128 (and probably I256 later).

It is easier to remember as
%lld for I64 or even %lllld for I128...

What would you recommend? Wouldn't it be a good idea to include
int128 support in the next standard? 128 bit integers will be
very useful and more used as 64 bit hardware becomes general.

jacob

Keith Thompson

unread,
Nov 12, 2011, 9:11:13 PM11/12/11
to
Nothing in the current standard forbids 128-bit integers. An
implementation could plausibly have:

char 8 bits
short 16 bits
int 32 bits
long 64 bits
long long 128 bits

though as far as I know no actual compilers do this. But even if
long long is left at 64 bits, you could have an extended integer type
that's 128 bits wide (say, __int128_t), with int128_t as a typedef
for it in <stdint.h> and <inttypes.h> -- and likewise for uint128_t.
The mechanisms are already defined.

Another question is whether to *require* all conforming
implementations to support at least a 128-bit type. I'm inclined
to say no, but I'm not strongly opposed to the idea (apart from
the relative lack of existing practice).

Practically speaking, going from 32 bits to 64 bits gives you a lot
of advantages; there are plenty of things you want to count that
there can be more than 4 billion of (bytes of memory, for example).
There are far fewer things that there are more than 18 quintillion
of. Very wide integer arithmetic is useful for cryptography, but 128
bits isn't enough for that; you need to build arbitrary-precision
arithmetic on top of narrower types, and for that purpose 64 bits
(or even 32 bits) is nearly as good as 128 bits.

[I plonked jacob a while ago, but so far that applies only to
comp.lang.c.]

Antoine Leca

unread,
Nov 14, 2011, 6:50:33 AM11/14/11
to
jacob navia wrote:
> Actually however, my main interest would be how to implement int128
> support into the compiler.

No problem, just do it!
The only point you should take care of is to not forget to adjust up
intmax_t to match (also in the preprocessor.) But other than that, I do
not see any barrier in C99 against it; and there is already much stuff
to make it available portably (INT128_C, INT128_MAX, PRId128, etc.)

Something which might shed some fun, is that UINT128_MAX might be larger
than FLT_MAX, when considered as mathematical values.


> It is easier to remember as %lld for I64

Grrr... Now _this_ is *wrong*. long long is NOT an alias for int64_t.

In fact, to test your implementation, you could build a compiler with
- 32-bit int
- 64-bit long
- 128-bit long long
and then try to compile several open source packages, to see how they
behave... (and of course report the potential bugs you'll undoubtly
unmask to the respective support teams.)
And with such a compiler, %lld will expect... an 128-bit value. ;-)


Antoine

jacob navia

unread,
Nov 14, 2011, 3:28:26 PM11/14/11
to
Le 14/11/11 12:50, Antoine Leca a écrit :
There isn't a single compiler with long long different of 64 bit quantity.

Anyway Antoine, my question was WHAT would you put in there?

I proposed %I128d and %I128u. Is this OK with the committee?
Couldn't we agree that there could be a directive in this sense in
the upcoming standard? I would bet that those integers will
generalize in the years from now till 2020.


Wojtek Lerch

unread,
Nov 14, 2011, 3:37:13 PM11/14/11
to
On 14/11/2011 3:28 PM, jacob navia wrote:
> There isn't a single compiler with long long different of 64 bit quantity.

How can you possibly know that?

How many compilers have you checked?

How many compilers do you think exist?

jacob navia

unread,
Nov 14, 2011, 4:04:33 PM11/14/11
to
Le 14/11/11 21:37, Wojtek Lerch a écrit :
Ahh Mr Lerch

I will check all the compilers in the world ASAP.

In the meantime, since it will take a while, could you please answer my
question actually?

Could the committee agree that %I128d and %I128u are the recommended
printf specs for 128 bit integers?

Or ANY other proposal? I would like to have a standard way of using
those integers in C.

If possible. Thanks

jacob

Keith Thompson

unread,
Nov 14, 2011, 4:08:50 PM11/14/11
to
jacob navia <ja...@spamsink.net> writes:
[...]
> There isn't a single compiler with long long different of 64 bit quantity.

Currently, as far as either of us knows.

But you're talking about a proposed change to the language standard,
which currently requires long long to be *at least* 64 bits and
sets no upper bound.

If you want to make changes that depend on the assumption that long
long is *exactly* 64 bits, you can do so, but any such change should
go along with a new requirement that long long cannot be any wider
than 64 bits.

Personally, I don't think that would be a good idea; extended integer
types and <stdint.h> already provide mechanisms for integers as
wide as any implementation cares to support. But if you want to
change the language to forbid a 128-bit long long type, please say
so explicitly as part of your proposal.

jacob navia

unread,
Nov 14, 2011, 4:15:18 PM11/14/11
to
Le 14/11/11 22:08, Keith Thompson a écrit :
> jacob navia<ja...@spamsink.net> writes:
> [...]
>> There isn't a single compiler with long long different of 64 bit quantity.
>
> Currently, as far as either of us knows.
>
> But you're talking about a proposed change to the language standard,
> which currently requires long long to be *at least* 64 bits and
> sets no upper bound.
>
> If you want to make changes that depend on the assumption that long
> long is *exactly* 64 bits, you can do so, but any such change should
> go along with a new requirement that long long cannot be any wider
> than 64 bits.
>
> Personally, I don't think that would be a good idea; extended integer
> types and<stdint.h> already provide mechanisms for integers as
> wide as any implementation cares to support. But if you want to
> change the language to forbid a 128-bit long long type, please say
> so explicitly as part of your proposal.
>

Can you READ what I am asking instead of starting rants that are
based on your misconceptions?

I would like to know WHAT should be the format used for 128 bit
integers.

Are you proposing %lld? I can't use that since it is taken by
long long.

And NO, I am not proposing limiting long long to 64 bits. You
can leave it like it is now, I do not care really.

The question is (for the nth time)

WHAT format should be used with 128 bit integers?


Wojtek Lerch

unread,
Nov 14, 2011, 4:15:04 PM11/14/11
to
On 14/11/2011 4:04 PM, jacob navia wrote:
> Le 14/11/11 21:37, Wojtek Lerch a écrit :
>> On 14/11/2011 3:28 PM, jacob navia wrote:
>>> There isn't a single compiler with long long different of 64 bit
>>> quantity.
>>
>> How can you possibly know that?
>>
> I will check all the compilers in the world ASAP.

Ah, so you do not actually know it (yet)? You were just bluffing?

> In the meantime, since it will take a while, could you please answer my
> question actually?

The question about the committee? I don't know the answer. I'm not a
member of the committee. Did you make your proposal to the committee,
or just in a newsgroup?

> Could the committee agree that %I128d and %I128u are the recommended
> printf specs for 128 bit integers?

I thought the recommended specifiers are the PRId128 macros. Or would
you want the committe's recommedantion about how to implement them?

> Or ANY other proposal? I would like to have a standard way of using
> those integers in C.

You already do. PRId128.

Richard Kettlewell

unread,
Nov 14, 2011, 4:17:57 PM11/14/11
to
There is already a standard way; "PRId128" etc.

--
http://www.greenend.org.uk/rjk/

jacob navia

unread,
Nov 14, 2011, 4:28:51 PM11/14/11
to
Le 14/11/11 22:17, Richard Kettlewell a écrit :
OK but those are MACROS that should expand to SOMETHING...

But OK, who cares. I will use that and that and that will be it.



Wojtek Lerch

unread,
Nov 14, 2011, 4:39:37 PM11/14/11
to
On 14/11/2011 4:28 PM, jacob navia wrote:
> Le 14/11/11 22:17, Richard Kettlewell a écrit :
>> There is already a standard way; "PRId128" etc.
>
> OK but those are MACROS that should expand to SOMETHING...

Yes, something implementation-specific that programs should not care
about. It's your pick, as an implementor. Making it I128d on your
compiler is fine, as long as you don't expect the committee to force
every other compiler to do the same.

> But OK, who cares. I will use that and that and that will be it.

Precisely.

jacob navia

unread,
Nov 14, 2011, 4:41:10 PM11/14/11
to
Le 14/11/11 22:15, Wojtek Lerch a �crit :
> On 14/11/2011 4:04 PM, jacob navia wrote:
>> Le 14/11/11 21:37, Wojtek Lerch a �crit :
>>> On 14/11/2011 3:28 PM, jacob navia wrote:
>>>> There isn't a single compiler with long long different of 64 bit
>>>> quantity.
>>>
>>> How can you possibly know that?
>>>
>> I will check all the compilers in the world ASAP.
>
> Ah, so you do not actually know it (yet)? You were just bluffing?
>

Of course. Just forget it. You are right,

Let's forget that. I will use %I128d or %I128u and that was it.
And the type will be int128.






Keith Thompson

unread,
Nov 14, 2011, 4:41:21 PM11/14/11
to
It depends on what this 128-bit type is called.

For example, there is no single answer to the question of what
format should be used with 32-bit integers. Even if int and long
are both 32 bits, there's no single format for both of them.

The format for int128_t, if it exists, is the expansion of the macro
PRId128, defined in <inttypes.h>.

If int128_t is a typedef for long long, then PRId128 should expand to
"lld".

If long long is 64 bits, and int128_t is a typedef for some extended
integer type, then PRId128 will probably expand to some
implementation-defined format string. There is currently no definition
in the standard of just what such a format string should look like,
except that it can't conflict with anything else. C99 7.26.9 says:

Lowercase letters may be added to the conversion specifiers and
length modifiers in fprintf and fscanf. Other characters may be
used in extensions.

So "%I128d" would be a reasonable implementation-defined format
for an extended 128-bit integer type, and on such an implementation
PRId128 would likely expand to "I128d".

As you can see, the C99 standard already covers this; there's
no great need to make any changes to the language for printing
128-bit integers.

On the other hand, if you want to change the standard to require
printf itself to recognize format strings for intN_t et al, 7.26.9
suggests that any new standard-defined conversion specifiers and
length modifiers would have to be lowercase letters ("%I128d" is
ok as an extension, but not as a standard-defined format). Such a
feature isn't strictly needed, given the existence of the macros in
<inttypes.h>. But I can see the benefits of it; the <inttypes.h>
macros are frankly ugly. We have "%zu" for size_t, and "%jd"
for intmax_t. New length qualifiers for intN_t could be convenient.

But we'd also want to cover intleastN_t and intfastN_t, and we're
running out of lowercase letters.

If you want to come up with a concrete proposal and post it here,
I'll be glad to take a look at it. But as I said, it would be a
convenience, not something that's strictly necessary.

In an earlier post, you wrote:

Wouldn't it be a good idea to include int128 support in the next
standard?

Can you clarify just what you're proposing? The current standard
already allows for 128-bit integers. Are you proposing to require
intmax_t to be at least 128 bits? Note that this would have the side
effect of requiring all compilers to provide extended integer types,
something that's not currently required.

Wojtek Lerch

unread,
Nov 14, 2011, 4:48:53 PM11/14/11
to
On 14/11/2011 4:41 PM, Keith Thompson wrote:
> If int128_t is a typedef for long long, then PRId128 should expand to
> "lld".

Nitpick: should or could? There's no requirement that it must be a
standard specifier when the type is a standard type, is there?

> If long long is 64 bits, and int128_t is a typedef for some extended
> integer type, then PRId128 will probably expand to some
> implementation-defined format string.

Another nitpick: I couldn't find the place where the standard says
implementation-defined -- are those strings indeed required to be
documented?

Wojtek Lerch

unread,
Nov 14, 2011, 5:13:45 PM11/14/11
to
On 14/11/2011 4:41 PM, jacob navia wrote:
> And the type will be int128.

Shouldn't you pick a name from the namespace reserved for
implementation, such as __int128 or _Int128? And then map it to
int128_t in <stdint.h>?

Keith Thompson

unread,
Nov 14, 2011, 5:53:32 PM11/14/11
to
Wojtek Lerch <wojt...@yahoo.ca> writes:
> On 14/11/2011 4:41 PM, Keith Thompson wrote:
>> If int128_t is a typedef for long long, then PRId128 should expand to
>> "lld".
>
> Nitpick: should or could? There's no requirement that it must be a
> standard specifier when the type is a standard type, is there?

No, there isn't. But if int128_t is long long, I don't see much
point in defining PRId128 as anything other than "lld". On the
other hand, if there's an implementation-defined format for int128_t,
then PRId128 could certainly expand to that.

>> If long long is 64 bits, and int128_t is a typedef for some extended
>> integer type, then PRId128 will probably expand to some
>> implementation-defined format string.
>
> Another nitpick: I couldn't find the place where the standard says
> implementation-defined -- are those strings indeed required to be
> documented?

Ah, good point. If there's an int128_t type, then printf has to be
able to print it (PRId128 has to expand to something that actually
works), but I don't think there's any requirement to document it.
It's unspecified, not implementation-defined (unless we've both
missed something).

Then again, even if the implementation doesn't bother to document it,
it's easy enough to find out what it is:

#ifdef PRId128
printf("PRId128 expands to \"%s\"\n", PRId128);
#else
printf("PRId128 is not defined\n");
#endif

So the distinction between unspecified and implementation-defined isn't
all that critical in this case.

jacob navia

unread,
Nov 14, 2011, 6:07:24 PM11/14/11
to
Le 14/11/11 23:53, Keith Thompson a écrit :
>
> Ah, good point. If there's an int128_t type, then printf has to be
> able to print it (PRId128 has to expand to something that actually
> works), but I don't think there's any requirement to document it.
> It's unspecified, not implementation-defined (unless we've both
> missed something).
>
> Then again, even if the implementation doesn't bother to document it,
> it's easy enough to find out what it is:
>
> #ifdef PRId128
> printf("PRId128 expands to \"%s\"\n", PRId128);
> #else
> printf("PRId128 is not defined\n");
> #endif
>


Well, Mister, have you ever thought about what you wrote there?

Instead of printing it with printf (!!) how about
reading the source code of the header file where that macro is defined???

Ahh ok, too simple.

:-)

It is impossible NOT to document a preprocessor macro.

Anyway... good night

jameskuyper

unread,
Nov 14, 2011, 6:39:01 PM11/14/11
to
jacob navia wrote:
> Le 14/11/11 23:53, Keith Thompson a �crit :
> >
> > Ah, good point. If there's an int128_t type, then printf has to be
> > able to print it (PRId128 has to expand to something that actually
> > works), but I don't think there's any requirement to document it.
> > It's unspecified, not implementation-defined (unless we've both
> > missed something).
> >
> > Then again, even if the implementation doesn't bother to document it,
> > it's easy enough to find out what it is:
> >
> > #ifdef PRId128
> > printf("PRId128 expands to \"%s\"\n", PRId128);
> > #else
> > printf("PRId128 is not defined\n");
> > #endif
> >
>
>
> Well, Mister, have you ever thought about what you wrote there?
>
> Instead of printing it with printf (!!) how about
> reading the source code of the header file where that macro is defined???

There need not be any such file. Even if there is, the macro could
easily be defined in terms of several other macros, each of them
conditionally defined somewhere else. I've had to track down such
things before, and it can be a real pain. The printf() approach
guarantees printing out the actual result after all preprocessing is
complete.

> Ahh ok, too simple.

Except when there is no file named stdint.h stored in any directory
that the user has both the knowledge and permissions to access. In
fact, #include <stdint.h> could cause the required declarations and
definitions to be directly inserted into the implementation's symbol
tables, without involving the actual reading of any human-readable
file.

> It is impossible NOT to document a preprocessor macro.

I'll agree, but only in the sense that the expansion of a macro can
always be printed out, after stringifying it, if necessary (which it
isn't, in this case).

Keith Thompson

unread,
Nov 14, 2011, 7:40:03 PM11/14/11
to
jacob navia <ja...@spamsink.net> writes:
> Le 14/11/11 23:53, Keith Thompson a écrit :
>> Ah, good point. If there's an int128_t type, then printf has to be
>> able to print it (PRId128 has to expand to something that actually
>> works), but I don't think there's any requirement to document it.
>> It's unspecified, not implementation-defined (unless we've both
>> missed something).
>>
>> Then again, even if the implementation doesn't bother to document it,
>> it's easy enough to find out what it is:
>>
>> #ifdef PRId128
>> printf("PRId128 expands to \"%s\"\n", PRId128);
>> #else
>> printf("PRId128 is not defined\n");
>> #endif
>>
>
>
> Well, Mister, have you ever thought about what you wrote there?
>
> Instead of printing it with printf (!!) how about
> reading the source code of the header file where that macro is defined???

Sure, that could work too. Assuming, of course, that the header
file is written in such a way that the string that PRId128 expands
to is obvious to a human reader. It could be the expansion refers
to another macro defined somewhere else, and/or there could be
several alternatives controlled by #ifdef directives -- and the
macros on which it depends might be defined by the compiler, or
on some other header whose identify is determined by the compiler.
Or there might be compiler magic involved:

#define PRId128 __builtin_PRId128

Or the header might not even be a C source file.

In fact, here's the relevant code in /usr/include/inttypes.h for
defining PRId64 (there is no PRId128) on the system I'm currently using:

# if __WORDSIZE == 64
# define __PRI64_PREFIX "l"
...
# else
# define __PRI64_PREFIX "ll"
..
# endif
...
# define PRId64 __PRI64_PREFIX "d"

There is no "#define __WORDSIZE" in that header file. Can you tell me
what PRId64 expands to on my system?

(And that might not even be conforming; C99 7.8.1 requires PRId64 to
expand to "a character string literal". Two character stirng literals
that will be concatenated together in translation phase 6 should be fine
for most purposes, perhaps even all purposes, but I don't think it quite
conforms to what the standard requires.)

> Ahh ok, too simple.
>
> :-)

Apparently not.

Sure, looking at the source of the implementation's <stdint.h>
*might* be a good way to see what PRId128 expands to. But printf
is more reliable.

> It is impossible NOT to document a preprocessor macro.

That's more or less the point I was making. I'm glad you agree.

But of course the Standard requires an implementation to be
"accompanied by a document that defines all implementation-defined
and locale-specific characteristics and all extensions" (C99 4p8).
The expansion of PRId128 needn't be documented in that document
(though it could be).

> Anyway... good night

Richard Kettlewell

unread,
Nov 14, 2011, 7:41:21 PM11/14/11
to
Indeed, just as int128_t would be a typedef that expands to something.

Once you can say what the something is, it may become easier to say what
the SOMETHING is.

--
http://www.greenend.org.uk/rjk/

Keith Thompson

unread,
Nov 14, 2011, 7:45:29 PM11/14/11
to
jameskuyper <james...@gmail.com> writes:
[...]
> Except when there is no file named stdint.h stored in any directory
> that the user has both the knowledge and permissions to access.

Or when there are multiple files by that name, and the compiler uses
some more or less obscure algorithm to determine which one to use.

[...]

Keith Thompson

unread,
Nov 14, 2011, 7:53:54 PM11/14/11
to
Richard Kettlewell <r...@greenend.org.uk> writes:
> jacob navia <ja...@spamsink.net> writes:
>> Richard Kettlewell a écrit :
>>> jacob navia<ja...@spamsink.net> writes:
>>>> Could the committee agree that %I128d and %I128u are the recommended
>>>> printf specs for 128 bit integers?
>>>>
>>>> Or ANY other proposal? I would like to have a standard way of using
>>>> those integers in C.
>>>
>>> There is already a standard way; "PRId128" etc.
>>
>> OK but those are MACROS that should expand to SOMETHING...
>
> Indeed, just as int128_t would be a typedef that expands to something.

Well, typedefs don't *expand* to anything, at least not in the sense
that macros do. They're aliases.

Still, that's a good point; int128_t, if it exists, has to be
a typedef for some existing type, either one of the predefined
integer types (long long if it happens to qualify), or more likely
some implementation-defined extended integer type.

> Once you can say what the something is, it may become easier to say what
> the SOMETHING is.

Right. An implementation can define a 128-bit extended integer type.
Its name would probably be an implementation-defined keyword
that starts with two underscore, or with an underscore and an
uppercase letter. The printf functions can then be extended to
use an implementation-defined length modifier, probably using an
uppercase letter. Once you've done that, you can define int128_t
as a typedef for the extended type, and PRId128 as a macro expanding
to the appropriate string.

If I were writing code to deal with 128-bit integers, I'd probably
declare them as in128_t and print them by converting to intmax_t and
using "%jd". But that's just because I find the <inttypes.h> macros
ugly; implementers still have to define them.

Wojtek Lerch

unread,
Nov 14, 2011, 9:40:52 PM11/14/11
to
On 14/11/2011 5:53 PM, Keith Thompson wrote:
> ... But if int128_t is long long, I don't see much
> point in defining PRId128 as anything other than "lld".

No, probably not, but this is comp.std.c and the difference between
"forbidden" and "pointless" is important...

The best example I can come up with is a system where a compiler switch
selects "long long" to be 64 or 128 bits wide, but the same set of
libraries is used for both cases. System headers define PRId128 and
PRId64 using Jacob's I128d syntax regardless of which of the two matches
the behaviour of lld, because they're more efficient than lld -- with
lld, the library has to go through an extra step of figuring out whether
your program was compiled with 64- or 128-bit long longs.

>>> If long long is 64 bits, and int128_t is a typedef for some extended
>>> integer type, then PRId128 will probably expand to some
>>> implementation-defined format string.
>>
>> Another nitpick: I couldn't find the place where the standard says
>> implementation-defined -- are those strings indeed required to be
>> documented?
...
> Then again, even if the implementation doesn't bother to document it,
> it's easy enough to find out what it is:

Sure, the standard never says that unspecified things must be kept
secret. But keep in mind that they may change when you apply a minor
compiler upgrade, even if the upgrade doesn't come with an errata or a
new set of documentation.

lawrenc...@siemens.com

unread,
Nov 15, 2011, 3:52:20 PM11/15/11
to
jacob navia <ja...@spamsink.net> wrote:
>
> Could the committee agree that %I128d and %I128u are the recommended
> printf specs for 128 bit integers?

No. The committee explicitly decided NOT to require (or even recommend)
any particular format specifiers for extended integer types when we
adopted the macros in <inttypes.h>, just like we decided not to require
or recommend any particular type specifiers for extended types. As an
implementor, you're entitled to use whatever you think is best. Since
there are precedents along those lines, those would be very reasonable
choices, in my opinion.
--
Larry Jones

OK, there IS a middle ground, but it's for sissy weasels. -- Calvin

jacob navia

unread,
Nov 15, 2011, 4:42:41 PM11/15/11
to
Le 15/11/11 21:52, lawrenc...@siemens.com a écrit :
> jacob navia<ja...@spamsink.net> wrote:
>>
>> Could the committee agree that %I128d and %I128u are the recommended
>> printf specs for 128 bit integers?
>
> No. The committee explicitly decided NOT to require (or even recommend)
> any particular format specifiers for extended integer types when we
> adopted the macros in<inttypes.h>, just like we decided not to require
> or recommend any particular type specifiers for extended types. As an
> implementor, you're entitled to use whatever you think is best. Since
> there are precedents along those lines, those would be very reasonable
> choices, in my opinion.

What precedents? I would like to know about them (if possible)

My point is that I would like to give users a portable solution
that wouldn't need much rewrite and would fit into the printf usage
since using the PRxxx macros isn't all that common.


Richard Kettlewell

unread,
Nov 15, 2011, 5:43:44 PM11/15/11
to
Keith Thompson <ks...@mib.org> writes:
> Richard Kettlewell <r...@greenend.org.uk> writes:
>> jacob navia <ja...@spamsink.net> writes:
>>> Richard Kettlewell a écrit :

>>>> There is already a standard way; "PRId128" etc.
>>>
>>> OK but those are MACROS that should expand to SOMETHING...
>>
>> Indeed, just as int128_t would be a typedef that expands to something.
>
> Well, typedefs don't *expand* to anything, at least not in the sense
> that macros do. They're aliases.
>
> Still, that's a good point; int128_t, if it exists, has to be
> a typedef for some existing type, either one of the predefined
> integer types (long long if it happens to qualify), or more likely
> some implementation-defined extended integer type.

Indeed. I don't understand why Jacob is finding this so difficult. The
answer has been right there for over a decade.

>> Once you can say what the something is, it may become easier to say what
>> the SOMETHING is.
>
> Right. An implementation can define a 128-bit extended integer type.
> Its name would probably be an implementation-defined keyword
> that starts with two underscore, or with an underscore and an
> uppercase letter. The printf functions can then be extended to
> use an implementation-defined length modifier, probably using an
> uppercase letter. Once you've done that, you can define int128_t
> as a typedef for the extended type, and PRId128 as a macro expanding
> to the appropriate string.
>
> If I were writing code to deal with 128-bit integers, I'd probably
> declare them as in128_t and print them by converting to intmax_t and
> using "%jd". But that's just because I find the <inttypes.h> macros
> ugly; implementers still have to define them.

Not a bad solution for printf but a bit tedious for scanf.

--
http://www.greenend.org.uk/rjk/

Keith Thompson

unread,
Nov 15, 2011, 7:27:54 PM11/15/11
to
Richard Kettlewell <r...@greenend.org.uk> writes:
> Keith Thompson <ks...@mib.org> writes:
[...]
>> If I were writing code to deal with 128-bit integers, I'd probably
>> declare them as in128_t and print them by converting to intmax_t and
>> using "%jd". But that's just because I find the <inttypes.h> macros
>> ugly; implementers still have to define them.
>
> Not a bad solution for printf but a bit tedious for scanf.

True. I don't use scanf() much myself; the fact that its behavior is
undefined if a numeric input value overflows is more or less a
deal-breaker. (Aside: any chance that can be corrected in a future
standard?)

But you can always read into an intmax_t object and then copy the
result.

lawrenc...@siemens.com

unread,
Nov 15, 2011, 11:27:32 PM11/15/11
to
jacob navia <ja...@spamsink.net> wrote:
> Le 15/11/11 21:52, lawrenc...@siemens.com a ?crit :
> > jacob navia<ja...@spamsink.net> wrote:
> >>
> >> Could the committee agree that %I128d and %I128u are the recommended
> >> printf specs for 128 bit integers?
> >
> > No. The committee explicitly decided NOT to require (or even recommend)
> > any particular format specifiers for extended integer types when we
> > adopted the macros in<inttypes.h>, just like we decided not to require
> > or recommend any particular type specifiers for extended types. As an
> > implementor, you're entitled to use whatever you think is best. Since
> > there are precedents along those lines, those would be very reasonable
> > choices, in my opinion.
>
> What precedents? I would like to know about them (if possible)

According to Wikipedia, %I32d, %I64d, etc. are common on Windows and
they're also parallel to the PRxxx macro names. The extension to 128-bit
is obvious.

> My point is that I would like to give users a portable solution
> that wouldn't need much rewrite and would fit into the printf usage
> since using the PRxxx macros isn't all that common.

It may not be all that common, but it is the officially portable
solution.
--
Larry Jones

There's a connection here, I just know it. -- Calvin
0 new messages