Portable way to printf() a size_t instance

Discussion in 'C Programming' started by Joakim Hove, Jun 12, 2005.

  1. Joakim Hove

    Joakim Hove Guest

    Hello,

    I have code which makses use of variables of type size_t. The code is
    originally developed on a 32 bit machine, but now it is run on both a
    32 bit and a 64 bit machine.

    In the code have statements like this:

    size_t buffer_size;
    printf("Total buffer size: %ud bytes \n",buffer_size);

    Now the format "%ud" works nicely on the 32 bit computer; it actually
    works on the 64 bit computer as well, but the compiler spits out
    warning message. On the 64 bit computer it would have prefered:

    printf("Total buffer size: %uld bytes \n",buffer_size); /* Or udl? */

    As I said it works, but I would really prefer the program to compile
    without warnings, as it is now I get *many* warnings of the type

    file.c:line: warning: unsigned int format, different type arg (arg 1).

    And, on several occasion this has actually led me to miss more
    important warnings.


    Any tips appreciated.


    Joakim


    --
    Joakim Hove
    hove AT ift uib no /
    Tlf: +47 (55 5)8 27 90 / Stabburveien 18
    Fax: +47 (55 5)8 94 40 / N-5231 Paradis
    http://www.ift.uib.no/~hove/ / 55 91 28 18 / 92 68 57 04
    Joakim Hove, Jun 12, 2005
    #1
    1. Advertising

  2. Joakim Hove

    pete Guest

    Joakim Hove wrote:
    >
    > Hello,
    >
    > I have code which makses use of variables of type size_t. The code is
    > originally developed on a 32 bit machine, but now it is run on both a
    > 32 bit and a 64 bit machine.
    >
    > In the code have statements like this:
    >
    > size_t buffer_size;
    > printf("Total buffer size: %ud bytes \n",buffer_size);
    >
    > Now the format "%ud" works nicely on the 32 bit computer; it actually
    > works on the 64 bit computer as well, but the compiler spits out
    > warning message. On the 64 bit computer it would have prefered:
    >
    > printf("Total buffer size: %uld bytes \n",buffer_size); /* Or udl? */
    >
    > As I said it works, but I would really prefer the program to compile
    > without warnings, as it is now I get *many* warnings of the type
    >
    > file.c:line: warning: unsigned int format, different type arg (arg 1).
    >
    > And, on several occasion this has actually led me to miss more
    > important warnings.
    >
    > Any tips appreciated.


    For C89, convert to long unsigned.

    printf("sizeof(int) is %lu\n", (long unsigned)sizeof(int));

    --
    pete
    pete, Jun 12, 2005
    #2
    1. Advertising

  3. Joakim Hove wrote:
    > Hello,
    >
    > I have code which makses use of variables of type size_t. The code is
    > originally developed on a 32 bit machine, but now it is run on both a
    > 32 bit and a 64 bit machine.
    >
    > In the code have statements like this:
    >
    > size_t buffer_size;
    > printf("Total buffer size: %ud bytes \n",buffer_size);
    >
    > Now the format "%ud" works nicely on the 32 bit computer;


    It shouldn't. The %<qualifier>d are the conversion specifiers for signed
    integers; the %<qualifier>u are the conversion specifiers for unsigned
    integers. 'u' is not a qualifier for %d.


    > it actually
    > works on the 64 bit computer as well, but the compiler spits out
    > warning message.


    Something like "%ud doesn't mean anything"?

    > On the 64 bit computer it would have prefered:
    >
    > printf("Total buffer size: %uld bytes \n",buffer_size); /* Or udl? */


    I doubt it. The printf routine rarely "wants" meaningless specifiers.
    If you have an up-to-date library, you could use
    printf("Total buffer size: %zu bytes \n",buffer_size);

    Otherwise, try
    printf("Total buffer size: %lu bytes \n",
    (long unsigned)buffer_size);
    or
    printf("Total buffer size: %llu bytes \n",
    (long long unsigned) buffer_size);

    That is, use an (properly written) unsigned specifier and cast the
    size_t argument to the same size unsigned.
    Martin Ambuhl, Jun 12, 2005
    #3
  4. Martin Ambuhl wrote (and now clarifies):
    > Joakim Hove wrote:

    [...]
    >> Now the format "%ud" works nicely on the 32 bit computer;


    > It shouldn't. The %<qualifier>d are the conversion specifiers for signed
    > integers; the %<qualifier>u are the conversion specifiers for unsigned
    > integers. 'u' is not a qualifier for %d.


    I should have been clearer. "%u" is the specifier you are using. The
    "d" is a literal portion of the output string. See the example below
    and note the extra 'd' at the end of the string:

    #include <stdio.h>
    int main(void)
    {
    printf("Printing an unsigned value using %%ud: %ud\n", 5u);
    return 0;
    }

    Printing an unsigned value using %ud: 5d
    Martin Ambuhl, Jun 12, 2005
    #4
  5. Joakim Hove <> writes:
    > I have code which makses use of variables of type size_t. The code is
    > originally developed on a 32 bit machine, but now it is run on both a
    > 32 bit and a 64 bit machine.
    >
    > In the code have statements like this:
    >
    > size_t buffer_size;
    > printf("Total buffer size: %ud bytes \n",buffer_size);


    I think you mean "%u", not "%ud". "%d" is for (signed) int; "%u" is
    for unsigned int.

    > Now the format "%ud" works nicely on the 32 bit computer; it actually
    > works on the 64 bit computer as well, but the compiler spits out
    > warning message. On the 64 bit computer it would have prefered:
    >
    > printf("Total buffer size: %uld bytes \n",buffer_size); /* Or udl? */


    The format for unsigned long is "%lu".

    In C90, the best way to print a size_t value is to convert it
    to unsigned long and use "%lu":

    printf("Total buffer size: %lu bytes\n", (unsigned long)buffer_size);

    C99 adds a 'z' modifier specifically for size_t:

    printf("Total buffer size: %zu bytes\n", buffer_size);

    but many printf implementations don't support it. (Even if your
    compiler supports C99 and defines __STDC_VERSION__ appropriately,
    that's not, practically speaking, a guarantee that the library also
    conforms to C99.)

    Even in C99, the "%lu" method will work unless size_t is bigger than
    unsigned long *and* the value being printed exceeds ULONG_MAX, which
    is unlikely to happen in practice.

    --
    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.
    Keith Thompson, Jun 12, 2005
    #5
  6. On Sun, 12 Jun 2005 08:07:07 +0200, Joakim Hove
    <> wrote:

    > I have code which makses use of variables of type size_t. The code is
    > originally developed on a 32 bit machine, but now it is run on both a
    > 32 bit and a 64 bit machine.
    >
    > In the code have statements like this:
    >
    > size_t buffer_size;
    > printf("Total buffer size: %ud bytes \n",buffer_size);


    That is undefined, because %u expects an int. Quite why you want to
    print a 'd' after the number I don't know, but it's your choice...

    > Now the format "%ud" works nicely on the 32 bit computer; it actually
    > works on the 64 bit computer as well, but the compiler spits out
    > warning message. On the 64 bit computer it would have prefered:
    >
    > printf("Total buffer size: %uld bytes \n",buffer_size); /* Or udl? */


    You probably mean %lu -- but it's still undefined behaviour because
    size_t is not the same as an unsigned long except by accident (well,
    implementers' choice, but something over which you have no control and
    the next version of the compiler could change it).

    > As I said it works, but I would really prefer the program to compile
    > without warnings, as it is now I get *many* warnings of the type
    >
    > file.c:line: warning: unsigned int format, different type arg (arg 1).


    Heed them. Your code is incorrect. Try, for instance,

    size_t buffer_size = 123;
    printf("%u %d\n", buffer_size, 42);

    On the 32 bit machine it may work (and give "123 42"), but on the 64 bit
    machine it may give you something like "123 0" (or possibly "0 123", or
    some other strange result).

    > And, on several occasion this has actually led me to miss more
    > important warnings.


    So correct the printf code.

    If your library is C99 compliant you can use the z conversion specifier
    for size_t:

    printf("%zu\n", buffer_size);

    Note that the /library/ must be compliant, not the actual compiler, and
    since gcc for instance uses printf from the underlying system it may not
    be supported (as I recall it was on Linux but wasn't on Solaris when I
    tried it). If the compiler doesn't support it then you may still get
    warnings, of course.

    Alternatively, cast the size to a known and supported type. For most
    purposes long is sufficient:

    printf("%lu\n", (long)buffer_size);

    That will get rid of the warnings (because there is no longer any
    mismatch) and allow for at least 32 bit sizes even on 16 bit machines.

    Chris C
    Chris Croughton, Jun 12, 2005
    #6
  7. Joakim Hove

    Me Guest

    %z is the specifier for size_t in C99 but I assume you want to be
    backwards compatible with older and broken implementations. Here is the
    smart way to go about this (untested, use at your own risk):

    #if __STDC_VERSION__ >= 199901L

    #include <stdint.h>

    #else

    #include <limits.h>

    #ifdef LLONG_MAX
    typedef long long intmax_t;
    typedef unsigned long long uintmax_t;
    #define INTMAX_MIN LLONG_MIN
    #define INTMAX_MAX LLONG_MAX
    #define UINTMAX_MAX ULLONG_MAX
    #elif defined(_I64_MAX)
    typedef __int64 intmax_t;
    typedef __uint64 uintmax_t;
    #define INTMAX_MIN _I64_MIN
    #define INTMAX_MAX _I64_MAX
    #define UINTMAX_MAX _UI64_MAX
    #else
    typedef long intmax_t;
    typedef unsigned long uintmax_t;
    #define INTMAX_MIN LONG_MIN
    #define INTMAX_MAX LONG_MAX
    #define UINTMAX_MAX ULONG_MAX
    #endif

    #endif

    or something similar for an implementation specific intmax_t type
    somewhat portably defined. There are several ways to do the next part
    but here is one simple way is to create another implementation specific
    header file:

    #if __STDC_VERSION__ >= 199901L

    #include <inttypes.h>

    #else

    #ifdef LLONG_MAX
    #define PRIiMAX "%lli"
    #define PRIuMAX "%llu"
    #elif defined(_I64_MAX)
    #define PRIiMAX "%I64i"
    #define PRIuMAX "%I64u"
    #else
    #define PRIiMAX "%li"
    #define PRIuMAX "%lu"
    #endif

    #endif

    And for all your printf calls do:

    printf("Total size: " PRIuMAX " bytes\n", (uintmax_t)size);

    Another simple way is to create printf specifier for size_t similar to
    the above using another implementation specific header that you have to
    keep in sync with: "%z" for C99, "%Iu" for visual studio's runtime,
    etc. or however you want to go about doing it.
    Me, Jun 12, 2005
    #7
  8. Joakim Hove

    CBFalconer Guest

    Keith Thompson wrote:
    > Joakim Hove <> writes:
    >
    >> I have code which makses use of variables of type size_t. The
    >> code is originally developed on a 32 bit machine, but now it is
    >> run on both a 32 bit and a 64 bit machine.
    >>
    >> In the code have statements like this:
    >>
    >> size_t buffer_size;
    >> printf("Total buffer size: %ud bytes \n",buffer_size);

    >
    > I think you mean "%u", not "%ud". "%d" is for (signed) int; "%u"
    > is for unsigned int.
    >
    >> Now the format "%ud" works nicely on the 32 bit computer; it
    >> actually works on the 64 bit computer as well, but the compiler
    >> spits out warning message. On the 64 bit computer it would have
    >> prefered:
    >>
    >> printf("Total buffer size: %uld bytes \n",buffer_size); /* Or udl? */

    >
    > The format for unsigned long is "%lu".
    >
    > In C90, the best way to print a size_t value is to convert it
    > to unsigned long and use "%lu":
    >
    > printf("Total buffer size: %lu bytes\n", (unsigned long)buffer_size);
    >
    > C99 adds a 'z' modifier specifically for size_t:
    >
    > printf("Total buffer size: %zu bytes\n", buffer_size);
    >
    > but many printf implementations don't support it. (Even if your
    > compiler supports C99 and defines __STDC_VERSION__ appropriately,
    > that's not, practically speaking, a guarantee that the library
    > also conforms to C99.)
    >
    > Even in C99, the "%lu" method will work unless size_t is bigger
    > than unsigned long *and* the value being printed exceeds ULONG_MAX,
    > which is unlikely to happen in practice.


    I was going to reply to the OP, but this covers it better. The
    major point is that, for C89 or any lack of full printf C99
    coverage in the library, you have to cast the size_t operand to
    something, and you have to then make the specifier agree with that
    cast. The programmer probably knows how bit his size_t object can
    actually become, and so can make the decision about what to cast it
    to. The safest is the largest unsigned that the library can
    handle.

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    CBFalconer, Jun 12, 2005
    #8
  9. Joakim Hove

    ade ishs Guest

    Chris Croughton wrote:

    > Alternatively, cast the size to a known and supported type. For most
    > purposes long is sufficient:
    >
    > printf("%lu\n", (long)buffer_size);


    ITYM

    printf("%lu\n", (unsigned long)buffer_size);

    --
    ade ishs
    ade ishs, Jun 12, 2005
    #9
  10. Chris Croughton <> writes:
    > On Sun, 12 Jun 2005 08:07:07 +0200, Joakim Hove
    > <> wrote:
    >
    >> I have code which makses use of variables of type size_t. The code is
    >> originally developed on a 32 bit machine, but now it is run on both a
    >> 32 bit and a 64 bit machine.
    >>
    >> In the code have statements like this:
    >>
    >> size_t buffer_size;
    >> printf("Total buffer size: %ud bytes \n",buffer_size);

    >
    > That is undefined, because %u expects an int. Quite why you want to
    > print a 'd' after the number I don't know, but it's your choice...

    [...]

    I think it's only potentially undefined. If size_t happens to be
    unsigned int for a given implementation, it's well defined. If you
    use a "%u" format, the implementation doesn't care whether you
    actually know that the argument is an unsigned int, or you just got
    lucky.

    It is, of course, unnecessarily non-portable.

    --
    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.
    Keith Thompson, Jun 12, 2005
    #10
  11. On Sun, 12 Jun 2005 15:57:46 +0000, Keith Thompson wrote:

    > Chris Croughton <> writes:
    >> On Sun, 12 Jun 2005 08:07:07 +0200, Joakim Hove
    >> <> wrote:
    >>
    >>> I have code which makses use of variables of type size_t. The code is
    >>> originally developed on a 32 bit machine, but now it is run on both a
    >>> 32 bit and a 64 bit machine.
    >>>
    >>> In the code have statements like this:
    >>>
    >>> size_t buffer_size;
    >>> printf("Total buffer size: %ud bytes \n",buffer_size);

    >>
    >> That is undefined, because %u expects an int. Quite why you want to
    >> print a 'd' after the number I don't know, but it's your choice...

    > [...]
    >
    > I think it's only potentially undefined.


    In the context of comp.lang.c that makes it undefined.

    > If size_t happens to be
    > unsigned int for a given implementation, it's well defined.


    But without the context of of the specific inplementation it is undefined.

    > If you
    > use a "%u" format, the implementation doesn't care whether you
    > actually know that the argument is an unsigned int, or you just got
    > lucky.


    Undefined doesn't mean that it won't do what you wanted on some
    implementation.

    Lawrence
    Lawrence Kirby, Jun 12, 2005
    #11
  12. Lawrence Kirby <> writes:
    > On Sun, 12 Jun 2005 15:57:46 +0000, Keith Thompson wrote:
    >
    >> Chris Croughton <> writes:
    >>> On Sun, 12 Jun 2005 08:07:07 +0200, Joakim Hove
    >>> <> wrote:
    >>>
    >>>> I have code which makses use of variables of type size_t. The code is
    >>>> originally developed on a 32 bit machine, but now it is run on both a
    >>>> 32 bit and a 64 bit machine.
    >>>>
    >>>> In the code have statements like this:
    >>>>
    >>>> size_t buffer_size;
    >>>> printf("Total buffer size: %ud bytes \n",buffer_size);
    >>>
    >>> That is undefined, because %u expects an int. Quite why you want to
    >>> print a 'd' after the number I don't know, but it's your choice...

    >> [...]
    >>
    >> I think it's only potentially undefined.

    >
    > In the context of comp.lang.c that makes it undefined.


    The term "undefined behavior" is defined by the standard, not by the
    newsgroup.

    >> If size_t happens to be
    >> unsigned int for a given implementation, it's well defined.

    >
    > But without the context of of the specific inplementation it is undefined.


    Without the context of the specific inplementation, we don't know
    whether it's undefined or not.

    >> If you
    >> use a "%u" format, the implementation doesn't care whether you
    >> actually know that the argument is an unsigned int, or you just got
    >> lucky.

    >
    > Undefined doesn't mean that it won't do what you wanted on some
    > implementation.


    Nor does it merely mean non-portable.

    If I declare x as an object of type unsigned int, and initialize it
    with some valid value, then the following:

    printf("x = %u\n", x);

    is well defined. If I instead declare it with a typedef name that
    happens to be an alias for unsigned int, it's still well defined. If
    the typedef name happens to be size_t, that doesn't make it undefined
    -- as long as size_t is an alias for unsigned int. A statement that
    assumes size_t is unsigned int is non-portable, and cannot appear in a
    strictly conforming program, and it invokes undefined behavior on a
    platform where size_t is not unsigned int.

    Similarly, the following:

    int i = 32767;
    i ++;

    is non-portable, but it invokes undefined behavior *only* on an
    implementation with INT_MAX == 32767; it's perfectly well defined on
    any implementation with INT_MAX > 32767.

    "Undefined behavior" is a useful concept. We need to be careful not
    to weaken it until it merely means "bad code".

    --
    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.
    Keith Thompson, Jun 13, 2005
    #12
  13. Joakim Hove

    pete Guest

    Keith Thompson wrote:
    >
    > Lawrence Kirby <> writes:
    > > On Sun, 12 Jun 2005 15:57:46 +0000, Keith Thompson wrote:


    > >> I think it's only potentially undefined.

    > >
    > > In the context of comp.lang.c that makes it undefined.

    >
    > The term "undefined behavior" is defined by the standard, not by the
    > newsgroup.


    Potentially undefined matches the meaning of undefined by the standard.

    A program that prints the value of CHAR_BIT has implementation
    defined behavior.

    A program that only crashes when CHAR_BIT equals eight,
    is different from a program with implementation defined behavior.

    --
    pete
    pete, Jun 13, 2005
    #13
  14. pete <> writes:
    > Keith Thompson wrote:
    >>
    >> Lawrence Kirby <> writes:
    >> > On Sun, 12 Jun 2005 15:57:46 +0000, Keith Thompson wrote:

    >
    >> >> I think it's only potentially undefined.
    >> >
    >> > In the context of comp.lang.c that makes it undefined.

    >>
    >> The term "undefined behavior" is defined by the standard, not by the
    >> newsgroup.

    >
    > Potentially undefined matches the meaning of undefined by the standard.
    >
    > A program that prints the value of CHAR_BIT has implementation
    > defined behavior.
    >
    > A program that only crashes when CHAR_BIT equals eight,
    > is different from a program with implementation defined behavior.


    The context was something like this:

    size_t s = 42;
    printf("s = %u\n", s);

    The standard defines "undefined behavior" as "behavior, upon use of a
    nonportable or erroneous program construct or of erroneous data, for
    which this International Standard imposes no requirements".

    The standard does impose requirements on the behavior of the above
    code; it requires it to print the string "42", followed by a newline,
    if size_t is a typedef for unsigned int.

    --
    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.
    Keith Thompson, Jun 13, 2005
    #14
  15. Joakim Hove

    pete Guest

    Keith Thompson wrote:

    > The context was something like this:
    >
    > size_t s = 42;
    > printf("s = %u\n", s);
    >
    > The standard defines "undefined behavior" as "behavior, upon use of a
    > nonportable or erroneous program construct or of erroneous data, for
    > which this International Standard imposes no requirements".
    >
    > The standard does impose requirements on the behavior of the above
    > code; it requires it to print the string "42", followed by a newline,
    > if size_t is a typedef for unsigned int.


    You don't know if size_t is a typedef for unsigned int.
    So, you don't really know what it does, do you?
    The code is either defined or undefined when you write it,
    not when you finally match it up to a machine
    where it does what you want.

    --
    pete
    pete, Jun 13, 2005
    #15
  16. pete <> writes:
    > Keith Thompson wrote:
    >
    >> The context was something like this:
    >>
    >> size_t s = 42;
    >> printf("s = %u\n", s);
    >>
    >> The standard defines "undefined behavior" as "behavior, upon use of a
    >> nonportable or erroneous program construct or of erroneous data, for
    >> which this International Standard imposes no requirements".
    >>
    >> The standard does impose requirements on the behavior of the above
    >> code; it requires it to print the string "42", followed by a newline,
    >> if size_t is a typedef for unsigned int.

    >
    > You don't know if size_t is a typedef for unsigned int.


    Maybe I do, maybe I don't.

    > So, you don't really know what it does, do you?


    I know exactly what it does *if* I run it on an implementation where
    size_t is unsigned int.

    > The code is either defined or undefined when you write it,
    > not when you finally match it up to a machine
    > where it does what you want.


    The standard talks about undefined behavior, not undefined code. The
    undefined behavior, at least in this case, occurs at run time, not
    when I'm entering the code in my text editor. If I don't run the code
    on a system where size_t is not unsigned int, there is no behavior,
    and therefore there is no undefined behavior.

    --
    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.
    Keith Thompson, Jun 13, 2005
    #16
  17. Joakim Hove

    pete Guest

    Keith Thompson wrote:
    >
    > pete <> writes:
    > > Keith Thompson wrote:
    > >
    > >> The context was something like this:
    > >>
    > >> size_t s = 42;
    > >> printf("s = %u\n", s);
    > >>
    > >> The standard defines "undefined behavior" as "behavior, upon use of a
    > >> nonportable or erroneous program construct or of erroneous data, for
    > >> which this International Standard imposes no requirements".
    > >>
    > >> The standard does impose requirements on the behavior of the above
    > >> code; it requires it to print the string "42", followed by a newline,
    > >> if size_t is a typedef for unsigned int.

    > >
    > > You don't know if size_t is a typedef for unsigned int.

    >
    > Maybe I do, maybe I don't.
    >
    > > So, you don't really know what it does, do you?

    >
    > I know exactly what it does *if* I run it on an implementation where
    > size_t is unsigned int.
    >
    > > The code is either defined or undefined when you write it,
    > > not when you finally match it up to a machine
    > > where it does what you want.

    >
    > The standard talks about undefined behavior, not undefined code.


    Code contains behavior.
    The standard catagorizes "correct programs"
    according to the behavior that they contain.

    > The
    > undefined behavior, at least in this case, occurs at run time, not
    > when I'm entering the code in my text editor. If I don't run the code
    > on a system where size_t is not unsigned int, there is no behavior,
    > and therefore there is no undefined behavior.


    If you refuse to ever run the code,
    does it become a strictly conforming program?

    ISO/IEC 9899:1999
    4. Conformance
    5
    A strictly conforming program shall use only those features of the
    language and library specified in this International Standard.
    It shall not produce output dependent on any
    unspecified, undefined, or implementation-defined behavior,
    and shall not exceed any minimum implementation limit.

    --
    pete
    pete, Jun 14, 2005
    #17
  18. Joakim Hove

    Chris Torek Guest

    In article <>
    pete <> wrote:
    >If you refuse to ever run the code,
    >does it become a strictly conforming program?


    A more interesting question (I think, anyway): if the code refuses
    to run itself, does it become strictly conforming?

    #include <stdio.h>

    void print_a_size_t(size_t val) {
    if (sizeof val == sizeof(unsigned))
    printf("%u", val);
    else if (sizeof val == sizeof(unsigned long))
    printf("%lu", val);
    else
    printf("<can't print size>");
    }

    int main(void) {
    printf("sizeof(int) = ");
    print_a_size_t(sizeof(int));
    printf("\n");
    return 0;
    }

    I believe the comp.std.c gnomes have already said that a program
    that changes its output based on compile-time conditions (like
    time-of-compile as stored in __DATE__, or printing the value of
    INT_MAX, or whatever) remains strictly conforming, even though the
    output changes from machine to machine or compile-time to compile-time.
    If so, is the above also strictly conforming? (If simply printing
    out INT_MAX renders the program not-strictly-conforming, I withdraw
    my question. :) )
    --
    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, Jun 14, 2005
    #18
  19. On Tue, 14 Jun 2005 02:17:07 +0000, Chris Torek wrote:

    > In article <>
    > pete <> wrote:
    >>If you refuse to ever run the code,
    >>does it become a strictly conforming program?

    >
    > A more interesting question (I think, anyway): if the code refuses
    > to run itself, does it become strictly conforming?


    If a program cannot execute code that resunts in undefined behaviour it
    can be strictly conforming, e.g.

    if (0) 1/0;

    can appear in a strictly conforming program.

    > #include <stdio.h>
    >
    > void print_a_size_t(size_t val) {
    > if (sizeof val == sizeof(unsigned))


    The size of an type is not enough to uniquely identify that type, so

    > printf("%u", val);


    this could still produce undefined behaviour. Think of an implementation
    where sizelf(unsigned)==sizeof(unsigned long) but unsigned has a
    smaller range, padding bits and trap representations.

    > else if (sizeof val == sizeof(unsigned long))
    > printf("%lu", val);
    > else
    > printf("<can't print size>");


    > }
    > }
    > int main(void) {
    > printf("sizeof(int) = ");
    > print_a_size_t(sizeof(int));
    > printf("\n");
    > return 0;
    > }
    > }
    > I believe the comp.std.c gnomes have already said that a program that
    > changes its output based on compile-time conditions (like
    > time-of-compile as stored in __DATE__, or printing the value of INT_MAX,
    > or whatever) remains strictly conforming, even though the output changes
    > from machine to machine or compile-time to compile-time.


    Agreed, strict conformance is NOT about the output being identical across
    implementations. However 5.2.4.2.1 does explicitly label the values of
    INT_MAX etc. as implementation-defined which means that (a) the
    implementation has to document them and (b) a strictly conforming program
    cannot generate output dependent on them.

    OTOH the return values of, for example, time() or rand() are not specified
    as implementation-defined and a strictly conforming program can produce
    output based on those.

    Lawrence
    Lawrence Kirby, Jun 14, 2005
    #19
  20. Joakim Hove

    pete Guest

    Lawrence Kirby wrote:

    > OTOH the return values of, for example,
    > time() or rand() are not specified
    > as implementation-defined
    > and a strictly conforming program can produce
    > output based on those.


    That sounds more like a correct program
    or like a conforming program to me,
    than like a strictly conforming program.

    ISO/IEC ISO/IEC 9899:1999

    4. Conformance
    3 A program that is correct in all other aspects,
    operating on correct data, containing
    unspecified behavior shall be a correct program and
    act in accordance with 5.1.2.3.

    5 A strictly conforming program shall use only those features
    of the language and library specified in this International
    Standard. It shall not produce output dependent on any
    unspecified, undefined, or implementation-defined behavior,
    and shall not exceed any minimum implementation limit.
    4)
    Conforming programs may depend upon nonportable
    features of a conforming implementation.

    --
    pete
    pete, Jun 14, 2005
    #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. G Patel
    Replies:
    17
    Views:
    1,053
    Vesa Siivola
    Feb 14, 2005
  2. David Mathog

    printf formats for size_t?

    David Mathog, May 12, 2005, in forum: C Programming
    Replies:
    6
    Views:
    4,813
    Clark S. Cox III
    May 13, 2005
  3. dank
    Replies:
    5
    Views:
    1,481
    Simon Biber
    Jun 30, 2006
  4. Alex Vinokur
    Replies:
    9
    Views:
    791
    James Kanze
    Oct 13, 2008
  5. Alex Vinokur
    Replies:
    1
    Views:
    575
Loading...

Share This Page