defining the size_t type

Discussion in 'C Programming' started by lubomir dobsik, Oct 25, 2007.

  1. hi, i have seen an interesting thing:

    #if sizeof((char*)0 - (char*)0) == sizeof(unsigned int)
    typedef unsigned int size_t;
    #elif sizeof((char*)0 - (char*)0) == sizeof(unsigned long)
    typedef unsigned long size_t;
    #elif sizeof((char*)0 - (char*)0) == sizeof(unsigned long long)
    typedef unsigned long long size_t;
    #endif

    is this way of defining the size_t portable?

    cheers, lubos
     
    lubomir dobsik, Oct 25, 2007
    #1
    1. Advertising

  2. lubomir dobsik

    santosh Guest

    lubomir dobsik wrote:

    > hi, i have seen an interesting thing:
    >
    > #if sizeof((char*)0 - (char*)0) == sizeof(unsigned int)
    > typedef unsigned int size_t;
    > #elif sizeof((char*)0 - (char*)0) == sizeof(unsigned long)
    > typedef unsigned long size_t;
    > #elif sizeof((char*)0 - (char*)0) == sizeof(unsigned long long)
    > typedef unsigned long long size_t;
    > #endif
    >
    > is this way of defining the size_t portable?


    As far as I know sizeof cannot be used with the conditional compilation
    directives. This may be a compiler specific extension.
     
    santosh, Oct 25, 2007
    #2
    1. Advertising

  3. lubomir dobsik

    Eric Sosman Guest

    lubomir dobsik wrote On 10/25/07 10:42,:
    > hi, i have seen an interesting thing:
    >
    > #if sizeof((char*)0 - (char*)0) == sizeof(unsigned int)
    > typedef unsigned int size_t;
    > #elif sizeof((char*)0 - (char*)0) == sizeof(unsigned long)
    > typedef unsigned long size_t;
    > #elif sizeof((char*)0 - (char*)0) == sizeof(unsigned long long)
    > typedef unsigned long long size_t;
    > #endif
    >
    > is this way of defining the size_t portable?


    No.

    One problem is that conditional compilation occurs
    before types exist, so casts don't work and `sizeof'
    cannot be evaluated. (At this stage of compilation,
    `sizeof' and `char' and `unsigned' and `int' and `long'
    are not even recognized as keywords.)

    Another problem is that size_t might be something
    other than the three types you test for.

    Still another problem is that sizes do not determine
    types. If `sizeof(size_t) == sizeof(unsigned int)' you
    cannot conclude that `size_t' and `unsigned int' are the
    same, just as you cannot conclude that `int' and `float'
    are the same even if their sizes agree.

    Even yet still another additional problem is that
    you're trying to infer the type of `size_t' by examining
    the size of `ptrdiff_t', a different type altogether.

    Moreover still another additional accompanying extra
    problem is that the attempt to define `size_t' is illegal
    in any module that includes any of the several Standard
    headers that define it for themselves.

    But the biggest problem of all is that it's stupid.
    Use a header; that's what they're for.

    --
     
    Eric Sosman, Oct 25, 2007
    #3
  4. In article <>,
    lubomir dobsik <> wrote:

    >#if sizeof((char*)0 - (char*)0) == sizeof(unsigned int)


    The difference between two pointers is of type ptrdiff_t, not size_t.
    You could use sizeof(sizeof(0)), if it weren't for the other problems
    in your code.

    -- Richard
    --
    "Consideration shall be given to the need for as many as 32 characters
    in some alphabets" - X3.4, 1963.
     
    Richard Tobin, Oct 25, 2007
    #4
  5. lubomir dobsik

    Ben Pfaff Guest

    lubomir dobsik <> writes:

    > is this way of defining the size_t portable?


    No.

    Here is a portable way:
    #include <stddef.h>
    --
    Ben Pfaff
    http://benpfaff.org
     
    Ben Pfaff, Oct 25, 2007
    #5
  6. lubomir dobsik <> writes:
    > hi, i have seen an interesting thing:
    >
    > #if sizeof((char*)0 - (char*)0) == sizeof(unsigned int)
    > typedef unsigned int size_t;
    > #elif sizeof((char*)0 - (char*)0) == sizeof(unsigned long)
    > typedef unsigned long size_t;
    > #elif sizeof((char*)0 - (char*)0) == sizeof(unsigned long long)
    > typedef unsigned long long size_t;
    > #endif
    >
    > is this way of defining the size_t portable?


    No, for all the reasons that have already been mentioned. Where did
    you see it?

    If you're not writing an implementation, then you don't need to define
    size_t; the implementation will do it for you.

    If you are writing an implementation, you don't need a portable
    definition. You can use whatever compiler-specific magic you like, as
    long as it produces the correct results. If you happen to know that
    your preprocessor handles sizeof (it's not required to, and I'm not
    certain it's allowed to), then you can take advantage of that, though
    as Richard Tobin mentions, ``(sizeof sizeof 0)'' would make more
    sense.

    The only context where the above would make sense is if you're writing
    a <stddef.h> to be used with several different implementations (say,
    the same compiler on several different platforms). But even then,
    there are likely to be cleaner ways to do it.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 25, 2007
    #6
  7. lubomir dobsik

    Chris Torek Guest

    In article <>
    Keith Thompson <> wrote:
    >If you are writing an implementation, you don't need a portable
    >definition [for size_t]. You can use whatever compiler-specific
    >magic you like, as long as it produces the correct results. If
    >you happen to know that your preprocessor handles sizeof (it's
    >not required to, and I'm not certain it's allowed to), then ...


    It is "allowed to" in certain circumstances.

    At this point in translation, pp-tokens that are not otherwise
    "special" -- by which I mean pp-tokens that will map to C keywords
    or ordinary identifiers -- are to be treated as if they were the
    integer constant zero. Hence:

    /* do not #define XYZ */

    #define FOUR 4
    #if FOUR == XYZ
    # error "this #error must not fire"
    #endif

    #if XYZ == 0
    # error "this #error must fire"
    #endif

    Because of this rule, the line:

    #if sizeof(int) == 2

    must be treated as if it read:

    #if 0(0) == 2

    (assuming, of course, you have not "#define"d sizeof and/or int).
    Because this is syntactically invalid, the compiler is required
    to emit "at least one diagnostic".

    Once the "at least one diagnostic" has been produced, however, the
    compiler can then "look back" at the original text, discover the
    sizeof and int, and compute the size of an int. So you might get
    the "diagnostic":

    foo.c:12: congratulations on your commitment to the Frobozz compiler!

    which thanks you for making sure your code will not port to other
    C compilers, so that you will have to continue paying the $10,000-
    per-hour fee to use the Frobozz-branded compiler. :)

    >The only context where the above would make sense is if you're writing
    >a <stddef.h> to be used with several different implementations (say,
    >the same compiler on several different platforms). But even then,
    >there are likely to be cleaner ways to do it.


    Indeed -- for instance, the compiler can pre-"#define" various
    names that live in the implementor's name space (i.e., the one you,
    the implementor, are allowed to use because your customer, the C
    programmer, is *not* allowed to use it). Thus:

    #if __int_size == 2
    ... code that depends on sizeof(int) == 2 ...
    #elif __int__size == 4
    ... code that depends on sizeof(int) == 4 ...
    #else
    #error "oops: internal implementation error with __int_size"
    #endif

    Note that we can construct cases where the "sizeof" keyword must
    be replaced, during "#if" arithmetic, with the integer constant
    zero, and the result is still syntactically valid:

    #if sizeof + 0 != 0
    # error "this compiler is broken"
    #endif

    This makes implementing Frobozz C correctly quite tricky.
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Oct 27, 2007
    #7
  8. lubomir dobsik

    Eric Sosman Guest

    Chris Torek wrote:
    > [... concerning sizeof, etc., in #if directives ...]
    > At this point in translation, pp-tokens that are not otherwise
    > "special" -- by which I mean pp-tokens that will map to C keywords
    > or ordinary identifiers -- are to be treated as if they were the
    > integer constant zero. [...]


    Are you sure pp-tokens that will eventually become keywords
    are treated differently than others? It's my understanding that,
    for example,

    #if return == while

    is equivalent to

    #if 0 == 0

    5.1.1.2 says that preprocessing directives are handled in phase 4
    before pp-tokens become tokens in phase 7. 6.4 describes the
    keywords as a subset of the tokens, and 6.4p3 includes "keywords"
    in the list of possible tokens but not in the list of pp-tokens.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Oct 27, 2007
    #8
  9. Chris Torek <> writes:
    > In article <>
    > Keith Thompson <> wrote:
    >>If you are writing an implementation, you don't need a portable
    >>definition [for size_t]. You can use whatever compiler-specific
    >>magic you like, as long as it produces the correct results. If
    >>you happen to know that your preprocessor handles sizeof (it's
    >>not required to, and I'm not certain it's allowed to), then ...

    >
    > It is "allowed to" in certain circumstances.
    >
    > At this point in translation, pp-tokens that are not otherwise
    > "special" -- by which I mean pp-tokens that will map to C keywords
    > or ordinary identifiers -- are to be treated as if they were the
    > integer constant zero. Hence:
    >
    > /* do not #define XYZ */
    >
    > #define FOUR 4
    > #if FOUR == XYZ
    > # error "this #error must not fire"
    > #endif
    >
    > #if XYZ == 0
    > # error "this #error must fire"
    > #endif
    >
    > Because of this rule, the line:
    >
    > #if sizeof(int) == 2
    >
    > must be treated as if it read:
    >
    > #if 0(0) == 2
    >
    > (assuming, of course, you have not "#define"d sizeof and/or int).
    > Because this is syntactically invalid, the compiler is required
    > to emit "at least one diagnostic".
    >
    > Once the "at least one diagnostic" has been produced, however, the
    > compiler can then "look back" at the original text, discover the
    > sizeof and int, and compute the size of an int. So you might get
    > the "diagnostic":
    >
    > foo.c:12: congratulations on your commitment to the Frobozz compiler!
    >
    > which thanks you for making sure your code will not port to other
    > C compilers, so that you will have to continue paying the $10,000-
    > per-hour fee to use the Frobozz-branded compiler. :)

    [...]

    Right. Note that it must produce this diagnostic on conforming mode.
    It's likely that the Frobozz C compiler works in a non-conforming mode
    by default, in which it needn't produce the diagnostic.

    (I'd love to see a compiler that, in its default mode, is fully
    conforming, implements no extensions, and rejects any source file that
    violates a syntax rule or constraint.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 27, 2007
    #9
  10. Eric Sosman <> writes:
    > Chris Torek wrote:
    >> [... concerning sizeof, etc., in #if directives ...]
    >> At this point in translation, pp-tokens that are not otherwise
    >> "special" -- by which I mean pp-tokens that will map to C keywords
    >> or ordinary identifiers -- are to be treated as if they were the
    >> integer constant zero. [...]

    >
    > Are you sure pp-tokens that will eventually become keywords
    > are treated differently than others?

    [...]

    He didn't say they were. He referred to "pp-tokens that will map to C
    keywords or ordinary identifiers".

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 27, 2007
    #10
  11. On Oct 25, 3:42 pm, lubomir dobsik <> wrote:
    > hi, i have seen an interesting thing:
    >
    > #if sizeof((char*)0 - (char*)0) == sizeof(unsigned int)
    > typedef unsigned int size_t;
    > #elif sizeof((char*)0 - (char*)0) == sizeof(unsigned long)
    > typedef unsigned long size_t;
    > #elif sizeof((char*)0 - (char*)0) == sizeof(unsigned long long)
    > typedef unsigned long long size_t;
    > #endif
    >
    > is this way of defining the size_t portable?
    >
    > cheers, lubos



    thanks all for the reactions. the snippet comes from the stddef.h of a
    particular compiler. i admit that under these circumstances my
    original question doesnt make much sense. anyway, i posted this
    because i was curious to see your comments on this rather than getting
    a yes/no answer. thanks again, lubos
     
    lubomir dobsik, Oct 29, 2007
    #11
  12. lubomir dobsik <> writes:
    > On Oct 25, 3:42 pm, lubomir dobsik <> wrote:
    >> #if sizeof((char*)0 - (char*)0) == sizeof(unsigned int)
    >> typedef unsigned int size_t;
    >> #elif sizeof((char*)0 - (char*)0) == sizeof(unsigned long)
    >> typedef unsigned long size_t;
    >> #elif sizeof((char*)0 - (char*)0) == sizeof(unsigned long long)
    >> typedef unsigned long long size_t;
    >> #endif
    >>
    >> is this way of defining the size_t portable?

    >
    > thanks all for the reactions. the snippet comes from the stddef.h of a
    > particular compiler. i admit that under these circumstances my
    > original question doesnt make much sense. anyway, i posted this
    > because i was curious to see your comments on this rather than getting
    > a yes/no answer. thanks again, lubos


    Interesting. Which compiler is it? I wonder whether the compiler
    actually recognizes "sizeof" in preprocessor directives, or perhaps
    the author of stddef.h just *thought* it did.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 29, 2007
    #12
  13. On Oct 29, 7:48 pm, Keith Thompson <> wrote:
    > lubomir dobsik <> writes:
    > > On Oct 25, 3:42 pm, lubomir dobsik <> wrote:
    > >> #if sizeof((char*)0 - (char*)0) == sizeof(unsigned int)
    > >> typedef unsigned int size_t;
    > >> #elif sizeof((char*)0 - (char*)0) == sizeof(unsigned long)
    > >> typedef unsigned long size_t;
    > >> #elif sizeof((char*)0 - (char*)0) == sizeof(unsigned long long)
    > >> typedef unsigned long long size_t;
    > >> #endif

    >
    > >> is this way of defining the size_t portable?

    >
    > > thanks all for the reactions. the snippet comes from the stddef.h of a
    > > particular compiler. i admit that under these circumstances my
    > > original question doesnt make much sense. anyway, i posted this
    > > because i was curious to see your comments on this rather than getting
    > > a yes/no answer. thanks again, lubos

    >
    > Interesting. Which compiler is it? I wonder whether the compiler
    > actually recognizes "sizeof" in preprocessor directives, or perhaps
    > the author of stddef.h just *thought* it did.
    >
    > --
    > Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    > San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    > "We must do something. This is something. Therefore, we must do this."
    > -- Antony Jay and Jonathan Lynn, "Yes Minister"


    it was IAR, and no, it doesn't recognize the sizof during
    preprocessing - the #if directive with the expression containing
    sizeof is nested inside of another #if directive whose expression
    apparently always evaluates to false.
     
    lubomir dobsik, Dec 4, 2007
    #13
  14. lubomir dobsik

    somenath Guest

    On Oct 28, 12:05 am, Chris Torek <> wrote:
    > In article <>
    > Keith Thompson <> wrote:
    >
    > >If you are writing an implementation, you don't need a portable
    > >definition [for size_t]. You can use whatever compiler-specific
    > >magic you like, as long as it produces the correct results. If
    > >you happen to know that your preprocessor handles sizeof (it's
    > >not required to, and I'm not certain it's allowed to), then ...

    >
    > It is "allowed to" in certain circumstances.
    >
    > At this point in translation, pp-tokens that are not otherwise
    > "special" -- by which I mean pp-tokens that will map to C keywords
    > or ordinary identifiers -- are to be treated as if they were the
    > integer constant zero. Hence:
    >
    > /* do not #define XYZ */
    >
    > #define FOUR 4
    > #if FOUR == XYZ
    > # error "this #error must not fire"
    > #endif
    >
    > #if XYZ == 0
    > # error "this #error must fire"
    > #endif
    >
    > Because of this rule, the line:
    >
    > #if sizeof(int) == 2
    >
    > must be treated as if it read:
    >
    > #if 0(0) == 2
    >


    Sorry if I have misunderstood what you are trying to convey.
    But
    #if sizeof(int) == 2
    #endif
    Will not be compiled.
    I think because as it is converted to #if 0(0) == 2

    The compiler is throwing eror
    foo.c:1:11: missing binary operator before '('


    > (assuming, of course, you have not "#define"d sizeof and/or int).
    > Because this is syntactically invalid, the compiler is required
    > to emit "at least one diagnostic".
    >
    > Once the "at least one diagnostic" has been produced, however, the
    > compiler can then "look back" at the original text, discover the
    > sizeof and int, and compute the size of an int. So you might get
    > the "diagnostic":
    >
    > foo.c:12: congratulations on your commitment to the Frobozz compiler!
    >
    > which thanks you for making sure your code will not port to other
    > C compilers, so that you will have to continue paying the $10,000-
    > per-hour fee to use the Frobozz-branded compiler. :)
    >
    > >The only context where the above would make sense is if you're writing
    > >a <stddef.h> to be used with several different implementations (say,
    > >the same compiler on several different platforms). But even then,
    > >there are likely to be cleaner ways to do it.

    >
    > Indeed -- for instance, the compiler can pre-"#define" various
    > names that live in the implementor's name space (i.e., the one you,
    > the implementor, are allowed to use because your customer, the C
    > programmer, is *not* allowed to use it). Thus:
    >
    > #if __int_size == 2
    > ... code that depends on sizeof(int) == 2 ...
    > #elif __int__size == 4
    > ... code that depends on sizeof(int) == 4 ...
    > #else
    > #error "oops: internal implementation error with __int_size"
    > #endif
    >
    > Note that we can construct cases where the "sizeof" keyword must
    > be replaced, during "#if" arithmetic, with the integer constant
    > zero, and the result is still syntactically valid:
    >
    > #if sizeof + 0 != 0
    > # error "this compiler is broken"
    > #endif
    >
    > This makes implementing Frobozz C correctly quite tricky.
     
    somenath, Dec 5, 2007
    #14
  15. lubomir dobsik

    Chris Torek Guest

    >On Oct 28, 12:05 am, Chris Torek <> wrote:
    >>... the line:
    >> #if sizeof(int) == 2
    >> must be treated as if it read:
    >> #if 0(0) == 2
    >>... [so that] the compiler is required to emit "at least one diagnostic".


    In article <>,
    somenath <> wrote:
    >Sorry if I have misunderstood what you are trying to convey.


    I think you have:

    >But
    >#if sizeof(int) == 2
    >#endif
    >Will not be compiled.
    >I think because as it is converted to #if 0(0) == 2
    >
    >The compiler is throwing eror
    >foo.c:1:11: missing binary operator before '('


    This is your "at least one diagnostic".

    If you have Frobozz C, *that* *particular* compiler -- which prints
    a different diagnostic -- then goes on to "re-inspect" the original
    line, and do something different.

    No C compiler is *required* to work the way Frobozz C does, so if
    you would ever like to use any *other* compiler, you should avoid
    depending on the special features offered by Frobozz C.

    This is true of other compilers as well. If you make use of various
    gcc-specific features, you will be unable to use lcc-win32 to
    compile your code; if you make use of certain lcc-win32-specific
    features, you will be unable to use gcc to compile your code; and
    so on. Thus, *any* time you make use of *any* compiler's special
    features, you should be aware of the *cost* of your actions, as
    well as the (presumed) benefit (i.e., getting the use of whatever
    the "special feature" does for you).

    In other words, I am not saying "do not use qfloat (lcc-win32) or
    &&label (gcc) or &42 (VMS) or #pragma dwim (Frobozz)", but rather,
    "be aware of BOTH the cost AND the benefit of your actions".
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Dec 5, 2007
    #15
    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. johny smith
    Replies:
    8
    Views:
    447
    Peter Koch Larsen
    Jul 2, 2004
  2. javadesigner

    How to use maximum size of size_t type ?

    javadesigner, Jan 21, 2004, in forum: C Programming
    Replies:
    11
    Views:
    1,305
    Dan Pop
    Jan 22, 2004
  3. Alex Vinokur
    Replies:
    9
    Views:
    832
    James Kanze
    Oct 13, 2008
  4. Alex Vinokur
    Replies:
    1
    Views:
    611
  5. Urs Thuermann
    Replies:
    6
    Views:
    515
    Urs Thuermann
    Nov 4, 2011
Loading...

Share This Page