size_t literals?

Discussion in 'C++' started by jacek.dziedzic@gmail.com, Feb 28, 2008.

1. Guest

Hi!

On a machine where size_t is 64-bit, unsigned long is 32-bit, how
does one construct a size_t literal that says 2^32? Typing in

size_t x = 4294967296UL;

complains about the value being too large for unsigned long
(obviously, it's too large by one).

The nonstandard suffices "UI64" are also not recognized by the
compiler.

Should I construct with a value of 4294967295UL and then increment
the size_t variable?

TIA,
- J.

, Feb 28, 2008

2. Victor BazarovGuest

wrote:
> On a machine where size_t is 64-bit, unsigned long is 32-bit, how
> does one construct a size_t literal that says 2^32? Typing in
>
> size_t x = 4294967296UL;
>
> complains about the value being too large for unsigned long
> (obviously, it's too large by one).
>
> The nonstandard suffices "UI64" are also not recognized by the
> compiler.
>
> Should I construct with a value of 4294967295UL and then increment
> the size_t variable?

Since the representation of 'size_t' is not dictated by the language,
you do what your implementation allows. If your 'size_t' is 64 bits,
then you need to find the type that would do what you need. Perhaps
a double. Maybe an unsigned long long?

size_t x = 4294967296ULL;

Another possibility is to get 2^16 value and square it:

size_t x = (size_t)(1 << 16) * (size_t)(1 << 16);

and hope that the compiler will be able to simplify it and make it
a value instead of a run-time expression.

V
--

Victor Bazarov, Feb 28, 2008

3. Pete BeckerGuest

On 2008-02-28 09:32:01 -0800, said:

>
> Hi!
>
> On a machine where size_t is 64-bit, unsigned long is 32-bit, how
> does one construct a size_t literal that says 2^32? Typing in
>
> size_t x = 4294967296UL;
>
> complains about the value being too large for unsigned long
> (obviously, it's too large by one).

Presumably this was a warning. The compiler is obliged to convert the
value to a suitable type, despite the suffix, and your code should
work as you expect it to.

>
> The nonstandard suffices "UI64" are also not recognized by the
> compiler.

The future standard will use ULL, or any other mix of cases for those
three letters.

>
> Should I construct with a value of 4294967295UL and then increment
> the size_t variable?

No.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Pete Becker, Feb 28, 2008
4. Joe GreerGuest

wrote in news:e6da1a2b-2561-4623-89a7-8303394cb7f9

>
> Hi!
>
> On a machine where size_t is 64-bit, unsigned long is 32-bit, how
> does one construct a size_t literal that says 2^32? Typing in
>
> size_t x = 4294967296UL;
>
> complains about the value being too large for unsigned long
> (obviously, it's too large by one).
>
> The nonstandard suffices "UI64" are also not recognized by the
> compiler.
>
> Should I construct with a value of 4294967295UL and then increment
> the size_t variable?
>
> TIA,
> - J.
>

What about the soon to be standard specifier of ULL? Otherwise, the math
method should work.

joe

Joe Greer, Feb 28, 2008
5. Pete BeckerGuest

On 2008-02-28 10:39:05 -0800, "Victor Bazarov" <> said:

> wrote:
>> On a machine where size_t is 64-bit, unsigned long is 32-bit, how
>> does one construct a size_t literal that says 2^32? Typing in
>>
>> size_t x = 4294967296UL;
>>
>> complains about the value being too large for unsigned long
>> (obviously, it's too large by one).
>>
>> The nonstandard suffices "UI64" are also not recognized by the
>> compiler.
>>
>> Should I construct with a value of 4294967295UL and then increment
>> the size_t variable?

>
> Since the representation of 'size_t' is not dictated by the language,
> you do what your implementation allows. If your 'size_t' is 64 bits,
> then you need to find the type that would do what you need. Perhaps
> a double. Maybe an unsigned long long?

Under the C99 rules and the C++0x rules, if unsigned long is too small
for a literal whose suffix is UL (i.e. unsigned long), the compiler
treats it as a literal of type unsigned long long. If unsigned long
long is too small, there's a problem, but in this case, it looks like
it's just what's needed.

The suffix tells the compiler the smallest type that you want; if the
value fits, you get that type. If the value is too large for that type,
you get a larger type. See [lex.icon]/2.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Pete Becker, Feb 28, 2008
6. Juha NieminenGuest

Pete Becker wrote:
> The future standard will use ULL, or any other mix of cases for those
> three letters.

Will it guarantee that
sizeof(unsigned long long) > sizeof(unsigned long)?

Or will ULL be defined as "postfix for literals with the same size as
size_t"? If not, why can't they define such a thing?

Juha Nieminen, Feb 28, 2008
7. Victor BazarovGuest

Juha Nieminen wrote:
> Pete Becker wrote:
>> The future standard will use ULL, or any other mix of cases for those
>> three letters.

>
> Will it guarantee that
> sizeof(unsigned long long) > sizeof(unsigned long)?

No, it will only guarangee

sizeof(unsigned long long) >= sizeof(unsigned long)

> Or will ULL be defined as "postfix for literals with the same size as
> size_t"? If not, why can't they define such a thing?

There is no standard-defined literal of type 'std::size_t' because
it's not a fundamental type. 'std::size_t' is defined in <cstddef>.
It is most likely a typedef. Of course it can be a synonym to some
kind of implementation-specific type (like uint64_t), see the
compiler documentation.

V
--

Victor Bazarov, Feb 28, 2008
8. James KanzeGuest

On Feb 28, 6:32 pm, wrote:

> On a machine where size_t is 64-bit, unsigned long is 32-bit, how
> does one construct a size_t literal that says 2^32? Typing in

> size_t x = 4294967296UL;

> complains about the value being too large for unsigned long
> (obviously, it's too large by one).

On a future conforming compiler, 4294967296ULL should do the
trick for this. Still, the next version of the standard will
allow size_t to be a typedef to an extended integral type, which
might well be longer than long long. And in that case, there is
no way you can simply create literals of that type (although
constant expressions are possible, e.g. (uintmax_t)1 << 200).

parts of it, as an extension, size_t can't be larger than
unsigned long, so there is no problem. (To tell the truth, I
can't imagine a compiler vendor being stupid enough not to make
long 64 bits if the hardware supported it.)

> The nonstandard suffices "UI64" are also not recognized by the
> compiler.

> Should I construct with a value of 4294967295UL and then
> increment the size_t variable?

You should be able to get around the problem with a constant
expression and a few casts, e.g. (uintmax_t)1 << 32, or some
such. (If the compiler doesn't support uintmax_t, then of
course, size_t can't be larger than unsigned long.)

--
James Kanze (GABI Software) email:
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

James Kanze, Feb 28, 2008
9. James KanzeGuest

On Feb 28, 8:26 pm, "Victor Bazarov" <> wrote:
> Juha Nieminen wrote:
> > Pete Becker wrote:
> >> The future standard will use ULL, or any other mix of cases for those
> >> three letters.

> > Will it guarantee that
> > sizeof(unsigned long long) > sizeof(unsigned long)?

> No, it will only guarangee

> sizeof(unsigned long long) >= sizeof(unsigned long)

And that long long will have at least 64 bits.

> > Or will ULL be defined as "postfix for literals with the same size as
> > size_t"? If not, why can't they define such a thing?

> There is no standard-defined literal of type 'std::size_t' because
> it's not a fundamental type. 'std::size_t' is defined in <cstddef>.
> It is most likely a typedef. Of course it can be a synonym to some
> kind of implementation-specific type (like uint64_t), see the
> compiler documentation.

In C++03, it must be a typedef to a standard unsigned integral
type: unsigned char, unsigned short, unsigned int or unsigned
long. There are no other choices. Which means that anything
you can represent with the suffix UL will fit in it.

In C++0x, of course, you have unsigned long long and the
extended integral types as possibilities as well. For unsigned
long long, the suffix ULL does the trick; if size_t is a typedef
to uint128_t, however, and long long is only 64 bits (the legal
minimum), you're out of luck.

--
James Kanze (GABI Software) email:
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

James Kanze, Feb 28, 2008
10. Ioannis VranosGuest

Victor Bazarov wrote:
>
> Since the representation of 'size_t' is not dictated by the language,
> you do what your implementation allows. If your 'size_t' is 64 bits,
> then you need to find the type that would do what you need. Perhaps
> a double. Maybe an unsigned long long?

There isn't such type under current ISO C++ 2003.

Ioannis Vranos, Feb 28, 2008
11. Victor BazarovGuest

James Kanze wrote:
> [..] (To tell the truth, I
> can't imagine a compiler vendor being stupid enough not to make
> long 64 bits if the hardware supported it.)

Just imagine Microsoft.

> [..]

V
--

Victor Bazarov, Feb 28, 2008
12. Victor BazarovGuest

James Kanze wrote:
> On Feb 28, 8:26 pm, "Victor Bazarov" <> wrote:
>> [..]
>> There is no standard-defined literal of type 'std::size_t' because
>> it's not a fundamental type. 'std::size_t' is defined in <cstddef>.
>> It is most likely a typedef. Of course it can be a synonym to some
>> kind of implementation-specific type (like uint64_t), see the
>> compiler documentation.

>
> In C++03, it must be a typedef to a standard unsigned integral
> type: unsigned char, unsigned short, unsigned int or unsigned
> long. There are no other choices. Which means that anything
> you can represent with the suffix UL will fit in it.

I can't see any proof of that. Could you please point me to the
relevant portion of the Standard that would state that 'size_t'
"must be a typedef to a standard unsigned ..." Thanks!

> [..]

V
--

Victor Bazarov, Feb 28, 2008
13. Victor BazarovGuest

Ioannis Vranos wrote:
> Victor Bazarov wrote:
>>
>> Since the representation of 'size_t' is not dictated by the language,
>> you do what your implementation allows. If your 'size_t' is 64 bits,
>> then you need to find the type that would do what you need. Perhaps
>> a double. Maybe an unsigned long long?

>
>
> There isn't such type under current ISO C++ 2003.

Yes, you're correct. There isn't. Neither would a double suffice
under the current standard (where only 6 digits of precision are
required for it). That's not the point. The OP's compiler may be
advanced enough beyond C++03 and/or provide unsigned long long as
an extension.

V
--

Victor Bazarov, Feb 28, 2008
14. Ioannis VranosGuest

Pete Becker wrote:
> On 2008-02-28 10:39:05 -0800, "Victor Bazarov" <>
> said:
>
>> wrote:
>>> On a machine where size_t is 64-bit, unsigned long is 32-bit, how
>>> does one construct a size_t literal that says 2^32? Typing in
>>>
>>> size_t x = 4294967296UL;
>>>
>>> complains about the value being too large for unsigned long
>>> (obviously, it's too large by one).
>>>
>>> The nonstandard suffices "UI64" are also not recognized by the
>>> compiler.
>>>
>>> Should I construct with a value of 4294967295UL and then increment
>>> the size_t variable?

>>
>> Since the representation of 'size_t' is not dictated by the language,
>> you do what your implementation allows. If your 'size_t' is 64 bits,
>> then you need to find the type that would do what you need. Perhaps
>> a double. Maybe an unsigned long long?

>
> Under the C99 rules and the C++0x rules, if unsigned long is too small
> for a literal whose suffix is UL (i.e. unsigned long), the compiler
> treats it as a literal of type unsigned long long. If unsigned long long
> is too small, there's a problem, but in this case, it looks like it's
> just what's needed.

C99 is off topic, C++0x is not finalised and thus there is not any
"C++0x" conforming compiler, since it is not a standard yet.

I think the real answer for the OP size_t x= size_t(4294967296);

Of course this code is implementation-specific.

Ioannis Vranos, Feb 28, 2008
15. Ioannis VranosGuest

Victor Bazarov wrote:
> Ioannis Vranos wrote:
>> Victor Bazarov wrote:
>>> Since the representation of 'size_t' is not dictated by the language,
>>> you do what your implementation allows. If your 'size_t' is 64 bits,
>>> then you need to find the type that would do what you need. Perhaps
>>> a double. Maybe an unsigned long long?

>>
>> There isn't such type under current ISO C++ 2003.

>
> Yes, you're correct. There isn't. Neither would a double suffice
> under the current standard (where only 6 digits of precision are
> required for it). That's not the point. The OP's compiler may be
> advanced enough beyond C++03 and/or provide unsigned long long as
> an extension.

AFAIK size_t being 64 bit and unsigned long being 32-bit, comply with
C++03. So he can just use

size_t(4294967296);

Of course this expression is implementation specific.

Ioannis Vranos, Feb 28, 2008
16. Pete BeckerGuest

On 2008-02-28 11:26:48 -0800, "Victor Bazarov" <> said:

> Juha Nieminen wrote:
>> Pete Becker wrote:
>>> The future standard will use ULL, or any other mix of cases for those
>>> three letters.

>>
>> Will it guarantee that
>> sizeof(unsigned long long) > sizeof(unsigned long)?

>
> No, it will only guarangee
>
> sizeof(unsigned long long) >= sizeof(unsigned long)

And, for pedancy's sake, it will require that unsigned long long is at
least 32 bits. Which doesn't respond to the question of whether it must
be larger than unsigned long, but completes what the standard will
require.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Pete Becker, Feb 28, 2008
17. Pete BeckerGuest

On 2008-02-28 14:06:39 -0800, Ioannis Vranos
<> said:

> Pete Becker wrote:
>> On 2008-02-28 10:39:05 -0800, "Victor Bazarov" <> said:
>>
>>> wrote:
>>>> On a machine where size_t is 64-bit, unsigned long is 32-bit, how
>>>> does one construct a size_t literal that says 2^32? Typing in
>>>>
>>>> size_t x = 4294967296UL;
>>>>
>>>> complains about the value being too large for unsigned long
>>>> (obviously, it's too large by one).
>>>>
>>>> The nonstandard suffices "UI64" are also not recognized by the
>>>> compiler.
>>>>
>>>> Should I construct with a value of 4294967295UL and then increment
>>>> the size_t variable?
>>>
>>> Since the representation of 'size_t' is not dictated by the language,
>>> you do what your implementation allows. If your 'size_t' is 64 bits,
>>> then you need to find the type that would do what you need. Perhaps
>>> a double. Maybe an unsigned long long?

>>
>> Under the C99 rules and the C++0x rules, if unsigned long is too small
>> for a literal whose suffix is UL (i.e. unsigned long), the compiler
>> treats it as a literal of type unsigned long long. If unsigned long
>> long is too small, there's a problem, but in this case, it looks like
>> it's just what's needed.

>
>
> C99 is off topic, C++0x is not finalised and thus there is not any
> "C++0x" conforming compiler, since it is not a standard yet.

Nevertheless, the answer to this question lies, in part, in the C99 and
C++0x standards. Neither is off topic or irrelevant here.

>
> I think the real answer for the OP size_t x= size_t(4294967296);
>
> Of course this code is implementation-specific.

The original code should work just fine, as should your version. I see
nothing implementation-specific in yours.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Pete Becker, Feb 28, 2008
18. Victor BazarovGuest

Pete Becker wrote:
> On 2008-02-28 11:26:48 -0800, "Victor Bazarov"
> <> said:
>> Juha Nieminen wrote:
>>> Pete Becker wrote:
>>>> The future standard will use ULL, or any other mix of cases for
>>>> those three letters.
>>>
>>> Will it guarantee that
>>> sizeof(unsigned long long) > sizeof(unsigned long)?

>>
>> No, it will only guarangee
>>
>> sizeof(unsigned long long) >= sizeof(unsigned long)

>
> And, for pedancy's sake, it will require that unsigned long long is at
> least 32 bits.

Not 64? Hmm in C99 unsigned long long int is (2^64 - 1)...

> Which doesn't respond to the question of whether it
> must be larger than unsigned long, but completes what the standard will
> require.

V
--

Victor Bazarov, Feb 28, 2008
19. Ioannis VranosGuest

Pete Becker wrote:
>
>> I think the real answer for the OP size_t x= size_t(4294967296);
>>
>> Of course this code is implementation-specific.

>
> The original code should work just fine, as should your version.

Mine gives the feeling of a size_t constant.

> I see
> nothing implementation-specific in yours.

If 4294967296 is larger than numeric_limits<size_t>::max(), then the
value will wrap around, if the code gets compiled.

In my system for the code:

#include <iostream>
#include <cstddef>

int main(void)
{
using namespace std;

size_t x= size_t(4294967296);

cout<< x<< endl;
}

gives the compilation error:

[john@localhost src]\$ g++ main.cc -o foobar-cpp
main.cc:9: error: integer constant is too large for ‘long’ type
[john@localhost src]\$

while

#include <iostream>
#include <cstddef>

int main(void)
{
using namespace std;

cout<< numeric_limits<size_t>::max()<< endl;
}

gives:

[john@localhost src]\$ ./foobar-cpp
4294967295
[john@localhost src]\$

(The value that the OP wants minus 1).

Ioannis Vranos, Feb 28, 2008
20. Pete BeckerGuest

On 2008-02-28 14:27:46 -0800, "Victor Bazarov" <> said:

> Pete Becker wrote:
>> On 2008-02-28 11:26:48 -0800, "Victor Bazarov"
>> <> said:
>>> Juha Nieminen wrote:
>>>> Pete Becker wrote:
>>>>> The future standard will use ULL, or any other mix of cases for
>>>>> those three letters.
>>>>
>>>> Will it guarantee that
>>>> sizeof(unsigned long long) > sizeof(unsigned long)?
>>>
>>> No, it will only guarangee
>>>
>>> sizeof(unsigned long long) >= sizeof(unsigned long)

>>
>> And, for pedancy's sake, it will require that unsigned long long is at
>> least 32 bits.

>
> Not 64? Hmm in C99 unsigned long long int is (2^64 - 1)...

64 is right. Sorry.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Pete Becker, Feb 28, 2008