size_t literals?

J

jacek.dziedzic

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.
 
V

Victor Bazarov

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
 
P

Pete Becker

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.
 
J

Joe Greer

(e-mail address removed) wrote in @k2g2000hse.googlegroups.com:
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
 
P

Pete Becker

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.
 
J

Juha Nieminen

Pete said:
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?
 
V

Victor Bazarov

Juha said:
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
 
J

James Kanze

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).

And of course, unless your compiler already implements C++0x, or
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.)
 
J

James Kanze

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

And that long long will have at least 64 bits.
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.
 
I

Ioannis Vranos

Victor said:
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.
 
V

Victor Bazarov

James said:
[..]
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
 
V

Victor Bazarov

Ioannis said:
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
 
I

Ioannis Vranos

Pete said:
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.
 
I

Ioannis Vranos

Victor said:
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.
 
P

Pete Becker

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.
 
P

Pete Becker

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.
 
V

Victor Bazarov

Pete said:
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
 
I

Ioannis Vranos

Pete said:
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).
 

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

size_t Question 9
size_t in C++ 0
size_t, ssize_t and ptrdiff_t 56
size_t in inttypes.h 4
The problem with size_t 45
size_t problems 466
64 bit C++ and OS defined types 71
size of bitfieds / strange warning 12

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top