C99 integer types

E

Eric Sosman

[...]
I didn't want to imply that I had any problem with the added complexity
(and don't think I had): I understand very well that there's a real need to
specify in detail how these sorts of conversions need to work.

However, I think it only works as expected if the signed integer type is a
two's complement type. 6.2.6.2s2 allows for three representations, two of
which won't work as expected when ULONG_MAX + 1 is "repeatedly added" as in
6.3.1.3p2.

In what way are your expectations taken aback? I expect (for
example) that negative one will convert to ULONG_MAX, no matter
how the negative one is represented, that negative two will give
ULONG_MAX-1, that zero will give zero, seven seven, and so on.
I've never worked with hardware that had anything other than two's
complement integers, but that is what I meant with the
"implementation-defined" bit.

I worked (very briefly and not in C) with a ones'-complement
Univac machine, back in the 1970's. Before that, I worked with a
signed-magnitude machine -- but it worked in decimal, not binary,
and definitely had no C implementation!

In recent years ("recent" meaning "since sometime in the Ford
administration") I've seen only two's-complement platforms. They're
the wave of the present.
 
R

Ronald Landheer-Cieslak

Eric Sosman said:
[...]
I didn't want to imply that I had any problem with the added complexity
(and don't think I had): I understand very well that there's a real need to
specify in detail how these sorts of conversions need to work.

However, I think it only works as expected if the signed integer type is a
two's complement type. 6.2.6.2s2 allows for three representations, two of
which won't work as expected when ULONG_MAX + 1 is "repeatedly added" as in
6.3.1.3p2.

In what way are your expectations taken aback? I expect (for
example) that negative one will convert to ULONG_MAX, no matter
how the negative one is represented, that negative two will give
ULONG_MAX-1, that zero will give zero, seven seven, and so on.
Hmmm. On first reading I though negative 0 in one's complement would yield
1 after conversion, but while writing the example out I found my bug (it
would yield zero)...

Same thing for sign and magnitude...

It's the footnote (49) that really clarifies it: "The rules describe the
arithmetic on the mathematical value...".

So, my bad :)

rlc
 
J

James Kuyper

Yes. That and the fact that due to the addition in 6.3.1.3p2 the result
differs on systems depending how signed integers are implemented (i.e. it
works as expected only for two's complement signed integers).

given:

int s_ul_comp(short i, unsigned long ul)
{
return i < ul;
}

If i < 0 that function will return a value of 1 if and only if the
mathematical value of ULONG_MAX + 1 + i is less than the value of ul.
That value depends only upon the values of i, ul, and ULONG_MAX. It does
not depend in any way upon whether 2's complement is used to represent
the signed values involved in that calculation.
 
T

Tim Rentsch

James Kuyper said:
OK, so it basically formalizes the conversions that the integer types goes
through to end up with either something useful or something
implementation-defined, or both.

Reading the draft Barry pointed to, it doesn't seem to actually change any
of the rules as they were before - just formalize them, is that right?

I believe that integer conversion rank was put into the very first
version of the C standard, nearly a quarter century ago. [snip]

A reasonable guess, but it wasn't.
 
T

Tim Rentsch

Eric Sosman said:
[... reformatted for legibility ...]
In <stdint.h> the follow types are defined:

typedef unsigned int uint_fast32_t;
typedef uint32_t uint_least32_t;
typedef unsigned long uint32_t; [..snip..]

Any insight in to the selection process for establishing the
underlying data types for the fixed, minimum and fastest width
types would be great.

If by "fixed" you mean "exact-width" (7.20.1.1), the selection
is straightforward: The implementation declares a type of exactly
the specified width (if it has one) that uses two's complement (for
signed exact-width types). If there's more than one such type,
the implementation can use any of them. The choices for uintN_t
and intN_t are independent: One might be `unsigned long' while the
other is `__builtin_twos_complement_32'. [snip]

Actually the choices for corresponding types in <stdint.h> are
not independent. If either is supplied then both must be, and
the unsigned type must be the unsigned type corresponding to the
signed type, and vice versa.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top