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
    #1
    1. Advertising

  2. 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
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Feb 28, 2008
    #2
    1. Advertising

  3. Pete Becker Guest

    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
    #3
  4. Joe Greer Guest

    wrote in news:e6da1a2b-2561-4623-89a7-8303394cb7f9
    @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
     
    Joe Greer, Feb 28, 2008
    #4
  5. Pete Becker Guest

    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
    #5
  6. 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
    #6
  7. 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
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Feb 28, 2008
    #7
  8. James Kanze Guest

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

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

    --
    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
    #8
  9. James Kanze Guest

    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
    #9
  10. 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
    #10
  11. 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
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Feb 28, 2008
    #11
  12. 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
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Feb 28, 2008
    #12
  13. 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
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Feb 28, 2008
    #13
  14. 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
    #14
  15. 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
    #15
  16. Pete Becker Guest

    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
    #16
  17. Pete Becker Guest

    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
    #17
  18. 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
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Feb 28, 2008
    #18
  19. 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
    #19
  20. Pete Becker Guest

    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
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John Goche
    Replies:
    8
    Views:
    16,575
  2. Howard Hinnant

    Re: size_t ... standards

    Howard Hinnant, Jun 29, 2003, in forum: C++
    Replies:
    5
    Views:
    3,585
    Jim Fischer
    Jun 30, 2003
  3. Howard Hinnant

    Re: size_t ... standards

    Howard Hinnant, Jun 29, 2003, in forum: C++
    Replies:
    0
    Views:
    858
    Howard Hinnant
    Jun 29, 2003
  4. Alex Vinokur
    Replies:
    9
    Views:
    832
    James Kanze
    Oct 13, 2008
  5. Alex Vinokur
    Replies:
    1
    Views:
    611
Loading...

Share This Page