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

Defect Report procedures

41 views
Skip to first unread message

Joseph S. Myers

unread,
Mar 22, 2001, 2:58:20 PM3/22/01
to
Sometimes the response to a question on comp.std.c is that a Defect
Report should be submitted concerning an issue with the Standard.
Does this mean that one of the committee members reading comp.std.c
will produce one, or does it mean that the person originally posing
the question needs to submit one?

If the latter, what are the procedures for doing so? (The POSIX
interpretations process has a web form for the submission of
interpretation requests, and public list archives of the
interpretation mailing lists; are such things available for ISO C? I
don't see them on the WG14 web site. Also, sometimes discussions on
"the reflector" are mentioned on comp.std.c; are there public archives
of "the reflector"?)

Cases where "submit a DR" (or something similar suggesting a DR might
be appropriate or that there was a defect in the standard) has been a
response to questions I've posed include:

* Requirements for <stdint.h> to define limits of sig_atomic_t and
wint_t on freestanding implementations.

* Inappropriate reversion of typedef disambiguation wording from C90
TC1 to the original C90 wording in C99.

* Defective fprintf example presuming that wchar_t promotes to wint_t.

* Unintended requirement in C99 that wchar_t cannot be plain char
(said to be a defect, not specifically as something for a DR).

--
Joseph S. Myers
js...@cam.ac.uk

Clive D. W. Feather

unread,
May 18, 2001, 6:10:06 AM5/18/01
to
In article <99dlgs$iuk$1...@pegasus.csx.cam.ac.uk>, Joseph S. Myers
<js...@cam.ac.uk> writes

>Sometimes the response to a question on comp.std.c is that a Defect
>Report should be submitted concerning an issue with the Standard.
>Does this mean that one of the committee members reading comp.std.c
>will produce one, or does it mean that the person originally posing
>the question needs to submit one?

Yes.

[That is, it could be either of these.]

>If the latter, what are the procedures for doing so?

Only a National Body, the Editor, or WG14 itself can submit DRs to WG14
(unless I've misunderstood). Your National Body is BSI group IST/5/-/14,

and Nick Maclaren is a member.

I sometimes pick up issues and put together a DR, but I don't promise to
do so for everything.

>* Requirements for <stdint.h> to define limits of sig_atomic_t and
> wint_t on freestanding implementations.

What's the issue ? That SIG_ATOMIC_MAX is in <stdint.h>, which is
required in freestanding implementations, even though sig_atomic_t is in
<signal.h>, which isn't ?

I could argue that 7.18#4 provides enough wriggle room to allow you to
leave those definitions out.

>* Inappropriate reversion of typedef disambiguation wording from C90
> TC1 to the original C90 wording in C99.

Can you give an example of what you mean and what's wrong with the
present wording ?

>* Defective fprintf example presuming that wchar_t promotes to wint_t.

Hmm.

>* Unintended requirement in C99 that wchar_t cannot be plain char
> (said to be a defect, not specifically as something for a DR).

You're looking at 7.18.3#4 and #5 in making that claim, yes ? I think
you're wrong. If wchar_t is plain char, neither paragraph applies
directly, but the values of WCHAR_MIN and WCHAR_MAX are forced to behave
appropriately by 6.2.5#15. The same issue applies with enumerated types.

--
Clive D.W. Feather, writing for himself | Home: <cl...@davros.org>
Tel: +44 20 8371 1138 (work) | Web: <http://www.davros.org>
Fax: +44 20 8371 4037 (D-fax) | Work: <cl...@demon.net>
Written on my laptop; please observe the Reply-To address

Nick Maclaren

unread,
May 18, 2001, 9:05:55 AM5/18/01
to

In article <gfNKU0h+...@romana.davros.org>,

"Clive D. W. Feather" <cl...@on-the-train.demon.co.uk> writes:
|> In article <99dlgs$iuk$1...@pegasus.csx.cam.ac.uk>, Joseph S. Myers
|> <js...@cam.ac.uk> writes
|> >Sometimes the response to a question on comp.std.c is that a Defect
|> >Report should be submitted concerning an issue with the Standard.
|> >Does this mean that one of the committee members reading comp.std.c
|> >will produce one, or does it mean that the person originally posing
|> >the question needs to submit one?
|>
|> Yes.
|>
|> [That is, it could be either of these.]
|>
|> >If the latter, what are the procedures for doing so?
|>
|> Only a National Body, the Editor, or WG14 itself can submit DRs to WG14
|> (unless I've misunderstood). Your National Body is BSI group IST/5/-/14,
|>
|> and Nick Maclaren is a member.

Heaven help me. I have never written a DR, though I could easily
turn many of my Public Comment Period comments into them. I have
wondered whether to kick off 100 or so, largely to make a political
point, but don't think that it would achieve anything useful.

|> I sometimes pick up issues and put together a DR, but I don't promise to
|> do so for everything.

The trouble is that the DR mechanism is really intended for flaws
of detail, whereas the things that I would really like to see
addressed are those of concept, structure and design.


Regards,
Nick Maclaren,
University of Cambridge Computing Service,
New Museums Site, Pembroke Street, Cambridge CB2 3QG, England.
Email: nm...@cam.ac.uk
Tel.: +44 1223 334761 Fax: +44 1223 334679

Greg Comeau

unread,
May 18, 2001, 9:56:43 AM5/18/01
to
In article <9e36nj$84e$1...@pegasus.csx.cam.ac.uk>,

Nick Maclaren <nm...@cus.cam.ac.uk> wrote:
>In article <gfNKU0h+...@romana.davros.org>,
>"Clive D. W. Feather" <cl...@on-the-train.demon.co.uk> writes:
>|> In article <99dlgs$iuk$1...@pegasus.csx.cam.ac.uk>, Joseph S. Myers
>|> <js...@cam.ac.uk> writes
>|> >Sometimes the response to a question on comp.std.c is that a Defect
>|> >Report should be submitted concerning an issue with the Standard.
>|> >Does this mean that one of the committee members reading comp.std.c
>|> >will produce one, or does it mean that the person originally posing
>|> >the question needs to submit one?
>|>
>|> Yes.
>|>
>|> [That is, it could be either of these.]
>|>
>|> >If the latter, what are the procedures for doing so?
>|>
>|> Only a National Body, the Editor, or WG14 itself can submit DRs to WG14
>|> (unless I've misunderstood). Your National Body is BSI group IST/5/-/14,
>|>
>|> and Nick Maclaren is a member.
>
>Heaven help me. I have never written a DR, though I could easily
>turn many of my Public Comment Period comments into them.

I'm confused then. Didn't you say that you submitted something to
the committee about when array parameters bounds stuff occurs?
I guess you did it after DR processing?

>I have
>wondered whether to kick off 100 or so, largely to make a political
>point, but don't think that it would achieve anything useful.

No, but it you really have 100, I bet at least 1 is technically
sound enough to warrant consideration. Go for it.

>|> I sometimes pick up issues and put together a DR, but I don't promise to
>|> do so for everything.
>
>The trouble is that the DR mechanism is really intended for flaws
>of detail, whereas the things that I would really like to see
>addressed are those of concept, structure and design.

I've come to realize that the DR mechanism is for whatever you want
it to mean, although it often does focus on what you say. As above,
new ideas can be important, so you should whittle the "best of"
what you think is important, and present it. Of course, it may
have had a better shot when revision was being focused on.
(Note: I'm not suggesting everybody should go an submit every
preferred pet feature to the committee.)
--
Greg Comeau Comeau C/C++ 4.2.45.2
ONLINE COMPILER ==> http://www.comeaucomputing.com/tryitout
NEW: Try out libcomo! NEW: Try out our C99 mode!
com...@comeaucomputing.com http://www.comeaucomputing.com

Nick Maclaren

unread,
May 18, 2001, 10:06:55 AM5/18/01
to

In article <9e39mr$eeb$1...@panix3.panix.com>,

com...@panix.com (Greg Comeau) writes:
|> In article <9e36nj$84e$1...@pegasus.csx.cam.ac.uk>,
|> Nick Maclaren <nm...@cus.cam.ac.uk> wrote:
|> >
|> >Heaven help me. I have never written a DR, though I could easily
|> >turn many of my Public Comment Period comments into them.
|>
|> I'm confused then. Didn't you say that you submitted something to
|> the committee about when array parameters bounds stuff occurs?
|> I guess you did it after DR processing?

A Public Comment Period comment, actually included in National
Body comments.

|> >I have
|> >wondered whether to kick off 100 or so, largely to make a political
|> >point, but don't think that it would achieve anything useful.
|>
|> No, but it you really have 100, I bet at least 1 is technically
|> sound enough to warrant consideration. Go for it.

It takes time. I have little enough of that, and have rather
given up on the hope of serious progress.

Seriously, I believe that there is little point in wasting much
effort on trying to fix details when the causes are much deeper.
It never works.

Joseph S. Myers

unread,
May 18, 2001, 10:08:48 AM5/18/01
to
In article <gfNKU0h+...@romana.davros.org>,

Clive D. W. Feather <cl...@davros.org> wrote:
>Only a National Body, the Editor, or WG14 itself can submit DRs to WG14
>(unless I've misunderstood). Your National Body is BSI group IST/5/-/14,

Searching www.bsi-global.com for either IST/5/-/14 or "defect report"
reveals nothing. The lists on www.iso.ch do not mention this part of
BSI. The links "your" or "member body" from the WG14 web site do not
seem to lead to a mention of this part of BSI. How is this
information meant to be accessible? Could any members of IST/5/-/14
reading this get BSI to make the existence and contact details of
IST/5/-/14, and something to do with defect reports, more accessible
from their web site given the obvious search terms?

I might as well as again: what is "the reflector"? Is this documented
anywhere public? Is subscription to it open? Are there archives of
it? If there are archives, are they public; if so, where are they?
If archives or subscription are not open, who has access to them?

>What's the issue ? That SIG_ATOMIC_MAX is in <stdint.h>, which is
>required in freestanding implementations, even though sig_atomic_t is in
><signal.h>, which isn't ?

Yes.

>I could argue that 7.18#4 provides enough wriggle room to allow you to
>leave those definitions out.

However, 7.18#4 says that <stdint.h> declares the typedef name, which
doesn't seem to be intended for sig_atomic_t - so I think 7.18#4 is
only meant to apply for the int*_t and uint*_t types.

Previous thread:
http://groups.google.com/groups?hl=en&lr=&safe=off&ic=1&th=55ae9e493cab4476,14

>>* Inappropriate reversion of typedef disambiguation wording from C90
>> TC1 to the original C90 wording in C99.
>
>Can you give an example of what you mean and what's wrong with the
>present wording ?

The change in TC1, apparently in response to DR#009, of (6.5.4.3)

In a parameter declaration, a single typedef name in parentheses
is taken to be an abstract declarator that specifies a function
with a single parameter, not as redundant parentheses around the
identifier for a declarator.

to

If, in a parameter declaration, an identifier can be treated as a
typedef name or as a parameter name, it shall be taken as a
typedef name.

which reverted in C99 to the unmodified C90 wording.

I can't find the thread in Google. I think the only response was:

Newsgroups: comp.std.c
From: "Douglas A. Gwyn" <gw...@arl.army.mil>
Subject: Re: typedef disambiguation
Message-ID: <3A01AF7F...@arl.army.mil>
Date: Thu, 2 Nov 2000 18:16:31 GMT

"Joseph S. Myers" wrote:
> In C99, the first has gone, presumably no longer needed because of the
> removal of implicit int, and the second has reverted to the unamended
> C90 wording. How does C99 disambiguate the cases for which the TC1
> change was made?

TC1 wasn't a change in intent, just clarification of the intent.
The intent is the same for C99. I don't know how the words got
lost, but they ought to be restored. This merits a DR against C99.

As far as I can tell, the example from DR#009 still applies.

>>* Defective fprintf example presuming that wchar_t promotes to wint_t.
>
>Hmm.

That is, the example at the bottom of page 280 of C99 has undefined
behavior.

Previous thread:
http://groups.google.com/groups?hl=en&lr=&safe=off&ic=1&th=269c86cde08c9f30,2

>>* Unintended requirement in C99 that wchar_t cannot be plain char
>> (said to be a defect, not specifically as something for a DR).
>
>You're looking at 7.18.3#4 and #5 in making that claim, yes ? I think
>you're wrong. If wchar_t is plain char, neither paragraph applies
>directly, but the values of WCHAR_MIN and WCHAR_MAX are forced to behave
>appropriately by 6.2.5#15. The same issue applies with enumerated types.

7.18.3#4 says "If wchar_t (see 7.17) is defined as a signed integer
type, [...], otherwise, wchar_t is defined as an unsigned integer type
[...].". That seems plainly enough to require that wchar_t be a
signed or unsigned integer type.

Previous thread:
http://groups.google.com/groups?hl=en&lr=&safe=off&ic=1&th=dd832032ca0c41e2,2

Douglas A. Gwyn

unread,
May 18, 2001, 12:08:39 PM5/18/01
to
"Joseph S. Myers" wrote:
> However, 7.18#4 says that <stdint.h> declares the typedef name, which
> doesn't seem to be intended for sig_atomic_t - so I think 7.18#4 is
> only meant to apply for the int*_t and uint*_t types.

Right; <stdint.h> does not define sig_atomic_t nor wint_t. 7.18
(introductory subclause) says what types are defined, and 7.18.3 says
that the types referred to there are "defined in other headers".

You are correct in identifying an issue here; these types are in fact
*not* defined in other headers in a freestanding implementation, but
clause 4 requires <stdint.h> to be provided in such an implementation.
Various ways to fix this suggest themselves, but this is very suitable
for submission as a Defect Report so that we can use the established
process to arrive at a solution.

> The change in TC1, apparently in response to DR#009, of (6.5.4.3)
> In a parameter declaration, a single typedef name in parentheses
> is taken to be an abstract declarator that specifies a function
> with a single parameter, not as redundant parentheses around the
> identifier for a declarator.
> to
> If, in a parameter declaration, an identifier can be treated as a
> typedef name or as a parameter name, it shall be taken as a
> typedef name.
> which reverted in C99 to the unmodified C90 wording.

In C99 it's 6.7.5.3 paragraph 11. Unless there was a specific vote
to change the wording back, which I don't recall, then this must be
an error in editing the previous standard document source into C99
(through a succession of stages). I thought that it had been
reviewed for incorporation of AM1, TC1, etc. but somehow that one
escaped our notice. Correcting it would, in my opinion, be a purely
editorial matter. However, a Defect Report is needed to initiate
the correction process. (As I said before, which you cited.)

> >>* Defective fprintf example presuming that wchar_t promotes to wint_t.
> >Hmm.
> That is, the example at the bottom of page 280 of C99 has undefined
> behavior.

It's worse than that; the spec for the c conversion specifier needs
more work. E.g., where does the wint_t come from? It's not
necessarily compatible with one of the types resulting from the
default argument promotions. This certainly needs a Defect Report.

> 7.18.3#4 says "If wchar_t (see 7.17) is defined as a signed integer
> type, [...], otherwise, wchar_t is defined as an unsigned integer type
> [...].". That seems plainly enough to require that wchar_t be a
> signed or unsigned integer type.

As far as I recall, that is intentional. There seems to be no
advantage to be gained by an implementation not picking one or
the other. After all, "plain" char really is one or the other,
although we included weasel words to keep its signedness
unspecified due to having to support existing practice for
8-bit character encoding. For wchar_t, there is no such
constraint, so we can require a crisper specification.

Joseph S. Myers

unread,
May 18, 2001, 2:27:42 PM5/18/01
to
In article <3B054907...@null.net>,

Douglas A. Gwyn <DAG...@null.net> wrote:
>It's worse than that; the spec for the c conversion specifier needs
>more work. E.g., where does the wint_t come from? It's not
>necessarily compatible with one of the types resulting from the
>default argument promotions. This certainly needs a Defect Report.

wint_t is "an integer type unchanged by default argument promotions"
(7.24.1#2). But a conforming implementation may have e.g. wchar_t
being "long int" and wint_t being "unsigned int" - which happen to be
the types used on x86 GNU/Linux.

However, I don't see any requirement for size_t, ptrdiff_t or intmax_t
to be unchanged by default argument promotions. The only significance
of this is probably that s.c. code can't pass them to va_arg, so
printf can't be implemented in s.c. code.

Douglas A. Gwyn

unread,
May 18, 2001, 2:26:47 PM5/18/01
to
I forgot to mention:

I thought at a previous WG14 meeting, a member promised
to monitor this newsgroup for suitable issues for DRs
and to submit such DRs. If this turned out to be too
much work, I certainly understand, but if in fact this
is being done, it would be useful to hear a confirmation.

DRs that reach the Committee through other than national
bodies can be registered (requiring our response) at the
discretion of the Convenor; while I'm not speaking
officially for the Committee here, I'm sure that we do
want to resolve serious practical issues. I'm also sure
that we do not want to spend our limited resources dealing
with issues that have no practical import; thus, some
infelicities of wording we can simply choose to live with.

Douglas A. Gwyn

unread,
May 18, 2001, 3:07:21 PM5/18/01
to
"Joseph S. Myers" wrote:
> wint_t is "an integer type unchanged by default argument promotions"
> (7.24.1#2).

Thanks; I had forgotten that.

> But a conforming implementation may have e.g. wchar_t being "long int"

> and wint_t being "unsigned int" ...

Only if they meet all requirements.. Since a wint_t has to be
capable of representing all relevant wchar_t values, I don't think
that is a problem.

> However, I don't see any requirement for size_t, ptrdiff_t
> or intmax_t to be unchanged by default argument promotions.

Drat, I don't recall adding the j, z, t specifiers.
So what I previously said about lc applies instead to these.

Clive D. W. Feather

unread,
May 23, 2001, 9:42:15 PM5/23/01
to
In article <9e3adg$83m$1...@pegasus.csx.cam.ac.uk>, Joseph S. Myers
<js...@cam.ac.uk> writes

>>What's the issue ? That SIG_ATOMIC_MAX is in <stdint.h>, which is
>>required in freestanding implementations, even though sig_atomic_t is in
>><signal.h>, which isn't ?
>
>Yes.

That's already on my list of DRs-to-write.

>>I could argue that 7.18#4 provides enough wriggle room to allow you to
>>leave those definitions out.
>
>However, 7.18#4 says that <stdint.h> declares the typedef name, which
>doesn't seem to be intended for sig_atomic_t - so I think 7.18#4 is
>only meant to apply for the int*_t and uint*_t types.

Probably. Hence "wriggle room" rather than an assertion.

>>>* Defective fprintf example presuming that wchar_t promotes to wint_t.
>>
>>Hmm.
>
>That is, the example at the bottom of page 280 of C99 has undefined
>behavior.

Yes. Hence "Hmm".

>>>* Unintended requirement in C99 that wchar_t cannot be plain char
>>> (said to be a defect, not specifically as something for a DR).

[...]
>7.18.3#4 says

Yes, I misread that.

I would take the view that 6.2.5#15 covers this. I seem to recall that a
previous DR response addressed this generic situation (not wchar_t in
particular).

Clive D. W. Feather

unread,
May 23, 2001, 9:45:19 PM5/23/01
to
In article <3B056967...@null.net>, Douglas A. Gwyn
<DAG...@null.net> writes

>I forgot to mention:
>
>I thought at a previous WG14 meeting, a member promised
>to monitor this newsgroup for suitable issues for DRs
>and to submit such DRs.

Me.

>If this turned out to be too
>much work, I certainly understand,

Not quite, but it's very low priority. Given the speed of the DR
process, this doesn't greatly worry me.

>DRs that reach the Committee through other than national
>bodies can be registered (requiring our response) at the
>discretion of the Convenor;

and I'll agree that this has happened. Equally, I have a batch sitting
somewhere in IST/5/-/14 that I ought to kick into life again.

Clive D. W. Feather

unread,
May 23, 2001, 9:52:35 PM5/23/01
to
In article <9e3piu$siv$1...@pegasus.csx.cam.ac.uk>, Joseph S. Myers
<js...@cam.ac.uk> writes

>However, I don't see any requirement for size_t, ptrdiff_t or intmax_t
>to be unchanged by default argument promotions.

intmax_t is unchanged by default argument promotions (because its
conversion rank is at least that of int).

>The only significance
>of this is probably that s.c. code can't pass them to va_arg, so
>printf can't be implemented in s.c. code.

Not true. If they are not unchanged, then they will be promoted.
Promotion does not change the value. What it means is that printf needs
to cast the value back to size_t or ptrdiff_t before printing the value.

I admit that the descriptions of z and t don't contain the parenthetical
remarks that h and hh do, but I believe that the concept still applies.

Clive D. W. Feather

unread,
May 23, 2001, 9:36:12 PM5/23/01
to
In article <9e3adg$83m$1...@pegasus.csx.cam.ac.uk>, Joseph S. Myers
<js...@cam.ac.uk> writes

>>Only a National Body, the Editor, or WG14 itself can submit DRs to WG14
>>(unless I've misunderstood). Your National Body is BSI group IST/5/-/14,
>
>Searching www.bsi-global.com for either IST/5/-/14 or "defect report"
>reveals nothing. The lists on www.iso.ch do not mention this part of
>BSI. The links "your" or "member body" from the WG14 web site do not
>seem to lead to a mention of this part of BSI. How is this
>information meant to be accessible?

I can't answer that, I'm afraid. If you contacted BSI and said "who
deals with C and ISO/IEC 9899", they should be able to give you a
pointer. I don't run the WG14 web site, and I'm currently somewhere
where I can't even look at it.

>I might as well as again: what is "the reflector"?

This is the mailing list for members of WG14.

>Is this documented
>anywhere public?

Probably not.

>Is subscription to it open?

I *think* you have to be sponsored by someone (in the UK, the IST/5/-/14
mailing list is subscribed to the WG14 reflector). Larry ? Doug ?

>Are there archives of
>it? If there are archives, are they public; if so, where are they?
>If archives or subscription are not open, who has access to them?

I have a personal archive, but I'm not sure if there's a proper one at
all, let alone a public one.

Joseph S. Myers

unread,
May 24, 2001, 4:17:08 AM5/24/01
to
In article <BKTyBpYj...@romana.davros.org>,

Clive D. W. Feather <cl...@davros.org> wrote:
>intmax_t is unchanged by default argument promotions (because its
>conversion rank is at least that of int).

Where is it specified that its integer conversion rank is at least
that of int?

>>The only significance
>>of this is probably that s.c. code can't pass them to va_arg, so
>>printf can't be implemented in s.c. code.
>
>Not true. If they are not unchanged, then they will be promoted.
>Promotion does not change the value. What it means is that printf needs
>to cast the value back to size_t or ptrdiff_t before printing the value.

I meant that s.c. code cannot pass the type names size_t or ptrdiff_t
to va_arg; the code would need to know what the promoted type is.

Nick Maclaren

unread,
May 24, 2001, 4:38:10 AM5/24/01
to
In article <9eig24$lpt$1...@pegasus.csx.cam.ac.uk>,

Joseph S. Myers <js...@cam.ac.uk> wrote:
>In article <BKTyBpYj...@romana.davros.org>,
>Clive D. W. Feather <cl...@davros.org> wrote:
>>intmax_t is unchanged by default argument promotions (because its
>>conversion rank is at least that of int).
>
>Where is it specified that its integer conversion rank is at least
>that of int?

Gug. That sounds a good topic for a DR - editorial, too :-)

>>>The only significance
>>>of this is probably that s.c. code can't pass them to va_arg, so
>>>printf can't be implemented in s.c. code.
>>
>>Not true. If they are not unchanged, then they will be promoted.
>>Promotion does not change the value. What it means is that printf needs
>>to cast the value back to size_t or ptrdiff_t before printing the value.
>
>I meant that s.c. code cannot pass the type names size_t or ptrdiff_t
>to va_arg; the code would need to know what the promoted type is.

Yes. As the specification stands. It could probably be enhanced
to handle that case, but would be messy.

Clive D. W. Feather

unread,
May 24, 2001, 9:11:55 AM5/24/01
to
In article <9eig24$lpt$1...@pegasus.csx.cam.ac.uk>, Joseph S. Myers
<js...@cam.ac.uk> writes

>>intmax_t is unchanged by default argument promotions (because its
>>conversion rank is at least that of int).
>
>Where is it specified that its integer conversion rank is at least
>that of int?

The rank of intmax_t is greater than that of any type with less
precision (6.3.1.1). From 7.18.1.5 we know that intmax_t can represent
the values that any other signed type can, and from 6.2.6.2 we know this
means it must have a precision no less than any other signed integer
type. So either:
- the precision of intmax_t is greater than that of int, in which case
the rank is greater, or
- intmax_t and int have the same precision.
In this case, either
- intmax_t is one of int, long int, or long long int, in which case its
rank is at least that of int, or
- intmax_t is an extended integer type, in which case, yes, its rank
will be less than that of int.

So, yes, it *is* possible to have a system where all of intmax_t, int,
long int, and long long int are the same size (e.g. 64 bits) and where
the rank of intmax_t is less than that of int. Of course, in this
situation the integer promotions do nothing to intmax_t, but it is
technically an issue.

The fix would be to require the conversion rank of intmax_t to be not
less than that of long long int (might as well do it properly); this
means that intmax_t either *is* long long int or is strictly bigger than
it.

>>Not true. If they are not unchanged, then they will be promoted.
>>Promotion does not change the value. What it means is that printf needs
>>to cast the value back to size_t or ptrdiff_t before printing the value.
>I meant that s.c. code cannot pass the type names size_t or ptrdiff_t
>to va_arg; the code would need to know what the promoted type is.

Good point.

Unfortunately, I can't see any way to fix this without a language
change. [While we're doing it, we should make it possible to get the
unsigned type corresponding to a signed type, and vice versa.] And such
a change is *not* something a DR can handle.

Nick Maclaren

unread,
May 25, 2001, 4:16:29 AM5/25/01
to
In article <9UddmG7b...@romana.davros.org>,

Clive D. W. Feather <cl...@davros.org> wrote:

Strictly, no. What if int was 32 value/sign bits followed by 32 padding
bits, and intmax_t was the other way round?

Fixing this is pretty well an editorial matter, as I can't see any
ambiguity in the intent.

Joseph S. Myers

unread,
May 25, 2001, 4:20:19 AM5/25/01
to
In article <9UddmG7b...@romana.davros.org>,

Clive D. W. Feather <cl...@davros.org> wrote:
>The fix would be to require the conversion rank of intmax_t to be not
>less than that of long long int (might as well do it properly); this
>means that intmax_t either *is* long long int or is strictly bigger than
>it.

I don't see any advantage in requiring the rank to be at least that of
long long int, over simply requiring it to be at least that of int,
and existing implementations that use long int as the type of intmax_t
on systems where both are 64-bit would be affected by such a change.

Nick Maclaren

unread,
May 25, 2001, 4:36:09 AM5/25/01
to
In article <9el4k3$lgb$1...@pegasus.csx.cam.ac.uk>,

We lost that one when 'long long' was perpetrated. Allowing the
ranking to be int < long < intmax_t < long long merely moves the mess
around. If intmax_t has ANY function, it is to be the longest standard
integer type.

Douglas A. Gwyn

unread,
May 25, 2001, 9:57:14 AM5/25/01
to
Nick Maclaren wrote:
> We lost that one when 'long long' was perpetrated. Allowing the
> ranking to be int < long < intmax_t < long long merely moves the mess
> around. If intmax_t has ANY function, it is to be the longest standard
> integer type.

I agree. intmax_t has to be at the "high end" of all supported
integer types; that is its *only* function.

Joseph S. Myers

unread,
May 25, 2001, 10:36:04 AM5/25/01
to
In article <9el5hp$n6o$1...@pegasus.csx.cam.ac.uk>,

Nick Maclaren <nm...@cus.cam.ac.uk> wrote:
>We lost that one when 'long long' was perpetrated. Allowing the
>ranking to be int < long < intmax_t < long long merely moves the mess
>around. If intmax_t has ANY function, it is to be the longest standard
>integer type.

But, given that intmax_t is the longest type, and that all of long,
long long and intmax_t are 64 bits, what is the benefit of a further
requirement that intmax_t must be long long rather than long or an
extended integer type of the same width? When the types are of the
same width, I don't think the exact ranks even make any difference to
the value of expressions under the usual arithmetic conversion (where
the ranks are used), or to whether they are signed or unsigned.

Nick Maclaren

unread,
May 25, 2001, 10:46:38 AM5/25/01
to

Whether or not there is any actual benefit, NOT making it the greatest
rank is producing a hostage to fortune. In particular, it makes it
more likely that some other change in the standard will make the
difference visible.

Joseph S. Myers

unread,
Jun 3, 2001, 10:04:05 AM6/3/01
to
In article <i5oK9rVM...@romana.davros.org>,

Clive D. W. Feather <cl...@davros.org> wrote:
[the reflector]

>I *think* you have to be sponsored by someone (in the UK, the IST/5/-/14
>mailing list is subscribed to the WG14 reflector). Larry ? Doug ?

So, who can sponsor subscription to the reflector, or how can one
subscribe to the IST/5/-/14 mailing list?

Chris Hills

unread,
Jun 3, 2001, 1:46:10 PM6/3/01
to

AFAIK I do :-)

Joseph S. Myers <js...@cam.ac.uk> writes

/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills Staffs England /\/\/\/\/\
/\/\/ ch...@phaedsys.org www.phaedsys.org \/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

Clive D. W. Feather

unread,
Jun 3, 2001, 6:36:18 PM6/3/01
to
In article <mS+bXJAi...@phaedsys.demon.co.uk>, Chris Hills
<ch...@phaedsys.org> writes
>
>AFAIK I do :-)

Indeed, you do.

Clive D. W. Feather

unread,
Jun 3, 2001, 6:35:37 PM6/3/01
to
In article <9el4ct$lt6$1...@pegasus.csx.cam.ac.uk>, Nick Maclaren
<nm...@cus.cam.ac.uk> writes

>>Of course, in this
>>situation the integer promotions do nothing to intmax_t, but it is
>>technically an issue.
>
>Strictly, no. What if int was 32 value/sign bits followed by 32 padding
>bits, and intmax_t was the other way round?

Um, the representation changes but the value doesn't, which is all that
the concepts in question address.

Clive D. W. Feather

unread,
Jun 3, 2001, 6:34:55 PM6/3/01
to
In article <9el4k3$lgb$1...@pegasus.csx.cam.ac.uk>, Joseph S. Myers
<js...@cam.ac.uk> writes

>>The fix would be to require the conversion rank of intmax_t to be not
>>less than that of long long int (might as well do it properly); this
>>means that intmax_t either *is* long long int or is strictly bigger than
>>it.
>
>I don't see any advantage in requiring the rank to be at least that of
>long long int, over simply requiring it to be at least that of int,

I don't see a disadvantage either, and it reinforces the point that the
type was supposed to be the "top" type.

>and existing implementations that use long int as the type of intmax_t
>on systems where both are 64-bit would be affected by such a change.

How ?

Joseph S. Myers

unread,
Jun 3, 2001, 7:50:04 PM6/3/01
to
In article <msm7oa+P...@romana.davros.org>,

Clive D. W. Feather <cl...@davros.org> wrote:
>In article <9el4k3$lgb$1...@pegasus.csx.cam.ac.uk>, Joseph S. Myers
><js...@cam.ac.uk> writes
>>I don't see any advantage in requiring the rank to be at least that of
>>long long int, over simply requiring it to be at least that of int,
>
>I don't see a disadvantage either, and it reinforces the point that the
>type was supposed to be the "top" type.

It would, for example, mean that the type couldn't be an extended type
__intmax_t, if all these types were 64-bit, and an implementation
might find use of an extended type here beneficial for alias analysis,
since it would then know that intmax_t values couldn't alias long or
long long values by 6.5#7.

>>and existing implementations that use long int as the type of intmax_t
>>on systems where both are 64-bit would be affected by such a change.
>
>How ?

The implementations then need to change everywhere - in the compiler
and in the library (which may be largely decoupled, as long as they
agree on certain types and the ABI) - that knows what the exact type
is. If C implementations with typesafe linkers exist, or where people
have used C99 headers, including intmax_t, in C++ programs, this is
also an ABI change even if the types have the same representation and
calling conventions.

I know of two C library implementations for 64-bit systems that
include intmax_t and make it "long" rather than "long long": glibc (an
almost complete C99 library implementation) and Solaris (based on an
old C9X draft). I don't know of any choosing "long long" where both
have the same width, though such implementations probably exist.
Given observation of these two systems, GCC 3.0 presumes by default
(for the purpose of checking %j formats) that intmax_t is long rather
than long long, where they have the same width, unless otherwise
configured for a given system.

James Kuyper Jr.

unread,
Jun 3, 2001, 11:14:00 PM6/3/01
to
"Joseph S. Myers" wrote:
>
> In article <msm7oa+P...@romana.davros.org>,
> Clive D. W. Feather <cl...@davros.org> wrote:
> >In article <9el4k3$lgb$1...@pegasus.csx.cam.ac.uk>, Joseph S. Myers
> ><js...@cam.ac.uk> writes
> >>I don't see any advantage in requiring the rank to be at least that of
> >>long long int, over simply requiring it to be at least that of int,
> >
> >I don't see a disadvantage either, and it reinforces the point that the
> >type was supposed to be the "top" type.
>
> It would, for example, mean that the type couldn't be an extended type
> __intmax_t, if all these types were 64-bit, and an implementation
> might find use of an extended type here beneficial for alias analysis,

You've lost me there. Why is that prohibited? It seems to me that it
would be perfectly legal for long, long long, and __intmax_t to be three
different 64-bit types, with __intmax_t having a rank higher than that
of long long, and intmax_t typedefed as __intmax_t. What clause of the
standard would that violate?

> >>and existing implementations that use long int as the type of intmax_t
> >>on systems where both are 64-bit would be affected by such a change.

I can't see that as a major issue. I can't sympathize with the costs
they face as a result of having made a decision about intmax_t that,
quite frankly, I find incomprehensible.

Joseph S. Myers

unread,
Jun 4, 2001, 3:38:31 AM6/4/01
to
In article <3B1AFCF8...@wizard.net>,

James Kuyper Jr. <kuy...@wizard.net> wrote:
>You've lost me there. Why is that prohibited? It seems to me that it
>would be perfectly legal for long, long long, and __intmax_t to be three
>different 64-bit types, with __intmax_t having a rank higher than that
>of long long, and intmax_t typedefed as __intmax_t. What clause of the
>standard would that violate?

6.3.1.1#1:

[...]

-- The rank of any standard integer type shall be greater
than the rank of any extended integer type with the
same width.

>> >>and existing implementations that use long int as the type of intmax_t
>> >>on systems where both are 64-bit would be affected by such a change.
>
>I can't see that as a major issue. I can't sympathize with the costs
>they face as a result of having made a decision about intmax_t that,
>quite frankly, I find incomprehensible.

Given that the implementations may want their headers to be compatible
as far as possible with the strict modes of C89 and C++ compilers -
which will object to long long - it has made sense for implementations
to prefer long as the type of intmax_t and avoid the additional "long
long" type as much as possible as generally irrelevant when "long" has
64 bits, even where this complicates the headers (used on both 32 and
64 bit systems, or on the same system in both 32 and 64 bit modes).

Douglas A. Gwyn

unread,
Jun 4, 2001, 11:34:26 AM6/4/01
to
"Joseph S. Myers" wrote:
> I know of two C library implementations for 64-bit systems that
> include intmax_t and make it "long" rather than "long long"

(Assuming that both "long" and "long long" are supported and have
the same representation.) I examined Solaris 8's sys/int_types.h
and as near as I can figure out, the exact definitions evolved
through a fairly complicated historical process, including the
HP/SGI/Sun "LP64" agreement. I'm pretty sure the C standards
committee would recommend that intmax_t be defined with the
highest integer conversion rank. C99 didn't include that
requirement for two main reasons: the integer-conversion-rank
notion wasn't formalized during earlier drafts of the <stdint.h>
specification, and there wasn't a widespread appreciation that
any property other than maximum width could be important. As
one of the shepherds of the <stdint.h> specification, I would
support as a "clarification of intention" a change to require
[u]intmax_t to have highest integer conversion rank also.

Niklas Matthies

unread,
Jun 4, 2001, 1:01:58 PM6/4/01
to
On Mon, 4 Jun 2001 15:34:26 GMT, Douglas A. Gwyn <DAG...@null.net> wrote:
> "Joseph S. Myers" wrote:
> > I know of two C library implementations for 64-bit systems that
> > include intmax_t and make it "long" rather than "long long"
[毽愍

> As one of the shepherds of the <stdint.h> specification, I would
> support as a "clarification of intention" a change to require
> [u]intmax_t to have highest integer conversion rank also.

Are you saying you are in favor of prohibiting [u]intmax_t to be
extended integer types?

It seems to me that the best solution would be (or would have been) to
make [u]intmax_t genuine additional standard integer types. Of course,
this necessitates changes in the compiler; merely placing typedefs in
the standard header files won't do.

-- Niklas Matthies

Douglas A. Gwyn

unread,
Jun 4, 2001, 3:30:20 PM6/4/01
to
Niklas Matthies wrote:
> On Mon, 4 Jun 2001 15:34:26 GMT, Douglas A. Gwyn <DAG...@null.net> wrote:
> > As one of the shepherds of the <stdint.h> specification, I would
> > support as a "clarification of intention" a change to require
> > [u]intmax_t to have highest integer conversion rank also.
> Are you saying you are in favor of prohibiting [u]intmax_t to be
> extended integer types?

No, and that is not implied by what I said.

If an extended integer type has greater width than long long int,
then [u]intmax_t is already required to be defined as an extended
integer type, and that would not be changed by the new requirement.
If there is an extended integer type with the *same width* as
long long int, then [u]intmax_t *should* be defined as [unsigned]
long long int, which would be implied by the new requirement.
The deficiency that I think needs to be remedied is the loophole
that allows [u]intmax_t to be declared as a standard integer type
other than long long int and still conform to the 1999 standard.
(Of course, it is nice to have [u]intmax_t available for program
use even under C implementations that don't support long long int.)

Niklas Matthies

unread,
Jun 4, 2001, 5:03:12 PM6/4/01
to
On Mon, 4 Jun 2001 19:30:20 GMT, Douglas A. Gwyn <DAG...@null.net> wrote:
> Niklas Matthies wrote:
> > On Mon, 4 Jun 2001 15:34:26 GMT, Douglas A. Gwyn <DAG...@null.net> wrote:
> > > As one of the shepherds of the <stdint.h> specification, I would
> > > support as a "clarification of intention" a change to require
> > > [u]intmax_t to have highest integer conversion rank also.
> > Are you saying you are in favor of prohibiting [u]intmax_t to be
> > extended integer types?
>
> No, and that is not implied by what I said.

Well, I meant to imply, but didn't actually write: ...also in the case
that it has the same width as a standard integer type?

> If there is an extended integer type with the *same width* as
> long long int, then [u]intmax_t *should* be defined as [unsigned]
> long long int, which would be implied by the new requirement.
> The deficiency that I think needs to be remedied is the loophole
> that allows [u]intmax_t to be declared as a standard integer type
> other than long long int and still conform to the 1999 standard.

Do you consider this a deficiency (only) because in this case
[u]intmax_t doesn't have maximum integer conversion rank, or do you have
other reasons?

Independently, what was the committee's rationale for requiring that the


rank of any standard integer type shall be greater than the rank of any

extended integer type with the same width?

-- Niklas Matthies

Douglas A. Gwyn

unread,
Jun 5, 2001, 10:03:40 AM6/5/01
to
Niklas Matthies wrote:
> Do you consider this a deficiency (only) because in this case
> [u]intmax_t doesn't have maximum integer conversion rank, ...

Exactly.

> Independently, what was the committee's rationale for requiring that the
> rank of any standard integer type shall be greater than the rank of any
> extended integer type with the same width?

Because when the conversion ranking system is such that
promotions produce standardized types as much as possible,
there are fewer tricky details for programmers to worry
about.

Note in passing: Implementations that are currently defining
intmax_t as long (64 bits) are going to have to change the
definition anyway when they add support for 128-bit integers,
so there can be nothing "sacred" about the current definition.

Niklas Matthies

unread,
Jun 5, 2001, 11:30:13 AM6/5/01
to
On Tue, 5 Jun 2001 14:03:40 GMT, Douglas A. Gwyn <DAG...@null.net> wrote:
[毽愍

> > Independently, what was the committee's rationale for requiring that the
> > rank of any standard integer type shall be greater than the rank of any
> > extended integer type with the same width?
>
> Because when the conversion ranking system is such that
> promotions produce standardized types as much as possible,
> there are fewer tricky details for programmers to worry
> about.

What kind of tricky details? (Sorry if these are dumb questions.)

-- Niklas Matthies

Fergus Henderson

unread,
Jun 5, 2001, 5:33:49 PM6/5/01
to
"Douglas A. Gwyn" <DAG...@null.net> writes:

>Note in passing: Implementations that are currently defining
>intmax_t as long (64 bits) are going to have to change the
>definition anyway when they add support for 128-bit integers,
>so there can be nothing "sacred" about the current definition.

That's one possible future.

Another possible future is that implementations which currently
defined intmax_t as 64 bits will continue to do so, and will
either (1) not add support for 128-bit integers or (2) add
support for 128-bit integers, but not use them for any of the
usual types like size_t, and claim that they are not
"extended integer types" in the sense of the C standard
(perhaps instead calling them "expanded" integer types ;-).

Given the strength of arguments for binary backwards compatibility,
I think that in at least some cases the latter approach is more likely.

--
Fergus Henderson <f...@cs.mu.oz.au> | "I have always known that the pursuit
| of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.

Douglas A. Gwyn

unread,
Jun 5, 2001, 5:29:45 PM6/5/01
to
Niklas Matthies wrote:
> What kind of tricky details?

Well, for one, you really don't want default argument promotions
going to a nonstandard representation of the same width.

Niklas Matthies

unread,
Jun 5, 2001, 6:32:02 PM6/5/01
to

Hum, that's not too convincing. First of all, are there implementations
that provide different representations for same-width (signed) integer
types? Even if so, AFAICS this can only be a problem when both a
standard signed integer type and an extended signed integer type of the
same width are used together as arguments to one of the bitwise
operators, and the programmer assumes the bit operation to be performed
using the representation of the standard signed integer type. This seems
such a rare case that I don't see any problems with leaving this as an
QoI issue (a compiler ought certainly to warn about such situations).
Or am I missing less esoteric cases, or maybe it actually isn't so
esoteric for some reason?

-- Niklas Matthies

Douglas A. Gwyn

unread,
Jun 5, 2001, 6:43:05 PM6/5/01
to
Fergus Henderson wrote:
> Given the strength of arguments for binary backwards compatibility,
> I think that in at least some cases the latter approach is more likely.

There is really no need for it if implementors and programmers
use [u]intmax_t for its advertised properties only, which will
persist through changes of implementation.

Christian Bau

unread,
Jun 6, 2001, 2:40:26 AM6/6/01
to
Niklas Matthies wrote:
>
> First of all, are there implementations
> that provide different representations for same-width (signed) integer
> types?

Do you mean an implementation where signed int is 32 bit ones complement
and signed long is 32 bit twos complement? I would certainly hope not!

But then I thought about it, and an implementor might be tempted to use
an IEEE standard floating point unit to implement 64 bit integers as
denormalised extended precision floating point numbers. That would
actually give you 64 bit + 1 sign bit with a signed magnitude
representation. add, subtract, compare and multiply should be quite
efficient; bit operations would not. I wonder if this might be made into
a conforming implementation, and how much existing code it would break
:-)

James Kuyper Jr.

unread,
Jun 6, 2001, 6:12:16 AM6/6/01
to
Christian Bau wrote:
>
> Niklas Matthies wrote:
> >
> > First of all, are there implementations
> > that provide different representations for same-width (signed) integer
> > types?
>
> Do you mean an implementation where signed int is 32 bit ones complement
> and signed long is 32 bit twos complement? I would certainly hope not!

A more plausible combination would be big-endian and little-endian
representations of the same size.

Douglas A. Gwyn

unread,
Jun 6, 2001, 10:15:17 AM6/6/01
to
Niklas Matthies wrote:
> ... are there implementations that provide different representations

> for same-width (signed) integer types?

It is certainly possible, for example
__sign_magnitude_64_t // useful for high word in m.p. arithmetic
vs.
__twos_complement_64_t // alias for long long and maybe long
It would be appropriate for compilers to add more support like this,
especially now that C99 sanctions it. C0x might even provide some
standard syntax for specifying such attribute combinations.

Fergus Henderson

unread,
Jun 7, 2001, 2:38:45 AM6/7/01
to
"Douglas A. Gwyn" <DAG...@null.net> writes:

If programmers use intmax_t in interfaces (e.g. for DLLs, shared objects,
or other binary components), then changing the representation of intmax_t
will break binary backwards compatibility, which would cause a lot of hassles.

Are you suggesting that programmers should not use intmax_t in interfaces?
If so, what should they use instead?

James Kuyper Jr.

unread,
Jun 7, 2001, 9:28:36 AM6/7/01
to
Fergus Henderson wrote:
>
> "Douglas A. Gwyn" <DAG...@null.net> writes:
>
> >Fergus Henderson wrote:
> >> Given the strength of arguments for binary backwards compatibility,
> >> I think that in at least some cases the latter approach is more likely.
> >
> >There is really no need for it if implementors and programmers
> >use [u]intmax_t for its advertised properties only, which will
> >persist through changes of implementation.
>
> If programmers use intmax_t in interfaces (e.g. for DLLs, shared objects,
> or other binary components), then changing the representation of intmax_t
> will break binary backwards compatibility, which would cause a lot of hassles.
>
> Are you suggesting that programmers should not use intmax_t in interfaces?
> If so, what should they use instead?

The concept behind [u]intmax_t is implicitly one subject to change as
technology advances; it must therefore not be used in any interface that
you won't be free to recompile - on both sides of the interface! -
whenever the largest integer type changes.
If you have an interface which must always be the large enough to store
the largest possible integer, there's no way you're going to avoid the
necessity of recompiling both sides of that interface when the largest
possible integer type changes.

If it doesn't have to be able to store the largest possible integer, use
a type other than [u]intmax_t whose meaning represents a some less
changeable concept.

Niklas Matthies

unread,
Jun 7, 2001, 9:33:22 AM6/7/01
to
On Thu, 07 Jun 2001 09:28:36 -0400, James Kuyper Jr. <kuy...@wizard.net> wrote:
[毽愍

> If you have an interface which must always be the large enough to
> store the largest possible integer, there's no way you're going to
> avoid the necessity of recompiling both sides of that interface when
> the largest possible integer type changes.

There is one: bignums.

-- Niklas Matthies

Nick Maclaren

unread,
Jun 7, 2001, 9:36:15 AM6/7/01
to

In article <slrn9hv0jq.ik.news/comp....@ns.nmhq.net>, news/comp....@nmhq.net (Niklas Matthies) writes:
|> On Thu, 07 Jun 2001 09:28:36 -0400, James Kuyper Jr. <kuy...@wizard.net> wrote:
|> [毽愍
|> > If you have an interface which must always be the large enough to
|> > store the largest possible integer, there's no way you're going to
|> > avoid the necessity of recompiling both sides of that interface when
|> > the largest possible integer type changes.
|>
|> There is one: bignums.

Be careful with that one. Most bignums are arbitrarily extensible,
and often start with a fixed size count.

More seriously, yes, there ARE ways of avoiding recompiling both
sides when the largest integer size changes, but they need careful
design. And bignums are only one such way of many.

None, however, are trivial.

Niklas Matthies

unread,
Jun 7, 2001, 10:11:37 AM6/7/01
to
On 7 Jun 2001 13:36:15 GMT, Nick Maclaren <nm...@cus.cam.ac.uk> wrote:
> In article <slrn9hv0jq.ik.news/comp....@ns.nmhq.net>, news/comp....@nmhq.net (Niklas Matthies) writes:
> |> On Thu, 07 Jun 2001 09:28:36 -0400, James Kuyper Jr. <kuy...@wizard.net> wrote:
> |> [毽愍
> |> > If you have an interface which must always be the large enough to
> |> > store the largest possible integer, there's no way you're going to
> |> > avoid the necessity of recompiling both sides of that interface when
> |> > the largest possible integer type changes.
> |>
> |> There is one: bignums.
>
> Be careful with that one. Most bignums are arbitrarily extensible,
> and often start with a fixed size count.

How does that make them unsuitable for a binary interface that needn't
be changed?

-- Niklas Matthies

Nick Maclaren

unread,
Jun 7, 2001, 10:15:56 AM6/7/01
to

In article <slrn9hv2rh.ik.news/comp....@ns.nmhq.net>,

news/comp....@nmhq.net (Niklas Matthies) writes:
|> On 7 Jun 2001 13:36:15 GMT, Nick Maclaren <nm...@cus.cam.ac.uk> wrote:
|> > In article <slrn9hv0jq.ik.news/comp....@ns.nmhq.net>, news/comp....@nmhq.net (Niklas Matthies) writes:
|> > |> On Thu, 07 Jun 2001 09:28:36 -0400, James Kuyper Jr. <kuy...@wizard.net> wrote:
|> > |> [毽愍
|> > |> > If you have an interface which must always be the large enough to
|> > |> > store the largest possible integer, there's no way you're going to
|> > |> > avoid the necessity of recompiling both sides of that interface when
|> > |> > the largest possible integer type changes.
|> > |>
|> > |> There is one: bignums.
|> >
|> > Be careful with that one. Most bignums are arbitrarily extensible,
|> > and often start with a fixed size count.
|>
|> How does that make them unsuitable for a binary interface that needn't
|> be changed?

Consider when the number needs to be bigger than the count allows :-)

That mistake has been made several dozen times in my experience, and
almost certainly hundreds if not thousands of times more.

Niklas Matthies

unread,
Jun 7, 2001, 10:51:04 AM6/7/01
to
On 7 Jun 2001 14:15:56 GMT, Nick Maclaren <nm...@cus.cam.ac.uk> wrote:
> In article <slrn9hv2rh.ik.news/comp....@ns.nmhq.net>,
> news/comp....@nmhq.net (Niklas Matthies) writes:
> |> On 7 Jun 2001 13:36:15 GMT, Nick Maclaren <nm...@cus.cam.ac.uk> wrote:
> |> > In article <slrn9hv0jq.ik.news/comp....@ns.nmhq.net>, news/comp....@nmhq.net (Niklas Matthies) writes:
> |> > |> On Thu, 07 Jun 2001 09:28:36 -0400, James Kuyper Jr. <kuy...@wizard.net> wrote:
> |> > |> [毽愍
> |> > |> > If you have an interface which must always be the large enough to
> |> > |> > store the largest possible integer, there's no way you're going to
> |> > |> > avoid the necessity of recompiling both sides of that interface when
> |> > |> > the largest possible integer type changes.
> |> > |>
> |> > |> There is one: bignums.
> |> >
> |> > Be careful with that one. Most bignums are arbitrarily extensible,
> |> > and often start with a fixed size count.
> |>
> |> How does that make them unsuitable for a binary interface that needn't
> |> be changed?
>
> Consider when the number needs to be bigger than the count allows :-)

Easy, the count is a bignum, too. :)

Admittedly, having a fixed-size count only pushes up the limit of
representable values, and doesn't abolish it. But it pushes it up to
around <previous limit>^<previous limit>, which I guess should be enough
for allmost all practical purposes. I mean, we were talkin about passing
integer values that fit into some native (even if future) type.

-- Niklas Matthies

Nick Maclaren

unread,
Jun 7, 2001, 11:03:14 AM6/7/01
to

In article <slrn9hv55g.62t.news/comp....@ns.nmhq.net>,

As I said, that mistake has been made many times - and using
precisely that argument, too :-)

It isn't very likely to hit nowadays, as the count will surely be
32 bits, but the point stands. One common reason is that an
interface is designed with the hidden assumption that it is going
to be used for purpose X, but ends up being used for purpose Y.
For example, having a 16-bit count of bits is fine for RSA until
the end of time (because, if it isn't, RSA has been broken). But
it is NBG for number theorists. Ditto the MVS argument limits,
Unix argument limits, etc. etc.

Dave Prosser

unread,
Jun 7, 2001, 11:38:16 AM6/7/01
to
"James Kuyper Jr." wrote:
> The concept behind [u]intmax_t is implicitly one subject to change as
> technology advances; it must therefore not be used in any interface that
> you won't be free to recompile - on both sides of the interface! -
> whenever the largest integer type changes.
> If you have an interface which must always be the large enough to store
> the largest possible integer, there's no way you're going to avoid the
> necessity of recompiling both sides of that interface when the largest
> possible integer type changes.
>
> If it doesn't have to be able to store the largest possible integer, use
> a type other than [u]intmax_t whose meaning represents a some less
> changeable concept.

Unfortunately, this cannot ever be true since the C99 standard
requires APIs that include [u]intmax_t, and the world provides
systems using shared libraries. Even plain old static libraries
are likely to be a problem in practice since making "flash"
changes can be difficult.

Once you've chosen what [u]intmax_t looks like "underneath",
it's nailed down. If you then decide that [u]intmax_t needs
to be bigger, you'll need to do name mapping or versioning or
something beyond regular practices, or existing binaries will
have been broken.

We've certainly had to do this sort of thing when APIs have
had incompatibilities forced on us, so it isn't impossible,
just painful.

--
Dave Prosser dfp at sco dot com Caldera, Murray Hill, NJ

James Kuyper

unread,
Jun 7, 2001, 11:26:28 AM6/7/01
to
Dave Prosser wrote:
...

> We've certainly had to do this sort of thing when APIs have
> had incompatibilities forced on us, so it isn't impossible,
> just painful.

It is impossible for an interface using a fixed-size type (as opposed to
bignums) to retain binary compatibility if that type must continue to be
the biggest integer type, even after the biggest integer type changes.
If you need to retain binary compatibility across such boundaries, then
you shouldn't be using uintmax_t for the interface. Selecting
"uintmax_t" for the interface says loudly and explicitly "Change me
whenever the biggest integer type changes". If that's not what your code
means, that's not what your code should say.

Nick Maclaren

unread,
Jun 7, 2001, 1:00:26 PM6/7/01
to

In article <3B1F9D24...@wizard.net>,

Not so. It has been done several times, though it does impose
some discipline on the developers of the software. Here is a
rough description of the technique, which is applicable to
most kinds of extension, with more or less hassle. Integer
sizes are an easy example.

Each binary has a flag indicating the maximum level of the
interface it supports, which is made available to the other side
of the interface in some fashion.

When the two sides connect, they agree to use the lower of
the two levels.

If one side gets a request that cannot be mapped into the
interface level, it returns an error. In this case, it will
happen only when one program's requirements exceed the capacity
of the old interface.

There are a zillion variations of this, and it becomes much
easier if you can assume that one side will always be at least
as advanced as the other. That is why sticking with 'long' as
the longest type and maintaining binary compatibility in the C
library is not a difficult task.

James Kuyper

unread,
Jun 7, 2001, 12:50:54 PM6/7/01
to

That approach requires a generic interface into which you can stuff an
arbitrary type. In C, this can be done using variable arguments or void*
or char*. Yes, those are good approaches, but they aren't applicable,
except as a superior alternative, in the case where the declared return
type or parameter type of a function or global variable is [u]intmax_t.

Nick Maclaren

unread,
Jun 7, 2001, 4:34:52 PM6/7/01
to
In article <3B1FB0EE...@wizard.net>,
James Kuyper <kuy...@wizard.net> wrote:

>Nick Maclaren wrote:
>>
>>
>> There are a zillion variations of this, and it becomes much
>> easier if you can assume that one side will always be at least
>> as advanced as the other. That is why sticking with 'long' as
>> the longest type and maintaining binary compatibility in the C
>> library is not a difficult task.
>
>That approach requires a generic interface into which you can stuff an
>arbitrary type. In C, this can be done using variable arguments or void*
>or char*. Yes, those are good approaches, but they aren't applicable,
>except as a superior alternative, in the case where the declared return
>type or parameter type of a function or global variable is [u]intmax_t.

That is only so if you insisting that the implementation use solely
facilities that are within the C language. Not merely can it be
done in the case you are describing, it has been done a good many
times. But it does need SOME way of selecting alternate code
depending on which intmax_t you are providing.

Douglas A. Gwyn

unread,
Jun 8, 2001, 1:15:40 PM6/8/01
to
Fergus Henderson wrote:
> Are you suggesting that programmers should not use intmax_t in interfaces?

When binary compatibility is a requirement, one should use *only*
types that have a sufficiently strict specification, e.g. int64_t
(signed, twos-complement, unpadded, width 64). One would think
that previous experience with things like off_t would have taught
people *some*thing.

Douglas A. Gwyn

unread,
Jun 8, 2001, 1:17:26 PM6/8/01
to
Niklas Matthies wrote:
> Easy, the count is a bignum, too. :)

I don't think you were serious, but actually that general idea
can be made to work. Knuth wrote a paper about it, and boy
could he express some incredibly big numbers.

Nick Maclaren

unread,
Jun 8, 2001, 2:09:42 PM6/8/01
to

Yes, it has. And that is not necessary, though it is one of the
easier approaches. There are several other ways of skinning this
cat, and the easiest one is also the one that is least compatible
with long-term portability.

Nick Maclaren

unread,
Jun 8, 2001, 2:10:25 PM6/8/01
to

Any computable number, in fact :-)

James Kuyper

unread,
Jun 8, 2001, 2:03:16 PM6/8/01
to
Nick Maclaren wrote:
>
> In article <3B2108A6...@null.net>, "Douglas A. Gwyn" <DAG...@null.net> writes:
> |> Niklas Matthies wrote:
> |> > Easy, the count is a bignum, too. :)
> |>
> |> I don't think you were serious, but actually that general idea
> |> can be made to work. Knuth wrote a paper about it, and boy
> |> could he express some incredibly big numbers.
>
> Any computable number, in fact :-)

Any number computable on a given machine, surely?

There's no way he could represent distinctly more than 2^N different
numbers, where N is the total number of bits of memory available to
store them. :-)

Nick Maclaren

unread,
Jun 8, 2001, 4:07:50 PM6/8/01
to
In article <3B211364...@wizard.net>,

That is true, but the FORMAT need not have any fixed limit. Consider
a format consisting of a sequence of the following:

If the first bit is one, the rest are a count of the number of
bytes in the next entry.
If the first bit is zero, the rest are the value.

Start this off with a single byte.

Niklas Matthies

unread,
Jun 9, 2001, 9:54:26 AM6/9/01
to
On Fri, 8 Jun 2001 17:17:26 GMT, Douglas A. Gwyn <DAG...@null.net> wrote:
> Niklas Matthies wrote:
> > Easy, the count is a bignum, too. :)
>
> I don't think you were serious, but actually that general idea
> can be made to work.

I was serious in the sense that I don't see any particular theoretical
problem with doing this (hence "easy"). But I think that for most uses,
one would prefer a fixed-size count to trade off some flexibility for
efficiency and simpler source code.

-- Niklas Matthies

Peter Curran

unread,
Jun 9, 2001, 10:24:09 PM6/9/01
to
On Fri, 8 Jun 2001 17:15:40 GMT, "Douglas A. Gwyn" <DAG...@null.net>
wrote:

>Fergus Henderson wrote:

Why would one think that? There was plenty of experience to learn from
ten years ago, but "long long" still happened. It will almost
certainly happen again with intmax. The only probably difference is
that this time the committee say "it's your own fault."

Clive D. W. Feather

unread,
Jun 10, 2001, 10:06:54 AM6/10/01
to
In article <9feifc$2ka$1...@pegasus.csx.cam.ac.uk>, Joseph S. Myers
<js...@cam.ac.uk> writes
>>>I don't see any advantage in requiring the rank to be at least that of
>>>long long int, over simply requiring it to be at least that of int,
>>
>>I don't see a disadvantage either, and it reinforces the point that the
>>type was supposed to be the "top" type.
>
>It would, for example, mean that the type couldn't be an extended type
>__intmax_t, if all these types were 64-bit,
[...]

That's a very good point.

>>>and existing implementations that use long int as the type of intmax_t
>>>on systems where both are 64-bit would be affected by such a change.
>>
>>How ?
>
>The implementations then need to change everywhere - in the compiler
>and in the library (which may be largely decoupled, as long as they
>agree on certain types and the ABI) - that knows what the exact type
>is.

True. I don't know how significant an issue this is.

So, we're back to "intmax_t might not have the highest integer
conversion rank, it might be changed by the integer promotions, but does
it matter ?".

--
Clive D.W. Feather, writing for himself | Home: <cl...@davros.org>
Tel: +44 20 8371 1138 (work) | Web: <http://www.davros.org>
Fax: +44 20 8371 4037 (D-fax) | Work: <cl...@demon.net>
Written on my laptop; please observe the Reply-To address

Clive D. W. Feather

unread,
Jun 10, 2001, 10:13:57 AM6/10/01
to
In article <9fn7hl$260$1...@mulga.cs.mu.OZ.AU>, Fergus Henderson
<f...@cs.mu.oz.au> writes

>If programmers use intmax_t in interfaces (e.g. for DLLs, shared objects,
>or other binary components), then changing the representation of intmax_t
>will break binary backwards compatibility,

BFD, says the cynical part of me.

More seriously, the C Standard was never aimed at binary portability,
just at source portability.

>Are you suggesting that programmers should not use intmax_t in interfaces?
>If so, what should they use instead?

They should, but if you want to write a formal ABI you need to think
carefully (e.g. by passing [u]intmax_t values as length/value pairs or
some other technique). This might be a good reason for wanting them to
be an extended integer type.

Clive D. W. Feather

unread,
Jun 10, 2001, 10:17:03 AM6/10/01
to
In article <slrn9hv0jq.ik.news/comp....@ns.nmhq.net>, Niklas Matthies
<news/comp....@nmhq.net> writes
>There is one: bignums.

We did consider allowing bignums to be integer types in C. In the end we
decided that a mandatory maximal integer type with well-understood
behaviour was more important.

Clive D. W. Feather

unread,
Jun 10, 2001, 10:11:07 AM6/10/01
to
In article <3B1DD05A...@isltd.insignia.com>, Christian Bau
<christ...@isltd.insignia.com> writes
>Do you mean an implementation where signed int is 32 bit ones complement
>and signed long is 32 bit twos complement?

Or have different endianness. Or int is 4 octets and long is 8. We
deliberately intended to allow all of these.

>But then I thought about it, and an implementor might be tempted to use
>an IEEE standard floating point unit to implement 64 bit integers as
>denormalised extended precision floating point numbers. That would
>actually give you 64 bit + 1 sign bit with a signed magnitude
>representation. add, subtract, compare and multiply should be quite
>efficient; bit operations would not.

Similar approaches have been used before.

>I wonder if this might be made into
>a conforming implementation,

I can't see why not.

Francis Glassborow

unread,
Jun 12, 2001, 5:35:06 PM6/12/01
to
In article <9fdg4l$qe4$1...@pegasus.csx.cam.ac.uk>, Joseph S. Myers
<js...@cam.ac.uk> writes
>So, who can sponsor subscription to the reflector, or how can one
>subscribe to the IST/5/-/14 mailing list?

1) start coming to BSI panel meetings.
2) persuade the Convenor of that panel that you are a bona fide
interested party.

The easiest way of doing that is by (preferably as an ACCU member,
annual fee 15ukp) donate at least 20ukp to the ACCU managed fund to
support standardisation of C, C++ and related topics) Those that attend
meeting spend much more than 20ukp in travel etc. so it seems reasonable
that others who are seriously involved but cannot come to meetings
should contribute something to the costs. ACCU actually covers the cost
of a seat on IST5 for both C and C++.


Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

Chris Hills

unread,
Jun 13, 2001, 5:22:05 PM6/13/01
to
Francis Glassborow <francis.g...@ntlworld.com> writes

>In article <9fdg4l$qe4$1...@pegasus.csx.cam.ac.uk>, Joseph S. Myers
><js...@cam.ac.uk> writes
>>So, who can sponsor subscription to the reflector, or how can one
>>subscribe to the IST/5/-/14 mailing list?

>1) start coming to BSI panel meetings.

Yes a good idea. Next one "sometime" late August or early September.

>2) persuade the Convenor of that panel that you are a bona fide
>interested party.

Also a good idea. Why are you an interested party?

>The easiest way of doing that is by (preferably as an ACCU member,
>annual fee 15ukp)

I agree with that part though it is not essential (but the ACCU is VERY
cost effective but then I would say that having been a member since
1989)

> donate at least 20ukp to the ACCU managed fund to
>support standardisation of C, C++ and related topics)

This is a personal thing. some people do some don't.

>Those that attend
>meeting spend much more than 20ukp in travel etc. so it seems reasonable
>that others who are seriously involved but cannot come to meetings
>should contribute something to the costs. ACCU actually covers the cost
>of a seat on IST5 for both C and C++.

This is true..... In theory there are some expenses for the WG meetings
but the local UK BSI meetings are "free" :-) the only perk (having
travelled to BSI London ids there are free coffee and biscuits :-)

/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills Staffs England /\/\/\/\/\
/\/\/ ch...@phaedsys.org www.phaedsys.org \/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

Fergus Henderson

unread,
Jun 18, 2001, 6:08:35 AM6/18/01
to
James Kuyper <kuy...@wizard.net> writes:

>It is impossible for an interface using a fixed-size type (as opposed to
>bignums) to retain binary compatibility if that type must continue to be
>the biggest integer type, even after the biggest integer type changes.

Agreed.

>If you need to retain binary compatibility across such boundaries, then
>you shouldn't be using uintmax_t for the interface.

What should you use instead, then?

>Selecting "uintmax_t" for the interface says loudly and explicitly "Change me
>whenever the biggest integer type changes". If that's not what your code
>means, that's not what your code should say.

I think that using "uintmax_t" in interfaces also says just as loudly
"Don't change the size of this type!". Together these two statements
imply "Don't change the size of the biggest integer type!".

--
Fergus Henderson <f...@cs.mu.oz.au> | "I have always known that the pursuit
The University of Melbourne | of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.

Nick Maclaren

unread,
Jun 18, 2001, 6:27:17 AM6/18/01
to

In article <9gkjv4$boj$1...@mulga.cs.mu.OZ.AU>, f...@cs.mu.oz.au (Fergus Henderson) writes:
|> James Kuyper <kuy...@wizard.net> writes:
|>
|> >It is impossible for an interface using a fixed-size type (as opposed to
|> >bignums) to retain binary compatibility if that type must continue to be
|> >the biggest integer type, even after the biggest integer type changes.
|>
|> Agreed.

It's not impossible - it's just tricky. All right, with the dumbing
down of project management, it may be impossible to get an appropriate
interface agreed and implemented. But it can be done.

James Kuyper Jr.

unread,
Jun 18, 2001, 8:57:03 AM6/18/01
to
Nick Maclaren wrote:
>
> In article <9gkjv4$boj$1...@mulga.cs.mu.OZ.AU>, f...@cs.mu.oz.au (Fergus Henderson) writes:
> |> James Kuyper <kuy...@wizard.net> writes:
> |>
> |> >It is impossible for an interface using a fixed-size type (as opposed to
> |> >bignums) to retain binary compatibility if that type must continue to be
> |> >the biggest integer type, even after the biggest integer type changes.
> |>
> |> Agreed.
>
> It's not impossible - it's just tricky. All right, with the dumbing
> down of project management, it may be impossible to get an appropriate
> interface agreed and implemented. But it can be done.

Please explain. I'm not talking about using bignums, nor about using any
interface with equivalent functionality, such as varargs or pointers to
an array. Nor are we talking about arranging to get both sides of the
interface recompiled; at least, that's what I'm assuming he meant when
talking about binary compatibility. How do you increase the range of
numbers that can be passed to through a fixed interface?

James Kuyper Jr.

unread,
Jun 18, 2001, 9:20:46 AM6/18/01
to
Fergus Henderson wrote:
>
> James Kuyper <kuy...@wizard.net> writes:
>
> >It is impossible for an interface using a fixed-size type (as opposed to
> >bignums) to retain binary compatibility if that type must continue to be
> >the biggest integer type, even after the biggest integer type changes.
>
> Agreed.
>
> >If you need to retain binary compatibility across such boundaries, then
> >you shouldn't be using uintmax_t for the interface.
>
> What should you use instead, then?

If using a fixed interface is important, use a typename whose name
describe the interface more specifically. For instance, if it must be 64
bits, use one of the size-named types. If you need to be able to use a
fixed-size type, need to be able to pass through that type any integer
that can be stored in a fixed-size type, and need to retain binary
compatibility across an increase in size of the maximum fixed-size type,
your needs are fundamentally in conflict with each other, and there's
nothing the standard can do to resolve that problem.

> >Selecting "uintmax_t" for the interface says loudly and explicitly "Change me
> >whenever the biggest integer type changes". If that's not what your code
> >means, that's not what your code should say.
>
> I think that using "uintmax_t" in interfaces also says just as loudly
> "Don't change the size of this type!". Together these two statements

I don't see that. The reason why I feel that the name uintmax_t implies
changeablility, is the vagueness of the name. The name doesn't say it
has any specific number of bits. It says only that it's the maximum. The
maximum can change if the set it's a maximum over is free to change. It
can be different on different platforms, on different compilers for the
same platform, and even on different runs of the same compiler using
compiler options. Why in the world would you assume that different
versions of the same compiler must retain the size of that type?

> imply "Don't change the size of the biggest integer type!".

The only way to guarantee that it won't change is to pick a time
sufficiently late in the lifetime of C, that there will be no further
desire to change it before C dies. I don't think that will happen any
time soon.

Nick Maclaren

unread,
Jun 18, 2001, 11:05:16 AM6/18/01
to

I posted it earlier, but it may not have reached you.


Not so. It has been done several times, though it does impose
some discipline on the developers of the software. Here is a
rough description of the technique, which is applicable to
most kinds of extension, with more or less hassle. Integer
sizes are an easy example.

Each binary has a flag indicating the maximum level of the
interface it supports, which is made available to the other side
of the interface in some fashion.

When the two sides connect, they agree to use the lower of
the two levels.

If one side gets a request that cannot be mapped into the
interface level, it returns an error. In this case, it will
happen only when one program's requirements exceed the capacity
of the old interface.

There are a zillion variations of this, and it becomes much


easier if you can assume that one side will always be at least
as advanced as the other. That is why sticking with 'long' as
the longest type and maintaining binary compatibility in the C
library is not a difficult task.

James Kuyper

unread,
Jun 18, 2001, 11:12:33 AM6/18/01
to
Nick Maclaren wrote:
>
> In article <3B2DFA9F...@wizard.net>, "James Kuyper Jr." <kuy...@wizard.net> writes:
> |> Nick Maclaren wrote:
...

> |> Please explain. I'm not talking about using bignums, nor about using any
> |> interface with equivalent functionality, such as varargs or pointers to
> |> an array. Nor are we talking about arranging to get both sides of the
> |> interface recompiled; at least, that's what I'm assuming he meant when
> |> talking about binary compatibility. How do you increase the range of
> |> numbers that can be passed to through a fixed interface?
>
> I posted it earlier, but it may not have reached you.
>
> Not so. It has been done several times, though it does impose
> some discipline on the developers of the software. Here is a
> rough description of the technique, which is applicable to
> most kinds of extension, with more or less hassle. Integer
> sizes are an easy example.
>
> Each binary has a flag indicating the maximum level of the
> interface it supports, which is made available to the other side
> of the interface in some fashion.
>
> When the two sides connect, they agree to use the lower of
> the two levels.
>
> If one side gets a request that cannot be mapped into the
> interface level, it returns an error. In this case, it will
> happen only when one program's requirements exceed the capacity
> of the old interface.

That's a way to make the program fail if it the binary's capacity is
exceeded; it doesn't provide a way to make the binary exceed the limit
that was built into it when it was compiled. That's what I'm saying is a
logical impossibility.

Niklas Matthies

unread,
Jun 18, 2001, 11:42:14 AM6/18/01
to
On Mon, 18 Jun 2001 11:12:33 -0400, James Kuyper <kuy...@wizard.net> wrote:
> Nick Maclaren wrote:
[毽愍

> That's a way to make the program fail if it the binary's capacity is
> exceeded; it doesn't provide a way to make the binary exceed the limit
> that was built into it when it was compiled. That's what I'm saying is a
> logical impossibility.

But it allows to change uintmax_t and to have a library that works with
client code compiled with either old or new uintmax_t.

-- Niklas Matthies

Douglas A. Gwyn

unread,
Jun 18, 2001, 11:08:26 AM6/18/01
to
"James Kuyper Jr." wrote:
> your needs are fundamentally in conflict with each other, and there's
> nothing the standard can do to resolve that problem.

Exactly.

Douglas A. Gwyn

unread,
Jun 18, 2001, 11:07:06 AM6/18/01
to
Fergus Henderson wrote:
> I think that using "uintmax_t" in interfaces also says just as loudly
> "Don't change the size of this type!".

No, it says "I don't understand what is under control of the program
and what is under contyrol of the implementation."

Nick Maclaren

unread,
Jun 18, 2001, 12:05:30 PM6/18/01
to

Precisely. It has been done many times, and can be made to work
very well. Theoretically, and practically in some languages, it
is possible to do what James Kuyper says is impossible!

If the interface is such that the size of an interface object is
returned from the interface, it is possible to compile a program
on a (say) 32-bit system and run it on 64-bit objects. What is
more, it is possible to do this even to ordinarily compiled code,
if the size of a type can be specified at program load time. And
this has been done - in fact, I have done it in a small way!

However, James Kuyper is right in that C language states that the
C language specifies integer types in such a way that the same
integer type has to be the same in all compilation units. This
does mean that extra constraints are needed, as well as extra
linker/loader support, if the size of an integer is to be allowed
to be a run-time parameter. It can't be done at all for the
standard-defined types, because of <limits.h> etc.

But it CAN be done for a surprisingly wide range of interfaces.

James Kuyper Jr.

unread,
Jun 18, 2001, 7:31:34 PM6/18/01
to

OK. Let's see how this works. Lets postulate a library function

uintmax_t rotate(uintmax_t u){ return u-1; }

There's no possible failure mode for this function, and therefore no
reason to provide it with a means of indicating that it's been given an
invalid value. This is obviously just an example - the key feature of
this function is the complete lack of a need for an error indicator,
which is not a particularly rare feature.

The library is compiled using uintmax_t = a 64 bit type.

A later version of the compiler comes out with uintmax_t = a 128-bit
type. It promises backwards compatibility through the negotiated
interface technique described by Nick, implemented almost invisibly to
the programmer. I say almost, because it has to do something like raise
a signal whenever the negotiated interface type is too small to handle
the value passed to it. Whatever it does in that regard will necessarily
cause strictly conforming code to fail. Therefore, the compiler does not
claim to be conforming when used in this way to connect old and new
binaries.

New code is written calling rotate() with an argument of 0. This module
is linked with the library module that expects intmax_t to be 64 bits. A
64-bit interface will be negotiated. The code will return 2^64-1, which
is the incorrect value; it should have returned 2^128-1. The detailed
functionality of rotate() doesn't matter - the only thing that matters
is that the 64-bit version can only see a maximum of 2^64 different
argument values; the 128-bit version can have as many as 2^128, and
there's not necessarily any way to wrap the 64-bit version so it gets
all 2^128 of them right.

The whole purpose of choosing uintmax_t as an interface is to handle
arbitrarily large values correctly; that's not what happens if you use
this technique.

Nick Maclaren

unread,
Jun 19, 2001, 4:00:49 AM6/19/01
to
In article <3B2E8F56...@wizard.net>,

James Kuyper Jr. <kuy...@wizard.net> wrote:
>Niklas Matthies wrote:
>>
>> On Mon, 18 Jun 2001 11:12:33 -0400, James Kuyper <kuy...@wizard.net> wrote:
>> > Nick Maclaren wrote:
>> [毽愍
>> > That's a way to make the program fail if it the binary's capacity is
>> > exceeded; it doesn't provide a way to make the binary exceed the limit
>> > that was built into it when it was compiled. That's what I'm saying is a
>> > logical impossibility.
>>
>> But it allows to change uintmax_t and to have a library that works with
>> client code compiled with either old or new uintmax_t.
>
>OK. Let's see how this works. Lets postulate a library function
>
> uintmax_t rotate(uintmax_t u){ return u-1; }
>
>There's no possible failure mode for this function, and therefore no
>reason to provide it with a means of indicating that it's been given an
>invalid value. This is obviously just an example - the key feature of
>this function is the complete lack of a need for an error indicator,
>which is not a particularly rare feature.

(a) There is a possible failure mode - the traditional diagnostic,
traceback and halt from the library. (b) Please don't confuse the
lack of a need for a failure indicator with the requirement for no
failures. See below.

>The library is compiled using uintmax_t = a 64 bit type.

In 30+ years of using hundreds (perhaps thousands) of compilers and
libraries, I cannot remember a single case where that sort of forward
compatibility was supported. In every case, when a major change is
made to the language between (say) versions N and N+1, the following
combinations are permitted:

Compiler Library
N N
N+1 N+1
N N+1 By the better vendors etc.
N+1 N Only rarely, and then only when the program
uses none of the new facilities in N+1

Can you give a counter example?

>A later version of the compiler comes out with uintmax_t = a 128-bit
>type. It promises backwards compatibility through the negotiated
>interface technique described by Nick, implemented almost invisibly to
>the programmer. I say almost, because it has to do something like raise
>a signal whenever the negotiated interface type is too small to handle
>the value passed to it. Whatever it does in that regard will necessarily
>cause strictly conforming code to fail. Therefore, the compiler does not
>claim to be conforming when used in this way to connect old and new
>binaries.

That is almost correct. I say almost, because most so-called conforming
compilers have some such features anyway, even within a single version.

>New code is written calling rotate() with an argument of 0. This module
>is linked with the library module that expects intmax_t to be 64 bits. A
>64-bit interface will be negotiated. The code will return 2^64-1, which
>is the incorrect value; it should have returned 2^128-1. The detailed
>functionality of rotate() doesn't matter - the only thing that matters
>is that the 64-bit version can only see a maximum of 2^64 different
>argument values; the 128-bit version can have as many as 2^128, and
>there's not necessarily any way to wrap the 64-bit version so it gets
>all 2^128 of them right.

No. That is an argument for proper overflow checking, as much as
anything. In your particular example, since C unsigned integers are
specified the way that they are, with overflow detection forbidden,
the negotiation should permit connexion of signed 128-bit to 64-bit
(with overflow detection) and forbid the connexion of unsigned.
There is then a simple incompatibility diagnostic - as you get on
many existing systems.

>The whole purpose of choosing uintmax_t as an interface is to handle
>arbitrarily large values correctly; that's not what happens if you use
>this technique.

That may be your intent, but is a mistaken use of uintmax_t; it is
not specified to do that, not even within a single C program all
compiled together. It is specified to be at least as large as a
specific set of standard-defined types and no more.

Niklas Matthies

unread,
Jun 19, 2001, 7:59:23 AM6/19/01
to
[毽愍

That's right. But you are talking about a lack in the implementation
here. It's not a property of the binary interface. The original claim
was that changing uintmax_t necessarily breaks binary interface
compatibility. Which is not true.

With regard to the implementation issue, you can write the library
function with a bignum implementation alternative which it uses as
a fallback if it doesn't "natively" support the client's type.

-- Niklas Matthies

James Kuyper Jr.

unread,
Jun 19, 2001, 8:47:26 AM6/19/01
to
Niklas Matthies wrote:
...

> That's right. But you are talking about a lack in the implementation
> here. It's not a property of the binary interface. The original claim
> was that changing uintmax_t necessarily breaks binary interface
> compatibility. Which is not true.

If a library module compiled with one version of the compiler cannot be
substitituted for the same module compiled with a different version of
the compiler without changing the observable behavior, then you have not
achieved full binary interface compatibility. An interface that uses a
uintmax_t argument can have a maximum of UINTMAX_MAX+1 different
behaviors dependent on that argument, all else being equal. If that
number increases, there is in general no way to map the larger range of
values to the smaller one so as to preserve the semantics required for
the larger range. Something has to be lost, and whatever it is that is
lost constitutes a failure of binary compatibility.

James Kuyper Jr.

unread,
Jun 19, 2001, 9:18:57 AM6/19/01
to
Nick Maclaren wrote:
>
> In article <3B2E8F56...@wizard.net>,
> James Kuyper Jr. <kuy...@wizard.net> wrote:
...

> In 30+ years of using hundreds (perhaps thousands) of compilers and
> libraries, I cannot remember a single case where that sort of forward
> compatibility was supported. In every case, when a major change is

That's entirely consistent with my claim that it's impossible to achieve
that kind of forward compatibility. Are we in agreement then?

> >cause strictly conforming code to fail. Therefore, the compiler does not
> >claim to be conforming when used in this way to connect old and new
> >binaries.
>
> That is almost correct. I say almost, because most so-called conforming
> compilers have some such features anyway, even within a single version.

Conceded; however the minute the subject wanders away from assuming
perfectly conforming implmentations, to take in real-world
imperfections, the subject widens so much as to be not worth talking
about. There's no limit to what forms non-conformance can take.

> >New code is written calling rotate() with an argument of 0. This module
> >is linked with the library module that expects intmax_t to be 64 bits. A
> >64-bit interface will be negotiated. The code will return 2^64-1, which
> >is the incorrect value; it should have returned 2^128-1. The detailed
> >functionality of rotate() doesn't matter - the only thing that matters
> >is that the 64-bit version can only see a maximum of 2^64 different
> >argument values; the 128-bit version can have as many as 2^128, and
> >there's not necessarily any way to wrap the 64-bit version so it gets
> >all 2^128 of them right.
>
> No. That is an argument for proper overflow checking, as much as
> anything. In your particular example, since C unsigned integers are
> specified the way that they are, with overflow detection forbidden,
> the negotiation should permit connexion of signed 128-bit to 64-bit
> (with overflow detection) and forbid the connexion of unsigned.

Then, with that prohibition, it's not a solution to this problem.
However, even if we were talking about intmax_t, I can easily specify a
function which should by definition never be capable of triggering
overflow. An implementation that causes a module compiled with an older
version to produce an overflow which could not possibly happen if it
were correctly translated using the newer version, does not qualify as
achieving full binary compatibility.

> >The whole purpose of choosing uintmax_t as an interface is to handle
> >arbitrarily large values correctly; that's not what happens if you use
> >this technique.
>
> That may be your intent, but is a mistaken use of uintmax_t; it is
> not specified to do that, not even within a single C program all
> compiled together. It is specified to be at least as large as a
> specific set of standard-defined types and no more.

The standard doesn't say "as large as", it says "capable of
representing"; uintmax_t can be smaller than the largest unsigned
integer type, if that type has padding bits and uintmax_t does not. It
doesn't restrict the set to standard-defined types; it says "any
unsigned integer type". Every valid unsigned integer-valued C expression
must by definition have a type from that set. Furthermore, every such
expression has a value that must be representable within that type, or
there's a constraint violation. Therefore, every such expression has a
value that can be stored in a uintmax_t object. That's a more precisely
statement of what I meant when I said "arbitrarily large values".

You suggest that this guarantee does not even hold for different parts
of a single C program all compiled together? On what grounds do you
suggest that?

Nick Maclaren

unread,
Jun 19, 2001, 9:54:27 AM6/19/01
to

In article <3B2F5141...@wizard.net>, "James Kuyper Jr." <kuy...@wizard.net> writes:
|> Nick Maclaren wrote:
|> >
|> > In article <3B2E8F56...@wizard.net>,
|> > James Kuyper Jr. <kuy...@wizard.net> wrote:
|> ...
|> > In 30+ years of using hundreds (perhaps thousands) of compilers and
|> > libraries, I cannot remember a single case where that sort of forward
|> > compatibility was supported. In every case, when a major change is
|>
|> That's entirely consistent with my claim that it's impossible to achieve
|> that kind of forward compatibility. Are we in agreement then?

Well, I suppose so. But I don't know why you are looking for a C
type to provide a facility that hasn't been provided in computing
history, and isn't likely to be.

|> > >The whole purpose of choosing uintmax_t as an interface is to handle
|> > >arbitrarily large values correctly; that's not what happens if you use
|> > >this technique.
|> >
|> > That may be your intent, but is a mistaken use of uintmax_t; it is
|> > not specified to do that, not even within a single C program all
|> > compiled together. It is specified to be at least as large as a
|> > specific set of standard-defined types and no more.
|>
|> The standard doesn't say "as large as", it says "capable of
|> representing"; uintmax_t can be smaller than the largest unsigned
|> integer type, if that type has padding bits and uintmax_t does not. It
|> doesn't restrict the set to standard-defined types; it says "any
|> unsigned integer type".

I was speaking loosely when saying "as large as". But it DOES restrict
it to standard-defined types - if you look at the definition of that
term in C99, they are a clearly defined extensible set. I said that
the set was specific, and not that there was an explicit list of types.

In particular, it has been pointed out by several people that it is
both permitted AND REASONABLE to have integer types much larger than
intmax_t, but that they would not be integer types as defined in the
standard. They would, however, have essentially all properties of
a C integer type other than that. Now, THOSE are not standard-defined
types.

|> Every valid unsigned integer-valued C expression
|> must by definition have a type from that set. Furthermore, every such
|> expression has a value that must be representable within that type, or
|> there's a constraint violation. Therefore, every such expression has a
|> value that can be stored in a uintmax_t object. That's a more precisely
|> statement of what I meant when I said "arbitrarily large values".

Well, it isn't what I understand by the term! Even ignoring bignums,
the type isn't required to be large enough to hold the maximum number
of bits in an array. Nor the number of characters in a file. Yet
they are perfectly well-defined (if not representable) values within
the standard.

Niklas Matthies

unread,
Jun 19, 2001, 10:19:39 AM6/19/01
to
On Tue, 19 Jun 2001 08:47:26 -0400, James Kuyper Jr. <kuy...@wizard.net> wrote:
> Niklas Matthies wrote:
> ...
> > That's right. But you are talking about a lack in the implementation
> > here. It's not a property of the binary interface. The original claim
> > was that changing uintmax_t necessarily breaks binary interface
> > compatibility. Which is not true.
>
> If a library module compiled with one version of the compiler cannot be
> substitituted for the same module compiled with a different version of
> the compiler without changing the observable behavior, then you have not
> achieved full binary interface compatibility.

But the proposed mechanism allows an implementation that does _not_
change the observable behavior.

-- Niklas Matthies

James Kuyper

unread,
Jun 19, 2001, 11:39:21 AM6/19/01
to
Nick Maclaren wrote:
>
> In article <3B2F5141...@wizard.net>, "James Kuyper Jr." <kuy...@wizard.net> writes:
> |> Nick Maclaren wrote:
> |> >
> |> > In article <3B2E8F56...@wizard.net>,
> |> > James Kuyper Jr. <kuy...@wizard.net> wrote:
...
> Well, I suppose so. But I don't know why you are looking for a C
> type to provide a facility that hasn't been provided in computing
> history, and isn't likely to be.

I'm not. I'm arguing that it's impossible to provide that facility, and
people seem to be disagreeing with me when I say that.

...


> I was speaking loosely when saying "as large as". But it DOES restrict
> it to standard-defined types - if you look at the definition of that
> term in C99, they are a clearly defined extensible set. I said that

The set of integer types is clearly extensible, and the meaning of that
set is defined byt the standard, as are restrictions on the properties
of the members. However, the specific entended types that are members of
that set are implementation-defined, not standard-defined. The standard
not define the names used to refer to those types, nor their specific
properties; it doesn't even specify whether there are any such types,
much less how many of them there are.

> In particular, it has been pointed out by several people that it is
> both permitted AND REASONABLE to have integer types much larger than
> intmax_t, but that they would not be integer types as defined in the
> standard. They would, however, have essentially all properties of
> a C integer type other than that. Now, THOSE are not standard-defined
> types.

Since they're not integer types, they're not relevant to my argument.

> |> Every valid unsigned integer-valued C expression
> |> must by definition have a type from that set. Furthermore, every such
> |> expression has a value that must be representable within that type, or
> |> there's a constraint violation. Therefore, every such expression has a
> |> value that can be stored in a uintmax_t object. That's a more precisely
> |> statement of what I meant when I said "arbitrarily large values".
>
> Well, it isn't what I understand by the term! Even ignoring bignums,
> the type isn't required to be large enough to hold the maximum number
> of bits in an array. Nor the number of characters in a file. Yet
> they are perfectly well-defined (if not representable) values within
> the standard.

I'll agree, I was exagerrating when I chose the phrase "arbitrarily
large". I can only plead lack of sleep as an excuse for that
exagerration.

James Kuyper

unread,
Jun 19, 2001, 11:57:36 AM6/19/01
to

You'll have to explain that to me; as far as I could tell the proposed
mechanism produces an overflow exception/signal, or some similar
behavior, whenever the caller calls the function with an argument that
is too big for the called function. That is NOT what the observed
behavior would have been if the called function had been re-compiled
using the same version of the compiler as was used to compile the
caller.

Note: I'm not saying that the function should produce the same behavior
when compiled with the new version as it did with the old. I'm saying
that the old version should produce the same behavior as the new one.
There's a subtle difference, in that the list of situations in which
they should produce the same result (and inherently can't) is much
larger when we're using the new version as the basis for comparison.
There are values which can be passed to function when it's compiled with
the new version of the compiler, which can't be passed to the function
when compiled with the old one, and therefore are intrisically incapable
of producing the same behavior except by accident.

In this particular case, unsigned rollover means that it doesn't even
produce the same result for all values that can be passed to the older
version, because the rollover occurs at different places. That's why
Nick amended his suggestion to prohibit its application to unsigned
types. However, you can produce the same effect by having the internal
calculations depend upon unsigned types with rollover, even if the
argument and the return value are both signed.

Niklas Matthies

unread,
Jun 19, 2001, 12:29:12 PM6/19/01
to
On Tue, 19 Jun 2001 11:57:36 -0400, James Kuyper <kuy...@wizard.net> wrote:
> Niklas Matthies wrote:
> > On Tue, 19 Jun 2001 08:47:26 -0400, James Kuyper Jr. <kuy...@wizard.net> wrote:
> > > Niklas Matthies wrote:
> > > ...
> > > > That's right. But you are talking about a lack in the implementation
> > > > here. It's not a property of the binary interface. The original claim
> > > > was that changing uintmax_t necessarily breaks binary interface
> > > > compatibility. Which is not true.
> > >
> > > If a library module compiled with one version of the compiler cannot be
> > > substitituted for the same module compiled with a different version of
> > > the compiler without changing the observable behavior, then you have not
> > > achieved full binary interface compatibility.
> >
> > But the proposed mechanism allows an implementation that does _not_
> > change the observable behavior.
>
> You'll have to explain that to me; as far as I could tell the proposed
> mechanism produces an overflow exception/signal, or some similar
> behavior, whenever the caller calls the function with an argument that
> is too big for the called function. That is NOT what the observed
> behavior would have been if the called function had been re-compiled
> using the same version of the compiler as was used to compile the
> caller.

You've either missed or misunderstood the following from my earlier
post:

With regard to the implementation issue, you can write the library
function with a bignum implementation alternative which it uses as
a fallback if it doesn't "natively" support the client's type.

I.e. the library function can be implemented in such a way that it can
handle arbitrarily large argument values. From the callee's
implementation perspective, the uintmax_t argument is effectively a
bignum -- but the calling code neither has to know nor has to care.
There only need to be some mechanism that tells the callee what the
caller thinks that uintmax_t is. (As has been said, this information
could be provided by the loader.)

What doesn't work--and I begin to suspect that's what you have in mind--
is to have the callee written in regular C expecting the argument in
one and only one fixed size.
But if you want to provide a library binary that is upward-compatible
for larger, future uintmax_t, and if the loader or linker provides some
way for the library code to determine the caller's uintmax_t size, then
it is certainly possible to do so, even for linking with multiple client
code with different notions of uintmax_t.

-- Niklas Matthies

James Kuyper

unread,
Jun 19, 2001, 1:23:32 PM6/19/01
to
Niklas Matthies wrote:
...

> What doesn't work--and I begin to suspect that's what you have in mind--
> is to have the callee written in regular C expecting the argument in
> one and only one fixed size.

That is correct. I have explicitly and repeatedly restricted my remarks
to fixed-size interfaces, and explicitly excluded bignums.

Niklas Matthies

unread,
Jun 19, 2001, 2:10:30 PM6/19/01
to

Well, the interface, as far as the client code is concerned, is
fixe-size. Or, in other words, it can be used like a fixed-size
interface by the client. If you will, it's an interface that is
polymorphic over all the possible fixed sizes. Besides the loader/
linker, it's only the callee that needs to take special measures.
The original concern, as I understood it, was that it was not possible
to provide libraries that are upward binary compatible with regard to
a growing uintmaxt_t. But given the presupposed loader/linker support,
it actually is possible to provide such libraries.

-- Niklas Matthies

David R Tribble

unread,
Jun 20, 2001, 12:05:54 AM6/20/01
to
[Apologies if this response is somewhat out of date; I just jumped into
this topic, which is somewhat backlogged on my system. -drt]

James Kuyper Jr. wrote:
> [...]


> How do you increase the range of numbers that can be passed to through a
> fixed interface?

One approach is to use typedefs of a fixed size (and range), combined with
version-specific API functions. Defined properly in your library header
files, you can arrange for the latest revision of the headers to cause the
client code to invoke the API with the lastest argument sizes/ranges, and
choose to support previous revision sizes/ranges. For example:

// mylib.h

typedef short Myint16;
typedef int Myint32;
typedef long Myint64;
typedef intmax_t Mymaxint; // This may change later

extern int myapi_1(Myint32 size, int op);
extern int myapi_2(Mymaxint size, int op);

#define myapi myapi_2 // Default to latest revision
...

Assuming the client calls myapi(), he should get a particular version of
that function (either myapi_1() or myapi_2()), which is coded to accept
arguments of specific sizes/ranges. The fact that client code always calls
a particular version of each API function allows you to control the
interface, and revise it if necessary.

There are many variations on this technique.

-- David R Tribble, mailto:da...@tribble.com --

James Kuyper Jr.

unread,
Jun 20, 2001, 8:35:30 AM6/20/01
to

That's not a physically fixed interface. It's a symbolically fixed
interface, but it still requires access to the latest version of the
library, which contains myapi_2(), in order for myapi() to handle any
values too larger for myapi_1(); it does not allow you to pass those
values to an older version of the library containing only myapi_1(), and
have them processed correctly.

I'm getting awfully tired of this discussion. Every solution that's been
suggested has been a solution to a different problem from the one I'm
claiming is insoluble. I'm quite familiar with every one of those
solutions, I've used most of them at one time or another; they're just
not applicable to this problem. I can't believe that people actually
believe it's soluble - I have to guess that they just don't understand
what problem I'm referring to. The problem I'm talking about involves an
interface where one side of the interface has already been compiled, and
cannot be recompiled or replaced, and that as compiled has limits on the
range of values it can accept. How do you send that function a value
outside that range, and have it process that value correctly?

People have been proposing lots of solutions that involve changing both
ends of the interface to one that can handle arbitrarily large values;
I'm not talking about being able to redesign the interface on the end
that has already been compiled. It accepts, for example, a single 32-bit
integer argument; not a pointer, not a bignum, not a varargs interface,
but a single 32-bit integer argument - how do you pass it a value too
large to fit in 32-bits?

People have been proposing what are effectively wrappers that will
accept numbers outside that range as arguments, but are intrinsically
incapable of actually passing those values to the wrapped function.
That's not a solution to this problem, but only a solution to the much
easier problem of making the already compiled module, with it's argument
range limitations intact, accessible through a different interface. It
does nothing to allow those range limitations to be transcended.

This is not a problem I've ever had to worry much about; the real-life
problems I've faced have always been one of the ones solvable by one of
the proposed alternative solutions. However, it's this problem, and only
this problem, which justifies the complaint about intmax_t that is the
basis of this thread. That complaint is inapplicable whenever any of the
other solutions can be used.

Niklas Matthies

unread,
Jun 20, 2001, 8:56:40 AM6/20/01
to
On Wed, 20 Jun 2001 08:35:30 -0400, James Kuyper Jr. <kuy...@wizard.net> wrote:
[毽愍

> People have been proposing lots of solutions that involve changing both
> ends of the interface to one that can handle arbitrarily large values;
> I'm not talking about being able to redesign the interface on the end
> that has already been compiled.

The thread was about uintmax_t, which is a new type, hence no existing
interface has to be redesigned; instead, the new interfaces which want
to use uintmax_t can be designed in a binary upward-compatible way,
along the lines that have been suggested in this thread.

Certainly everyone will agree that an interface using one fixed-size
type naturally has a fixed, limited range of values that can be passed
through that type. But, so what? No one disputed this in the first
place, and neither does it mean that uintmax_t is unfit for use in
binary interfaces.

-- Niklas Matthies

Fergus Henderson

unread,
Jun 21, 2001, 12:18:24 AM6/21/01
to
"James Kuyper Jr." <kuy...@wizard.net> writes:
>Fergus Henderson wrote:
>> James Kuyper <kuy...@wizard.net> writes:
>>
>> >If you need to retain binary compatibility across such boundaries, then
>> >you shouldn't be using uintmax_t for the interface.
>>
>> What should you use instead, then?
>
>If using a fixed interface is important, use a typename whose name
>describe the interface more specifically. For instance, if it must be 64
>bits, use one of the size-named types. If you need to be able to use a
>fixed-size type, need to be able to pass through that type any integer
>that can be stored in a fixed-size type, and need to retain binary
>compatibility across an increase in size of the maximum fixed-size type,
>your needs are fundamentally in conflict with each other, and there's
>nothing the standard can do to resolve that problem.

What is often needed (or at least strongly desired) by a large
group of application developers is
- to use a fixed-size type
[needed to avoid dynamic memory management]
- to be able to pass through that type any integer that can be
stored in another fixed-size type
[needed so that you can write a single routine that
handles any fixed-size integer type]
- to retain binary compatibility

This set of needs is not self-conflicting. It can be satisfied.
The way to satisfy it is by never changing the size of the maximum
fixed-size type.

I think that in cases where there is a desire from some users for
adding larger fixed-size types (e.g. for crypographic purposes),
in practice the set of needs above is likely to be more commercially
important in most environments, and so if larger fixed-size types are
added, they will be added without changing the size of intmax_t.

In practice these needs are not absolute, and software will eventually
be migrated to different ABIs. But that's a long-term solution;
in the medium-term, people will use fixed-size integer types which
are larger than intmax_t and may even invent some other typedef, e.g.
"int_really_max_t". Only when the cost of such hacks becomes
intolerable will people be willing to migrate to a different ABI.

Fergus Henderson

unread,
Jun 21, 2001, 12:34:45 AM6/21/01
to
Note that the future issues with intmax_t in C will be quite similar to
the current issue of wchar_t in C and the issue of Unicode in Java.
For Java, "char" was supposed to be a Unicode character, and Unicode
was supposed to be a "universal" character set. Unfortunately the JVM
has 16-bit "char", which makes it hard to support the recently published
Unicode 3.1 standard, which no longer fits in 16 bits. The "universalness"
of a Unicode character is a bit like the "maximumness" of intmax_t;
it's a difficult guarantee to enforce.

Fergus Henderson

unread,
Jun 21, 2001, 12:50:21 AM6/21/01
to
nm...@cus.cam.ac.uk (Nick Maclaren) writes:
>"James Kuyper Jr." <kuy...@wizard.net> writes:
>|> Nick Maclaren wrote:
>|> > f...@cs.mu.oz.au (Fergus Henderson) writes:
>|> > |> James Kuyper <kuy...@wizard.net> writes:
>|> > |>
>|> > |> >It is impossible for an interface using a fixed-size type [...]

>|> > |> >to retain binary compatibility if that type must continue to be
>|> > |> >the biggest integer type, even after the biggest integer type changes.
>|> > |>
>|> > |> Agreed.
>|> >
>|> > It's not impossible - it's just tricky.

What is wanted is for *all* interfaces using a fixed-size type to
retain binary compatibility.

>That is why sticking with 'long' as
>the longest type and maintaining binary compatibility in the C
>library is not a difficult task.

Retaining binary compatibility for just the *standard* C library is
certainly quite doable. The really difficult task is retaining binary
compatibility with all the *other* C libraries that programmers happened
to have compiled on the platform. "Impossible" may be too strong a word,
but I think "infeasible" is pretty close to the mark.

James Kuyper Jr.

unread,
Jun 21, 2001, 1:07:23 AM6/21/01
to
Fergus Henderson wrote:
>
> "James Kuyper Jr." <kuy...@wizard.net> writes:
> >Fergus Henderson wrote:
> >> James Kuyper <kuy...@wizard.net> writes:
> >>
> >> >If you need to retain binary compatibility across such boundaries, then
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

> >> >you shouldn't be using uintmax_t for the interface.
> >>
> >> What should you use instead, then?
> >
> >If using a fixed interface is important, use a typename whose name
> >describe the interface more specifically. For instance, if it must be 64
> >bits, use one of the size-named types. If you need to be able to use a
> >fixed-size type, need to be able to pass through that type any integer
> >that can be stored in a fixed-size type, and need to retain binary
^^^^^^^^^^^^^^^^^^^^^

> >compatibility across an increase in size of the maximum fixed-size type,

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

> >your needs are fundamentally in conflict with each other, and there's
> >nothing the standard can do to resolve that problem.
>
> What is often needed (or at least strongly desired) by a large
> group of application developers is
> - to use a fixed-size type
> [needed to avoid dynamic memory management]
> - to be able to pass through that type any integer that can be
> stored in another fixed-size type
> [needed so that you can write a single routine that
> handles any fixed-size integer type]
> - to retain binary compatibility
>
> This set of needs is not self-conflicting. It can be satisfied.
> The way to satisfy it is by never changing the size of the maximum
> fixed-size type.

You are correct; there is no internal conflict in those needs. My list
included one need which you apparently claim these developer don't share
- the need to retain binary compatibility across an increase in the size
of the maximum fixed-size type. You're postulating that such an increase
can be prevented. In that case, there'd be no need to retain binary
compatibility across it. If you don't have that need, my advice does not
apply, and I've said as much from the beginning.

I don't believe it's possible to maintain such a limit indefinitely,
though it might be possible to do so for a limited period of time. I
certainly don't think that the standard should do so - it would be
contrary to the spirit of C to constrain implementations that way.

It is loading more messages.
0 new messages