From: Ulrich Eckhardt on
Hi!

Following code, paraphrased from Boost[1] puzzles me a bit:

#if BOOST_HAS_LONG_LONG
size_t const npos = static_cast<size_t>(~0ULL);
#else
size_t const npos = static_cast<size_t>(~0UL);
#endif

What I wonder is if one couldn't simply write this:

size_t const npos = ~static_cast<size_t>(0);

I'm aware of the fact that using

size_t const npos = ~0;

might not work because '0' is an int and that might be smaller than a
size_t. However, truncating the largest possible integer to a size_t is a
waste on 32 bit platforms with long long support. Also, I think size_t is
unsigned (correct me if I'm wrong!) and the almost idiomatic way to get the
largest value of an unsigned integer is

size_t const npos = size_t(-1);

or is there a reason not to do this? How about using numeric_limits, btw?

So I wonder if there's some corner case I didn't consider and above code is
just an undocumented workaround...

thanks

Uli

[1] Boost 1.33.1, in libs/regex/src/cregex.cpp


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: dan2online on
Ulrich Eckhardt wrote:
> Hi!
>
> Following code, paraphrased from Boost[1] puzzles me a bit:
>
> #if BOOST_HAS_LONG_LONG
> size_t const npos = static_cast<size_t>(~0ULL);
> #else
> size_t const npos = static_cast<size_t>(~0UL);
> #endif

It is portable for all 32/64 bit data models.

>
> What I wonder is if one couldn't simply write this:
>
> size_t const npos = ~static_cast<size_t>(0);

I think it is acceptable unless your compiler complains it.

>
> I'm aware of the fact that using
>
> size_t const npos = ~0;
>
> might not work because '0' is an int and that might be smaller than a
> size_t. However, truncating the largest possible integer to a size_t is a
> waste on 32 bit platforms with long long support. Also, I think size_t is

On 64-bit systems, size_t may be a different data type to int.

> unsigned (correct me if I'm wrong!) and the almost idiomatic way to get the
> largest value of an unsigned integer is
>
> size_t const npos = size_t(-1);
>
> or is there a reason not to do this? How about using numeric_limits, btw?
>

You assume 2' complement.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Vladimir Marko on
dan2online wrote:
> Ulrich Eckhardt wrote:
> > Hi!
> >
> > Following code, paraphrased from Boost[1] puzzles me a bit:
> >
> > #if BOOST_HAS_LONG_LONG
> > size_t const npos = static_cast<size_t>(~0ULL);
> > #else
> > size_t const npos = static_cast<size_t>(~0UL);
> > #endif
> [...]
> > Also, I think size_t is
> > unsigned (correct me if I'm wrong!) and the almost idiomatic way to get the
> > largest value of an unsigned integer is
> >
> > size_t const npos = size_t(-1);
> >
> > or is there a reason not to do this? How about using numeric_limits, btw?
> >
>
> You assume 2' complement.

There is no such assumption. 4.7/2 defines the result of the conversion
to an unsigned integer type as congruent to the source value modulo
2^n where n is the number of bits of the _destination_ type. Since
size_t is unsigned (by inclusion from the C standard), size_t(-1) shall
be the largest value of type size_t (unless the size_t in question is
not the std::size_t).

Vladimir Marko


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: dan2online on
Vladimir Marko wrote:

> There is no such assumption. 4.7/2 defines the result of the conversion
> to an unsigned integer type as congruent to the source value modulo
> 2^n where n is the number of bits of the _destination_ type. Since
> size_t is unsigned (by inclusion from the C standard), size_t(-1) shall
> be the largest value of type size_t (unless the size_t in question is

There is no standard for data type size_t, and the actual size of
size_t is architecture-dependent. The assumption of size_t as an
unsigned integer will lead to programming errors for 64bit
architecture.

Only 2 complement and size_t defined as unsigned, size_t(-1) is the
largest value of type size_t.

> not the std::size_t).

size_t is not explicit std::size_t in the original post. size_t also
doesn't mean unsigned int.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Martin Bonner on

dan2online wrote:
> Vladimir Marko wrote:
>
> > There is no such assumption. 4.7/2 defines the result of the conversion
> > to an unsigned integer type as congruent to the source value modulo
> > 2^n where n is the number of bits of the _destination_ type. Since
> > size_t is unsigned (by inclusion from the C standard), size_t(-1) shall
> > be the largest value of type size_t (unless the size_t in question is
>
> There is no standard for data type size_t,
No, but the standard imposes some constraints. Specifically, it is
unsigned, and it is integral.
> and the actual size of
> size_t is architecture-dependent.
True.
> The assumption of size_t as an
> unsigned integer will lead to programming errors for 64bit
> architecture.
Assuming that size_t is <code>unsigned int</code> will lead to errors.
However, the standard assures us that it will be an integer, and that
it will be unsigned.
>
> Only 2 complement and size_t defined as unsigned, size_t(-1) is the
> largest value of type size_t.
Not so (I assume you meant "Only in that case that ..., will size_t(-1)
....". As explained above, the standard defines the conversion from a
signed int (like -1) to /any/ unsigned integer type. On a
two-complement machine that degenerates to a no-op if the length is
unchanged, but on a sign-and-magnitude machine the compiler will
generate the appropriate code.

> > not the std::size_t).
>
> size_t is not explicit std::size_t in the original post. size_t also
> doesn't mean unsigned int.
But it does mean unsigned something.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

 |  Next  |  Last
Pages: 1 2 3 4
Prev: Global Variables
Next: std::ws