Topic: Making C++ integer types more orthogonal


Author: usenet-nospam@nmhq.net (Niklas Matthies)
Date: Thu, 5 Oct 2006 04:30:05 GMT
Raw View
On 2006-10-04 22:33, John Nagle wrote:
:
>     If C++ detected overflow, like Java does, this sort
> of thing would be much more reasonable.  But the C and
> C++ worlds are historically rather casual about integer overflow.

FWIW, Java does not detect overflow, it implements two's complement
modulo semantics.

-- Niklas Matthies

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: musiphil@bawi.org (Seungbeom Kim)
Date: Thu, 5 Oct 2006 15:02:27 GMT
Raw View
John Nagle wrote:
>
> The classic example is
>
>     unsigned i,j;
>     int k;
>
>     k = i - j;
>
> which is undefined behavior if i<j, because (i-j) is
> "unsigned" and cannot contain a negative value.

True, (i - j) is unsigned and cannot contain a negative value,
but its value is very well defined to follow the modulo arithmetic.
It is the assignment to k that may cause overflow and undefined
behaviour, where (i - j) may have a larger value than INT_MAX.
If you assigned (i - j) to an unsigned, there would be no UB there.

--
Seungbeom Kim

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: bop@gmb.dk ("Bo Persson")
Date: Thu, 5 Oct 2006 16:19:47 GMT
Raw View
John Nagle wrote:
> kanze wrote:
>> Agreed, but doing so now would break just about every program in
>> existance.  And while it would be better, the gain isn't that
>> great.  So the cost benefits analysis says:
>>
>>   + slightly more elegant
>>   - breaks 99.9% of existing code.
>>
>> Somehow, I don't think it's going to fly.
>
>    I know.
>
>    I'd proposed a better approach to integer types years ago, but
> the
> backwards compatibility problem was too much.
>
>    My main concern was intermediate temporaries.  If you write
>
> uint32_t i,j,k,m,n,p;
>
> m = (i*j)/k;
>
> what should the size of "(i*j)" be?  I proposed that the
> implementation must choose the size of temporaries such that, unless
> overflow will occur in the final result, it will not occur in a
> temporary.
>     So, in this case, "(i * j)" would be a 64-bit value.

What if there isn't a 64-bit value available to the compiler?

>
>     Most of the ordinary cases, like
>
> m = i + j + k;
>
> don't require an extra-large temporary value, because if you get
> overflow in a subexpression, you'll get overflow in the final
> result.

But that doesn't hold for

m = i + j - k;

so how would you solve that?

> This is a numeric distinction, not a lexical one.
> Internally, the implementation should be carrying along upper
> and lower bounds for each value and computing the bounds for
> each result based on the properties of the operator.

Isn't it the programmer's responsibilty to consider the ranges of the
possible values used in a program, rather than the compiler's job to
consider the type's maximum ranges?

>
>    Some expressions have to be rejected.  Consider
>
> m = (i * j * k) / (n * p);
>
> This requires 96 or 128 bit integers to do safely.  If
> those aren't available, the compiler would have to report
> an error.

And that would break the remaining 0.1% of existing code.

> The user would then have to write something like
>
> m = uint32_t(i * j * k) / (n * p);
>
> which would force the computation down to 32 bits.

Don't you think it would be more reasonable to have the programmer
force conputations *up* where needed insetad?

Bo Persson


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "kanze" <kanze@gabi-soft.fr>
Date: Fri, 6 Oct 2006 12:08:53 CST
Raw View
Seungbeom Kim wrote:
> John Nagle wrote:

> > The classic example is

> >     unsigned i,j;
> >     int k;

> >     k = i - j;

> > which is undefined behavior if i<j, because (i-j) is
> > "unsigned" and cannot contain a negative value.

> True, (i - j) is unsigned and cannot contain a negative value,
> but its value is very well defined to follow the modulo
> arithmetic.  It is the assignment to k that may cause overflow
> and undefined behaviour,

Not undefined, implementation defined.  Overflow when using an
arithmetic operator is undefined behavior, but the results of
converting a value when the value doesn't fit in the target type
is implementation defined (but can be, at least according to the
C standard, an implementation defined signal).

--
James Kanze                                           GABI Software
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "kanze" <kanze@gabi-soft.fr>
Date: Tue, 3 Oct 2006 10:06:56 CST
Raw View
Tommi H   yn   l   nmaa wrote:
> Jack Klein kirjoitti:
> > Are you proposing instantiation of this template with
> > arbitrary values of 'N', or only values which the underlying
> > hardware supports?

> With arbitrary values of N.

Exact length, presumably, or...

Are you proposing that an implementation must support something
like Integer<17>.

> > If the former, what you are asking for can be a large amount
> > of implementation effort.

> > If the latter, what do these templates do for you that the
> > C99 exact width integer types do not?  These will soon be
> > (if they are not already) part of the C++ standard.  It is
> > quite easy to put together a <stdint.h> header for those
> > required C99 types that your C++ implementation supports.
> > Although I suppose it would be deprecated and <cstdint>
> > would be preferred, to put the templates only in the std
> > namespace.  Have you looked at the C solution?

> > In what way is unsigned_integer<32> better than uint32_t?

> Typedefs like uint32_t are fine and they could be implemented
> in terms of the integer templates. BTW, I don't like the "_t"
> suffix. It makes code a bit ugly.

Never the less, it is the standard C (and C++) convention for a
typename defined by means of a typedef.  (In the case of C++, it
is also used for one built-in type, wchar_t.  But only because
that type was a typedef in C.)

Note too that in C, int32_t is not guaranteed to be present
(since a system might not support 32 bit integers in hardware),
and that if it is present, the representation is also guaranteed
to be 2's complement.

> > Actually, there have been, and still are, some architectures
> > where int is not the optimal integer size, but merely the
> > best available that meets the requirements of the standard.

> Anyway, int would be the integer type that is somehow best or
> optimal for the platform. I don't know if there is already
> some requirement for the minimum width of int in the C++
> standard. IMHO there should be.

At least 16 bits.  (The actual specification is rather that it
must be able to represent all values in the range
-32767..32767.  And that it use a binary representation.)

> ..

> > Are you the proposing banning (un)signed char, short, int,
> > long, etc., from the language once these templates are
> > added?  That would break a huge amount of existing code.

> They would not be banned but deprecated.

They are, never the less, very useful.  I almost never need an
exact size, just something big enough.  If I say short, I know
that the performance penalty won't be too excessive.  If I say
Integer<16>, it could be.

> >> 2. Support for integer types for very large values.
> >> Currently the largest available integer type has usually 32
> >> or 64 bits.

> > There are already libraries available that support arbitrary
> > precision integer types.  I am sure that at least some of
> > these wrap their support in classes or templates.  Given the
> > current lack of support for the export keyword in the
> > language, you face a very real chance of the overhead of
> > operators for, say, 1024 bit integer types being included in
> > every object module of a program that instantiated that
> > type.

> Code bloat can be avoided by implementing the integer
> templates directly in the compiler.

Code bloat is code bloat, regardless of whether the compiler
generates it or not.

> Integer arithmetics is practically always implemented by
> inlined machine language code.

Yes, because C++ lets the implementation choose the appropriate
sizes.  On my machines, for example, Integer<17> or Integer<143>
are definitly going to require extra code.  On some other
machines, Integer<16> and Integer<32> could be the problems.

> Of course, when N in large some subroutines would be needed
> but these can be put into a single library.

Not just when N is large.

> The integer templates should be built-in into the compiler
> also in order to allow full optimization of the code that uses
> them, i.e. the code should be as fast as that using
> non-template integer types.

> >> Also there should be a built-in typedef

> >>    typedef long double long_double

> >> to make type modifiers unnecessary for the floating point types, too.

> > What is wrong with providing such a typedef yourself?

> It should be in the standard C++ library.

> > What I fail to see from your suggestion is what gain do you
> > perceive for the standard integer types, other than
> > esthetics?

> Orthogonality and support for integer types with arbitrary
> width.

I'll admit that I don't see it.  The naming conventions could be
more rational---I especially don't like long long.  But they're
not the end of the world, and your solution doesn't seem
realistic.  And you've not addresses a number of issues, like
integral promotions, conversions, etc.

If orthogonality were the only criteria, I'd propose:

 -- two basic integral types, signed and unsigned;
 -- six size modifiers: long, longer, longest and short,
    shorter, shortest (that should suffice);
 -- character types are not integral types, but separate (and
    don't support), a char with three modifiers: wide, narrow
    and medium, plain char is a synonym for char with one of
    these modifiers;
 -- a similar policy for floating point, with float (which would
    correspond to today's double in most cases), and the same
    modifiers as for ints.

Of course, the advantages gained compared to the current
situation are small, and certainly not worth the cost of
breaking compatibility.

> > Does it provide any benefits other than removal of the type
> > modifiers?

> Removal of type modifiers makes the language more orthogonal.

I don't see why.  The current modifiers are the results of
history, and aren't always very orthogonal (although I find
short and long a pretty good choice of vocabulary), but that's
because they have a history, not because they are modifiers.

--
James Kanze                                           GABI Software
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: M.Kronenburg@inter.nl.net ("Maarten Kronenburg")
Date: Tue, 3 Oct 2006 17:31:37 GMT
Raw View
Tommi,
Last july I proposed an infinite precision integer, see
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2020.pdf
In my opinion the template parameter is unnecessary,
because the length of the integer should be as long as needed
to hold its value. Otherwise you also have the problem of overflows.
Also every programmer would choose his own length and it would
be impossible to mix the template types.
Note that also the GMP class wrapper mpz_class does not have
a template parameter, see the GMP manual.
Regards, Maarten.

"Tommi H=F6yn=E4l=E4nmaa" <tommi.hoynalanmaa@iki.fi> wrote in message
news:%8TTg.24165$TD1.1488@reader1.news.jippii.net...

Currently C++ has a set of predefined signed integer and unsigned
integer types. The sizes of integer types may vary across different
platforms. The syntax used for naming the integer types (type modifiers)
can't be used for user defined types (type names like "unsigned int" and
"long int").

So I suggest introduction of two new built-in template classes

   integer<N>

and

   unsigned_integer<N>

where N is a template argument taking positive integer values. N is the
size of the integer type in bits.
Variables of type integer<N> would take values in range
-2^(N-1)-1 ... 2^(N-1) and variables of type unsigned_integer<N> in
range 0 ... 2^N - 1.

Type int shall still be the optimal integer size for the platform. It
could be defined by a typedef using the integer template.
There shall be a typedef unsigned_int that is defined with template
unsigned_integer. This typedef shall be the unsigned integer type
containing the same number of bits as int.

There would be the following benefits:
1. Orthogonality: The integer template classes use the standard C++
template syntax. The type modifiers, which can't be used in user defined
classes, are not used.
2. Support for integer types for very large values. Currently the
largest available integer type has usually 32 or 64 bits.

Also there should be a built-in typedef

   typedef long double long_double

to make type modifiers unnecessary for the floating point types, too.

--
Tommi H=F6yn=E4l=E4nmaa
s=E4hk=F6posti / e-mail: tommi.hoynalanmaa@iki.fi
kotisivu / homepage: http://www.iki.fi/tohoyn/

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Gennaro Prota <gennaro_prota@yahoo.com>
Date: Tue, 3 Oct 2006 12:38:36 CST
Raw View
On Tue,  3 Oct 2006 10:06:56 CST, "kanze" <kanze@gabi-soft.fr> wrote:

>Tommi H   yn   l   nmaa wrote:
>> Jack Klein kirjoitti:
>> > Are you proposing instantiation of this template with
>> > arbitrary values of 'N', or only values which the underlying
>> > hardware supports?
>
>> With arbitrary values of N.
>
>Exact length, presumably, or...
>
>Are you proposing that an implementation must support something
>like Integer<17>.

Incidentally, limiting to the types actually supported by the
implementation it's trivial to implement an integral< n > template
whose nested 'typedef type' (to follow a common metaprogramming
practice) resolves to the appropriate type (I mean that it can be done
portably, with the code actually *determining* what the correct type
is --possibly out of several choices with the same width).

--
Gennaro Prota

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: tommi.hoynalanmaa@iki.fi (=?ISO-8859-1?Q?Tommi_H=F6yn=E4l=E4nmaa?=)
Date: Tue, 3 Oct 2006 18:30:52 GMT
Raw View
kanze kirjoitti:
>=20
> Exact length, presumably, or...
>=20
> Are you proposing that an implementation must support something
> like Integer<17>.

Yes.

..
>=20
> Note too that in C, int32_t is not guaranteed to be present
> (since a system might not support 32 bit integers in hardware),
> and that if it is present, the representation is also guaranteed
> to be 2's complement.

How can we guarantee that any fixed size integer type has hardware=20
support in all platforms? I think every fixed size integer type has the=20
same problem.

>=20
>> Anyway, int would be the integer type that is somehow best or
>> optimal for the platform. I don't know if there is already
>> some requirement for the minimum width of int in the C++
>> standard. IMHO there should be.
>=20
> At least 16 bits.  (The actual specification is rather that it
> must be able to represent all values in the range
> -32767..32767.  And that it use a binary representation.)

There could be another integer type (a typedef in the standard library)=20
that is guaranteed to be at least 32 bits. Often 16 bits is not enough.
I suppose that this would be the same as current "long".

>=20
>> ..
>=20
>>> Are you the proposing banning (un)signed char, short, int,
>>> long, etc., from the language once these templates are
>>> added?  That would break a huge amount of existing code.
>=20
>> They would not be banned but deprecated.
>=20
> They are, never the less, very useful.  I almost never need an
> exact size, just something big enough.  If I say short, I know
> that the performance penalty won't be too excessive.  If I say
> Integer<16>, it could be.

There could be typedefs in the standard library that are specified to=20
have some minimum width.

>> Code bloat can be avoided by implementing the integer
>> templates directly in the compiler.
>=20
> Code bloat is code bloat, regardless of whether the compiler
> generates it or not.
>=20
>> Integer arithmetics is practically always implemented by
>> inlined machine language code.
>=20
> Yes, because C++ lets the implementation choose the appropriate
> sizes.  On my machines, for example, Integer<17> or Integer<143>
> are definitly going to require extra code.  On some other
> machines, Integer<16> and Integer<32> could be the problems.
>=20
>> Of course, when N in large some subroutines would be needed
>> but these can be put into a single library.
>=20
> Not just when N is large.

Subroutines for integer arithmetic with arbitrary N could take N as an=20
ordinary argument (in the stack). This would eliminate code bloat=20
completely when a little intelligence is added to the compilers so that=20
they handle the integer templates specially.

>=20
>>> What I fail to see from your suggestion is what gain do you
>>> perceive for the standard integer types, other than
>>> esthetics?
>=20
>> Orthogonality and support for integer types with arbitrary
>> width.
>=20
> I'll admit that I don't see it.  The naming conventions could be
> more rational---I especially don't like long long.  But they're
> not the end of the world, and your solution doesn't seem
> realistic.  And you've not addresses a number of issues, like
> integral promotions, conversions, etc.
>=20
> If orthogonality were the only criteria, I'd propose:
>=20
>  -- two basic integral types, signed and unsigned;
>  -- six size modifiers: long, longer, longest and short,
>     shorter, shortest (that should suffice);
>  -- character types are not integral types, but separate (and
>     don't support), a char with three modifiers: wide, narrow
>     and medium, plain char is a synonym for char with one of
>     these modifiers;

Character types should indeed be separate from integer types.

>  -- a similar policy for floating point, with float (which would
>     correspond to today's double in most cases), and the same
>     modifiers as for ints.
>=20
> Of course, the advantages gained compared to the current
> situation are small, and certainly not worth the cost of
> breaking compatibility.
>=20
..
>=20
>> Removal of type modifiers makes the language more orthogonal.
>=20
> I don't see why.  The current modifiers are the results of
> history, and aren't always very orthogonal (although I find
> short and long a pretty good choice of vocabulary), but that's
> because they have a history, not because they are modifiers.
>=20

Type modifiers can't be used in user defined types. Hence removing (or=20
deprecating) them would increase orthogonality.

--=20
Tommi H=F6yn=E4l=E4nmaa
s=E4hk=F6posti / e-mail: tommi.hoynalanmaa@iki.fi
kotisivu / homepage: http://www.iki.fi/tohoyn/

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: tommi.hoynalanmaa@iki.fi (=?ISO-8859-1?Q?Tommi_H=F6yn=E4l=E4nmaa?=)
Date: Tue, 3 Oct 2006 18:32:18 GMT
Raw View
Maarten Kronenburg kirjoitti:
> Tommi,
> Last july I proposed an infinite precision integer, see
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2020.pdf
> In my opinion the template parameter is unnecessary,
> because the length of the integer should be as long as needed
> to hold its value.

Infinite precision integers are a different thing and they should also=20
be supported in the standard library.

Fixed size integer types are essential for efficient code (in cases=20
where the speed of integer computations has real significance).
For example, in a 32-bit architecture you can usually add two 32-bit=20
integers with one machine language instruction.

> Otherwise you also have the problem of overflows.

As regards overflows the integer templates behave as ordinary fixed size=20
integer types. They follow the rules of 2's complement arithmetic.

> Also every programmer would choose his own length and it would
> be impossible to mix the template types.

There could be an implicit conversion from integer<N1> to integer<N2>=20
where N1 < N2 and similar implicit conversion for unsigned_integer.

> Note that also the GMP class wrapper mpz_class does not have
> a template parameter, see the GMP manual.

--=20
Tommi H=F6yn=E4l=E4nmaa
s=E4hk=F6posti / e-mail: tommi.hoynalanmaa@iki.fi
kotisivu / homepage: http://www.iki.fi/tohoyn/

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: M.Kronenburg@inter.nl.net ("Maarten Kronenburg")
Date: Tue, 3 Oct 2006 22:01:20 GMT
Raw View
Tommi,
In certain special cases the fixed length integer
may be faster than the infinite precision integer.
But when mixing different fixed lengths with implicit
conversion, then using different fixed lengths is slower,
because implicit conversion to a larger fixed length
would always imply a memory allocation and copy.
So the performance you win, you may loose
somewhere else.
Regards, Maarten.

"Tommi H=F6yn=E4l=E4nmaa" <tommi.hoynalanmaa@iki.fi> wrote in message
news:6mxUg.25482$WW6.2451@reader1.news.jippii.net...
Maarten Kronenburg kirjoitti:
> Tommi,
> Last july I proposed an infinite precision integer, see
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2020.pdf
> In my opinion the template parameter is unnecessary,
> because the length of the integer should be as long as needed
> to hold its value.

Infinite precision integers are a different thing and they should also
be supported in the standard library.

Fixed size integer types are essential for efficient code (in cases
where the speed of integer computations has real significance).
For example, in a 32-bit architecture you can usually add two 32-bit
integers with one machine language instruction.

> Otherwise you also have the problem of overflows.

As regards overflows the integer templates behave as ordinary fixed size
integer types. They follow the rules of 2's complement arithmetic.

> Also every programmer would choose his own length and it would
> be impossible to mix the template types.

There could be an implicit conversion from integer<N1> to integer<N2>
where N1 < N2 and similar implicit conversion for unsigned_integer.

> Note that also the GMP class wrapper mpz_class does not have
> a template parameter, see the GMP manual.

--
Tommi H=F6yn=E4l=E4nmaa
s=E4hk=F6posti / e-mail: tommi.hoynalanmaa@iki.fi
kotisivu / homepage: http://www.iki.fi/tohoyn/

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: Tue, 3 Oct 2006 18:16:25 CST
Raw View
In article <6mxUg.25482$WW6.2451@reader1.news.jippii.net>, Tommi
H   yn   l   nmaa <tommi.hoynalanmaa@iki.fi> writes
>Infinite precision integers are a different thing and they should also
>be supported in the standard library.
I think you are confusing 'unlimited precision' wit 'infinite precision'
The former seems achievable at least in theory, the later seems out of
bounds to me.

--
Francis Glassborow      ACCU
Author of 'You Can Do It!' and "You Can Program in C++"
see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: wkaras@yahoo.com
Date: Wed, 4 Oct 2006 10:04:18 CST
Raw View
Tommi H   yn   l   nmaa wrote:
> Currently C++ has a set of predefined signed integer and unsigned
> integer types. The sizes of integer types may vary across different
> platforms. The syntax used for naming the integer types (type modifiers)
> can't be used for user defined types (type names like "unsigned int" and
> "long int").
..

If you follow this logic:

if (precision > 32 bits)
    use long long
else if (precision > 16 bits)
    use long
else if (fast access more important than min size)
    use int
else if (precision > 8 bits)
    use short
else
    use char

I think the standard guarantees your code will be portable (not sure
about "long long").

Why do so many people feel this is inadequate?  Are there lots of
compliers that have defined "long" to be 64 bits?

I dislike the modifier use because of the ugly conversions that result
( static_cast<unsigned char>(x) as opposed to int(x) ).


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "kanze" <kanze@gabi-soft.fr>
Date: Wed, 4 Oct 2006 10:04:14 CST
Raw View
Tommi H   yn   l   nmaa wrote:
> kanze kirjoitti:

> > Exact length, presumably, or...

> > Are you proposing that an implementation must support something
> > like Integer<17>.

> Yes.

> ..

> > Note too that in C, int32_t is not guaranteed to be present
> > (since a system might not support 32 bit integers in hardware),
> > and that if it is present, the representation is also guaranteed
> > to be 2's complement.

> How can we guarantee that any fixed size integer type has
> hardware support in all platforms?

We can't.  That's why whether the type is present or not is
implementation defined in C.

Looking at it, there's actually a defect here in the C standard:
from    7.18.1.1:

    The typedef name intN_t designates a signed integer type
    with width N, no padding bits, and a two's complement
    representation.

    [...]

    These types are optional. However, if an implementation
    provides integer types with widths of 8, 16, 32, or 64 bits,
    it shall define the corresponding typedef names.

What is an implementation with 32 bit one's complement supposed
to do?  It provides an integer type with width of 32, so it is
requiremd to define int32_t... to a signed integer type with
width 32, no padding bits, and a two's complement
representation.  (If anyone here is involved with the C
standard committee, I think a defect report would be in order.)

Of course, it's not a problem in practice, since the only one's
complement machine on the market has 36 bit integers.

> I think every fixed size integer type has the same problem.

> >> Anyway, int would be the integer type that is somehow best or
> >> optimal for the platform. I don't know if there is already
> >> some requirement for the minimum width of int in the C++
> >> standard. IMHO there should be.

> > At least 16 bits.  (The actual specification is rather that it
> > must be able to represent all values in the range
> > -32767..32767.  And that it use a binary representation.)

> There could be another integer type (a typedef in the standard library)
> that is guaranteed to be at least 32 bits.

There is.  It's called long.

    [...]
> > If orthogonality were the only criteria, I'd propose:

> >  -- two basic integral types, signed and unsigned;
> >  -- six size modifiers: long, longer, longest and short,
> >     shorter, shortest (that should suffice);
> >  -- character types are not integral types, but separate (and
> >     don't support), a char with three modifiers: wide, narrow
> >     and medium, plain char is a synonym for char with one of
> >     these modifiers;

> Character types should indeed be separate from integer types.

Agreed, but doing so now would break just about every program in
existance.  And while it would be better, the gain isn't that
great.  So the cost benefits analysis says:

  + slightly more elegant
  - breaks 99.9% of existing code.

Somehow, I don't think it's going to fly.

--
James Kanze                                           GABI Software
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: jdennett@acm.org (James Dennett)
Date: Wed, 4 Oct 2006 16:02:52 GMT
Raw View
wkaras@yahoo.com wrote:
> Tommi H=F6yn=E4l=E4nmaa wrote:
>> Currently C++ has a set of predefined signed integer and unsigned
>> integer types. The sizes of integer types may vary across different
>> platforms. The syntax used for naming the integer types (type modifier=
s)
>> can't be used for user defined types (type names like "unsigned int" a=
nd
>> "long int").
> ..
>=20
> If you follow this logic:
>=20
> if (precision > 32 bits)
>     use long long
> else if (precision > 16 bits)
>     use long
> else if (fast access more important than min size)
>     use int
> else if (precision > 8 bits)
>     use short
> else
>     use char
>=20
> I think the standard guarantees your code will be portable (not sure
> about "long long").
>=20
> Why do so many people feel this is inadequate?  Are there lots of
> compliers that have defined "long" to be 64 bits?

Yes; almost all "64-bit" platforms have made long 64 bits,
the same size as their pointers.

> I dislike the modifier use because of the ugly conversions that result
> ( static_cast<unsigned char>(x) as opposed to int(x) ).

You don't write static_cast for the better readability and
checkability anyway? ;-)

-- James

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: kuyper@wizard.net
Date: Wed, 4 Oct 2006 11:03:22 CST
Raw View
wkaras@yahoo.com wrote:
.
> Why do so many people feel this is inadequate?  Are there lots of
> compliers that have defined "long" to be 64 bits?

I don't know about "lots" - I have personal knowledge of only a limited
variety of compilers. However, there are certainly some that do so. The
IRIX C compiler is the one I use most frequently, and in 64-bit mode
(the one we use most frequently), 'long' is a 64-bit type.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: kuyper@wizard.net
Date: Wed, 4 Oct 2006 14:15:13 CST
Raw View
kanze wrote:
> Tommi H   yn   l   nmaa wrote:
> > kanze kirjoitti:
..
> Looking at it, there's actually a defect here in the C standard:
> from    7.18.1.1:
>
>     The typedef name intN_t designates a signed integer type
>     with width N, no padding bits, and a two's complement
>     representation.
>
>     [...]
>
>     These types are optional. However, if an implementation
>     provides integer types with widths of 8, 16, 32, or 64 bits,
>     it shall define the corresponding typedef names.
>
> What is an implementation with 32 bit one's complement supposed
> to do?  It provides an integer type with width of 32, so it is
> requiremd to define int32_t... to a signed integer type with
> width 32, no padding bits, and a two's complement
> representation.  (If anyone here is involved with the C
> standard committee, I think a defect report would be in order.)

One was filed, and has been resolved in a TR. I can't cite the revised
wording, but I believe that it was revised to require a typedef for
intN_t only if the implementation provides a 2's complement N-bit type
with no padding.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: nagle@animats.com (John Nagle)
Date: Wed, 4 Oct 2006 22:33:18 GMT
Raw View
kanze wrote:
> Agreed, but doing so now would break just about every program in
> existance.  And while it would be better, the gain isn't that
> great.  So the cost benefits analysis says:
>
>   + slightly more elegant
>   - breaks 99.9% of existing code.
>
> Somehow, I don't think it's going to fly.

    I know.

    I'd proposed a better approach to integer types years ago, but the
backwards compatibility problem was too much.

    My main concern was intermediate temporaries.  If you write

 uint32_t i,j,k,m,n,p;

 m = (i*j)/k;

what should the size of "(i*j)" be?  I proposed that the implementation
must choose the size of temporaries such that, unless overflow will occur
in the final result, it will not occur in a temporary.

     So, in this case, "(i * j)" would be a 64-bit value.

     Most of the ordinary cases, like

 m = i + j + k;

don't require an extra-large temporary value, because if you get
overflow in a subexpression, you'll get overflow in the final
result.  This is a numeric distinction, not a lexical one.
Internally, the implementation should be carrying along upper
and lower bounds for each value and computing the bounds for
each result based on the properties of the operator.

    Some expressions have to be rejected.  Consider

 m = (i * j * k) / (n * p);

This requires 96 or 128 bit integers to do safely.  If
those aren't available, the compiler would have to report
an error.  The user would then have to write something like

 m = uint32_t(i * j * k) / (n * p);

which would force the computation down to 32 bits.

    If C++ detected overflow, like Java does, this sort
of thing would be much more reasonable.  But the C and
C++ worlds are historically rather casual about integer overflow.

    I orignally thought this up during the 16 to 32 bit transition
in the 1980s, when overflows in 16-bit intermediate values were a
real problem.  Today, it's less of an issue.

    If you want to address this problem, though, think of it
in numerical terms, not lexical terms. Thinking of it
in lexical terms results in wierd numerical semantics that
lead to wrong answers.  The classic example is

 unsigned i,j;
 int k;

 k = i - j;

which is undefined behavior if i<j, because (i-j) is
"unsigned" and cannot contain a negative value.  That's
what comes of using a linguistic model instead of a numeric
one.

(Those semantics broke TCP sequence number
arithmetic in the initial release of 4.3BSD, resulting
in random TCP connection failures when the sequence numbers
were in the upper half of the unsigned number space.
Sometimes this stuff really matters.)

    John Nagle
    Animats

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: tommi.hoynalanmaa@iki.fi (=?ISO-8859-1?Q?Tommi_H=F6yn=E4l=E4nmaa?=)
Date: Sun, 1 Oct 2006 22:53:15 GMT
Raw View
Currently C++ has a set of predefined signed integer and unsigned=20
integer types. The sizes of integer types may vary across different=20
platforms. The syntax used for naming the integer types (type modifiers)=20
can't be used for user defined types (type names like "unsigned int" and=20
"long int").

So I suggest introduction of two new built-in template classes

   integer<N>

and

   unsigned_integer<N>

where N is a template argument taking positive integer values. N is the=20
size of the integer type in bits.
Variables of type integer<N> would take values in range
-2^(N-1)-1 ... 2^(N-1) and variables of type unsigned_integer<N> in=20
range 0 ... 2^N - 1.

Type int shall still be the optimal integer size for the platform. It=20
could be defined by a typedef using the integer template.
There shall be a typedef unsigned_int that is defined with template=20
unsigned_integer. This typedef shall be the unsigned integer type=20
containing the same number of bits as int.

There would be the following benefits:
1. Orthogonality: The integer template classes use the standard C++=20
template syntax. The type modifiers, which can't be used in user defined=20
classes, are not used.
2. Support for integer types for very large values. Currently the=20
largest available integer type has usually 32 or 64 bits.

Also there should be a built-in typedef

   typedef long double long_double

to make type modifiers unnecessary for the floating point types, too.

--=20
Tommi H=F6yn=E4l=E4nmaa
s=E4hk=F6posti / e-mail: tommi.hoynalanmaa@iki.fi
kotisivu / homepage: http://www.iki.fi/tohoyn/

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: jackklein@spamcop.net (Jack Klein)
Date: Mon, 2 Oct 2006 04:57:33 GMT
Raw View
On Sun,  1 Oct 2006 22:53:15 GMT, tommi.hoynalanmaa@iki.fi (Tommi
H=F6yn=E4l=E4nmaa) wrote in comp.std.c++:

>=20
> Currently C++ has a set of predefined signed integer and unsigned=20
> integer types. The sizes of integer types may vary across different=20
> platforms. The syntax used for naming the integer types (type modifiers=
)=20
> can't be used for user defined types (type names like "unsigned int" an=
d=20
> "long int").
>=20
> So I suggest introduction of two new built-in template classes
>=20
>    integer<N>
>=20
> and
>=20
>    unsigned_integer<N>
>=20
> where N is a template argument taking positive integer values. N is the=
=20
> size of the integer type in bits.
> Variables of type integer<N> would take values in range
> -2^(N-1)-1 ... 2^(N-1) and variables of type unsigned_integer<N> in=20
> range 0 ... 2^N - 1.

Are you proposing instantiation of this template with arbitrary values
of 'N', or only values which the underlying hardware supports?

If the former, what you are asking for can be a large amount of
implementation effort.

If the latter, what do these templates do for you that the C99 exact
width integer types do not?  These will soon be (if they are not
already) part of the C++ standard.  It is quite easy to put together a
<stdint.h> header for those required C99 types that your C++
implementation supports.  Although I suppose it would be deprecated
and <cstdint> would be preferred, to put the templates only in the std
namespace.  Have you looked at the C solution?

In what way is unsigned_integer<32> better than uint32_t?

> Type int shall still be the optimal integer size for the platform. It=20
> could be defined by a typedef using the integer template.
> There shall be a typedef unsigned_int that is defined with template=20
> unsigned_integer. This typedef shall be the unsigned integer type=20
> containing the same number of bits as int.

Actually, there have been, and still are, some architectures where int
is not the optimal integer size, but merely the best available that
meets the requirements of the standard.

> There would be the following benefits:
> 1. Orthogonality: The integer template classes use the standard C++=20
> template syntax. The type modifiers, which can't be used in user define=
d=20
> classes, are not used.

Are you the proposing banning (un)signed char, short, int, long, etc.,
from the language once these templates are added?  That would break a
huge amount of existing code.

> 2. Support for integer types for very large values. Currently the=20
> largest available integer type has usually 32 or 64 bits.

There are already libraries available that support arbitrary precision
integer types.  I am sure that at least some of these wrap their
support in classes or templates.  Given the current lack of support
for the export keyword in the language, you face a very real chance of
the overhead of operators for, say, 1024 bit integer types being
included in every object module of a program that instantiated that
type.

> Also there should be a built-in typedef
>=20
>    typedef long double long_double
>=20
> to make type modifiers unnecessary for the floating point types, too.

What is wrong with providing such a typedef yourself?

What I fail to see from your suggestion is what gain do you perceive
for the standard integer types, other than esthetics?  Does it provide
any benefits other than removal of the type modifiers?  How will it
make my programs compile or run faster or better?

--=20
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: AlbertoBarbati@libero.it (Alberto Ganesh Barbati)
Date: Mon, 2 Oct 2006 14:32:26 GMT
Raw View
Tommi H=F6yn=E4l=E4nmaa ha scritto:
>=20
> Currently C++ has a set of predefined signed integer and unsigned=20
> integer types. The sizes of integer types may vary across different=20
> platforms. The syntax used for naming the integer types (type modifiers=
)=20
> can't be used for user defined types (type names like "unsigned int" an=
d=20
> "long int").
>=20
> So I suggest introduction of two new built-in template classes
>=20
>   integer<N>
>=20
> and
>=20
>   unsigned_integer<N>
>=20

Have a look at Boost.Integer:

http://boost.org/libs/integer/integer.htm

Ganesh

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: tommi.hoynalanmaa@iki.fi (=?ISO-8859-1?Q?Tommi_H=F6yn=E4l=E4nmaa?=)
Date: Mon, 2 Oct 2006 16:27:32 GMT
Raw View
Jack Klein kirjoitti:
> Are you proposing instantiation of this template with arbitrary values
> of 'N', or only values which the underlying hardware supports?

With arbitrary values of N.

>=20
> If the former, what you are asking for can be a large amount of
> implementation effort.
>=20
> If the latter, what do these templates do for you that the C99 exact
> width integer types do not?  These will soon be (if they are not
> already) part of the C++ standard.  It is quite easy to put together a
> <stdint.h> header for those required C99 types that your C++
> implementation supports.  Although I suppose it would be deprecated
> and <cstdint> would be preferred, to put the templates only in the std
> namespace.  Have you looked at the C solution?
>=20
> In what way is unsigned_integer<32> better than uint32_t?

Typedefs like uint32_t are fine and they could be implemented in terms=20
of the integer templates. BTW, I don't like the "_t" suffix. It makes=20
code a bit ugly.

> Actually, there have been, and still are, some architectures where int
> is not the optimal integer size, but merely the best available that
> meets the requirements of the standard.
>=20

Anyway, int would be the integer type that is somehow best or optimal=20
for the platform. I don't know if there is already some requirement for=20
the minimum width of int in the C++ standard. IMHO there should be.

..
>=20
> Are you the proposing banning (un)signed char, short, int, long, etc.,
> from the language once these templates are added?  That would break a
> huge amount of existing code.

They would not be banned but deprecated.

>=20
>> 2. Support for integer types for very large values. Currently the=20
>> largest available integer type has usually 32 or 64 bits.
>=20
> There are already libraries available that support arbitrary precision
> integer types.  I am sure that at least some of these wrap their
> support in classes or templates.  Given the current lack of support
> for the export keyword in the language, you face a very real chance of
> the overhead of operators for, say, 1024 bit integer types being
> included in every object module of a program that instantiated that
> type.

Code bloat can be avoided by implementing the integer templates directly=20
in the compiler. Integer arithmetics is practically always implemented=20
by inlined machine language code. Of course, when N in large some=20
subroutines would be needed but these can be put into a single library.
The integer templates should be built-in into the compiler also in order=20
to allow full optimization of the code that uses them, i.e. the code=20
should be as fast as that using non-template integer types.

>=20
>> Also there should be a built-in typedef
>>
>>    typedef long double long_double
>>
>> to make type modifiers unnecessary for the floating point types, too.
>=20
> What is wrong with providing such a typedef yourself?

It should be in the standard C++ library.

>=20
> What I fail to see from your suggestion is what gain do you perceive
> for the standard integer types, other than esthetics?=20

Orthogonality and support for integer types with arbitrary width.

> Does it provide
> any benefits other than removal of the type modifiers?=20

Removal of type modifiers makes the language more orthogonal.

> How will it
> make my programs compile or run faster or better?
>=20

In case you have a 32-bit machine and need 128-bit integer types.=20
However, the orthogonality of a programming language is important issue=20
alone.

--=20
Tommi H=F6yn=E4l=E4nmaa
s=E4hk=F6posti / e-mail: tommi.hoynalanmaa@iki.fi
kotisivu / homepage: http://www.iki.fi/tohoyn/

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]