function calls, mandatory compiler promotion of int arguments tosize_t?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • David Mathog

    function calls, mandatory compiler promotion of int arguments tosize_t?

    For this small test program:

    #include <stdio.h>
    void main(void){
    char buffer[]="ABCDEFGHIJKLM NOPQRSTUVWXYZ\n ";
    int size, count;
    size = 27; /* always a small number which will fit in an int */
    count = 1; /* ditto */
    (void) fwrite(buffer, size, count, stdout);
    }

    The int variables size and count are both used for fwrite() arguments
    which are prototyped to be size_t. If size_t is bigger than int (as on
    some 64 bit systems where size_t is 8 bytes and int is 4 bytes), does
    the C standard require the compiler to promote these two int values to
    size_t before passing them to the function, and if so, what exactly does
    it say?

    I know that in _practice_ the code above works, but I am curious if that
    must always be the case.

    Thanks,

    David Mathog


  • Eric Sosman

    #2
    Re: function calls, mandatory compiler promotion of int argumentsto size_t?

    David Mathog wrote:
    For this small test program:
    >
    #include <stdio.h>
    void main(void){
    Tut. Tut, tut, tut. Consider your wrist slapped.
    char buffer[]="ABCDEFGHIJKLM NOPQRSTUVWXYZ\n ";
    int size, count;
    size = 27; /* always a small number which will fit in an int */
    count = 1; /* ditto */
    (void) fwrite(buffer, size, count, stdout);
    }
    >
    The int variables size and count are both used for fwrite() arguments
    which are prototyped to be size_t. If size_t is bigger than int (as on
    some 64 bit systems where size_t is 8 bytes and int is 4 bytes), does
    the C standard require the compiler to promote these two int values to
    size_t before passing them to the function, and if so, what exactly does
    it say?
    Yes, and 6.5.2.2p7: "If the expression that denotes the called
    function has a type that does include a prototype, the arguments are
    implicitly converted, as if by assignment, to the types of the
    corresponding parameters, taking the type of each parameter to be the
    unqualified version of its declared type."
    I know that in _practice_ the code above works, but I am curious if that
    must always be the case.
    Yes, it is. Note that the prototype-governed conversions cut both
    ways, though: If you pass a "wide" argument expression to a prototyped
    function with a "narrower" parameter, the conversion from wide to narrow
    may lose information silently. Similarly, if you pass a floating-point
    argument to a prototyped integer parameter, the fractional part vanishes
    silently. (There's the seedling of an IOCCC entry here, I think: try
    `malloc(atan(42 .0))' to allocate an 88-byte object ...)

    --
    Eric.Sosman@sun .com

    Comment

    • Keith Thompson

      #3
      Re: function calls, mandatory compiler promotion of int arguments to size_t?

      Eric Sosman <Eric.Sosman@su n.comwrites:
      [...]
      Yes, it is. Note that the prototype-governed conversions cut both
      ways, though: If you pass a "wide" argument expression to a prototyped
      function with a "narrower" parameter, the conversion from wide to narrow
      may lose information silently.
      Or it may give you some unexpected result. Conversion to a signed
      integer type, if the value can't be represented in the target type,
      yields an implementation-defined result (or raises an
      implementation-defined signal; the latter is new in C99).
      Similarly, if you pass a floating-point
      argument to a prototyped integer parameter, the fractional part vanishes
      silently. (There's the seedling of an IOCCC entry here, I think: try
      `malloc(atan(42 .0))' to allocate an 88-byte object ...)
      For certain values of 42.0.

      Actually, for *no* values of 42.0; the results of atan() are in the
      range [-pi/2, +pi/2] (radians).

      But tan(1.5595) would do it. Note that very small changes in the
      argument result in large changes in the result.

      --
      Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
      Nokia
      "We must do something. This is something. Therefore, we must do this."
      -- Antony Jay and Jonathan Lynn, "Yes Minister"

      Comment

      • Eric Sosman

        #4
        Re: function calls, mandatory compiler promotion of int argumentsto size_t?

        Keith Thompson wrote:
        Eric Sosman <Eric.Sosman@su n.comwrites:
        [...]
        > Yes, it is. Note that the prototype-governed conversions cut both
        >ways, though: If you pass a "wide" argument expression to a prototyped
        >function with a "narrower" parameter, the conversion from wide to narrow
        >may lose information silently.
        >
        Or it may give you some unexpected result. Conversion to a signed
        integer type, if the value can't be represented in the target type,
        yields an implementation-defined result (or raises an
        implementation-defined signal; the latter is new in C99).
        Both of these qualify as "losing information," in my view.
        > Similarly, if you pass a floating-point
        >argument to a prototyped integer parameter, the fractional part vanishes
        >silently. (There's the seedling of an IOCCC entry here, I think: try
        >`malloc(atan(4 2.0))' to allocate an 88-byte object ...)
        >
        For certain values of 42.0.
        >
        Actually, for *no* values of 42.0; the results of atan() are in the
        range [-pi/2, +pi/2] (radians).
        Oh, drat! Calculator operating in degree mode instead of radians,
        brain operating in la-la mode instead of with its usual acuituity ...
        But tan(1.5595) would do it. Note that very small changes in the
        argument result in large changes in the result.
        I'd also considered log(1E30) and pow(42.0, 2.40), but they
        seemed insufficiently obfuscatory.

        --
        Eric.Sosman@sun .com

        Comment

        • Keith Thompson

          #5
          Re: function calls, mandatory compiler promotion of int arguments to size_t?

          Eric Sosman <Eric.Sosman@su n.comwrites:
          Keith Thompson wrote:
          >Eric Sosman <Eric.Sosman@su n.comwrites:
          >[...]
          >> Yes, it is. Note that the prototype-governed conversions cut both
          >>ways, though: If you pass a "wide" argument expression to a prototyped
          >>function with a "narrower" parameter, the conversion from wide to narrow
          >>may lose information silently.
          >Or it may give you some unexpected result. Conversion to a signed
          >integer type, if the value can't be represented in the target type,
          >yields an implementation-defined result (or raises an
          >implementati on-defined signal; the latter is new in C99).
          >
          Both of these qualify as "losing information," in my view.
          But raising a signal doesn't necesssarily qualify as "silently".

          [snip]

          --
          Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
          Nokia
          "We must do something. This is something. Therefore, we must do this."
          -- Antony Jay and Jonathan Lynn, "Yes Minister"

          Comment

          • David Mathog

            #6
            Re: function calls, mandatory compiler promotion of int argumentsto size_t?

            Eric Sosman wrote:
            David Mathog wrote:
            >For this small test program:
            >>
            >#include <stdio.h>
            >void main(void){
            >
            Tut. Tut, tut, tut. Consider your wrist slapped.
            Exit status and error checking were intentionally sacrificed for a
            shorter example program. I agree that real programs shouldn't do this,
            but by going with "void main" and throwing out the one status value
            returned the example program was able to drop a few lines which had
            nothing to do with the question at hand.
            >
            Yes, and 6.5.2.2p7: "If the expression that denotes the called
            function has a type that does include a prototype, the arguments are
            implicitly converted, as if by assignment, to the types of the
            corresponding parameters, taking the type of each parameter to be the
            unqualified version of its declared type."
            Perfect, that was exactly what I wanted to know.

            Thanks,

            David Mathog

            Comment

            • Ben Bacarisse

              #7
              Re: function calls, mandatory compiler promotion of int arguments to size_t?

              David Mathog <mathog@caltech .eduwrites:
              Eric Sosman wrote:
              >David Mathog wrote:
              >>For this small test program:
              >>>
              >>#include <stdio.h>
              >>void main(void){
              >>
              > Tut. Tut, tut, tut. Consider your wrist slapped.
              >
              Exit status and error checking were intentionally sacrificed for a
              shorter example program.
              In fact, C99 permits the return <exp>; to be omitted (zero is assumed)
              so int main(void)... is even shorter (OK, by only one character) /and/
              letter-of-the-law correct.

              --
              Ben.

              Comment

              • Antoninus Twink

                #8
                Re: function calls, mandatory compiler promotion of int argumentsto size_t?

                On 1 Aug 2008 at 22:29, David Mathog wrote:
                Eric Sosman wrote:
                >David Mathog wrote:
                >>void main(void){
                >>
                > Tut. Tut, tut, tut. Consider your wrist slapped.
                >
                Exit status and error checking were intentionally sacrificed for a
                shorter example program. I agree that real programs shouldn't do this,
                but by going with "void main" and throwing out the one status value
                returned the example program was able to drop a few lines which had
                nothing to do with the question at hand.
                Unfortunately that won't wash with many of the "regulars" around here.
                They don't know much about C, but they do have a religious zeal for
                getting the return type of main "correct".

                Many of them will try to argue that having void main there might have
                everything to do with the question at hand, since according to clc dogma
                it invokes UB, and they expect the compiler then to do everything in its
                power to make your program go wrong.

                The fact that this is complete nonsense in the real world means not a
                whit to them.

                Comment

                • vippstar@gmail.com

                  #9
                  Re: function calls, mandatory compiler promotion of int arguments tosize_t?

                  On Aug 2, 1:29 am, David Mathog <mat...@caltech .eduwrote:
                  Eric Sosman wrote:
                  David Mathog wrote:
                  For this small test program:
                  >
                  #include <stdio.h>
                  void main(void){
                  >
                  Tut. Tut, tut, tut. Consider your wrist slapped.
                  >
                  Exit status and error checking were intentionally sacrificed for a
                  shorter example program.
                  Then why the superfluous cast in the fwrite call?

                  Comment

                  • Barry Schwarz

                    #10
                    Re: function calls, mandatory compiler promotion of int arguments to size_t?

                    On Fri, 01 Aug 2008 12:48:21 -0700, David Mathog <mathog@caltech .edu>
                    wrote:
                    >For this small test program:
                    >
                    >#include <stdio.h>
                    >void main(void){
                    >char buffer[]="ABCDEFGHIJKLM NOPQRSTUVWXYZ\n ";
                    >int size, count;
                    size = 27; /* always a small number which will fit in an int */
                    count = 1; /* ditto */
                    (void) fwrite(buffer, size, count, stdout);
                    >}
                    >
                    >The int variables size and count are both used for fwrite() arguments
                    >which are prototyped to be size_t. If size_t is bigger than int (as on
                    >some 64 bit systems where size_t is 8 bytes and int is 4 bytes), does
                    >the C standard require the compiler to promote these two int values to
                    >size_t before passing them to the function, and if so, what exactly does
                    >it say?
                    As long as others have picked the nits, this is not a promotion in the
                    way the standard uses the term. It is a conversion as if by
                    assignment. If you change size and count to long and have a system
                    where size_t is unsigned int, the compiler is still required to
                    convert the arguments to the type expected by the called function
                    (even though it is a demotion).

                    --
                    Remove del for email

                    Comment

                    • santosh

                      #11
                      Re: function calls, mandatory compiler promotion of int arguments to size_t?

                      vippstar@gmail. com wrote:
                      On Aug 2, 2:21 pm, santosh <santosh....@gm ail.comwrote:
                      >vipps...@gmail .com wrote:
                      On Aug 1, 10:48 pm, David Mathog <mat...@caltech .eduwrote:
                      >For this small test program:
                      >>
                      >#include <stdio.h>
                      >void main(void){
                      >char buffer[]="ABCDEFGHIJKLM NOPQRSTUVWXYZ\n ";
                      >int size, count;
                      > size = 27; /* always a small number which will fit in an int
                      > */
                      > count = 1; /* ditto
                      > */ (void) fwrite(buffer, size, count, stdout);
                      >>
                      >}
                      >>
                      >[ ... ]
                      >I know that in _practice_ the code above works, but I am curious
                      >if that must always be the case.
                      >>
                      It doesn't, it's not.
                      >>
                      >Does it _really_ fail if 'size' and 'count' are switched in this
                      >case? [ ... ]
                      They are both correct. However I was refering to 'void main()'.
                      (assuming hosted implementation)
                      Ah, OK. I failed to notice that error.

                      Comment

                      • blargg

                        #12
                        Re: function calls, mandatory compiler promotion of int arguments to size_t?

                        In article <slrng97476.438 .nospam@nospam. invalid>, Antoninus Twink
                        <nospam@nospam. invalidwrote:
                        On 1 Aug 2008 at 22:29, David Mathog wrote:
                        Eric Sosman wrote:
                        David Mathog wrote:
                        >void main(void){
                        >
                        Tut. Tut, tut, tut. Consider your wrist slapped.
                        Exit status and error checking were intentionally sacrificed for a
                        shorter example program. I agree that real programs shouldn't do this,
                        but by going with "void main" and throwing out the one status value
                        returned the example program was able to drop a few lines which had
                        nothing to do with the question at hand.
                        >
                        Unfortunately that won't wash with many of the "regulars" around here.
                        They don't know much about C, but they do have a religious zeal for
                        getting the return type of main "correct".
                        >
                        Many of them will try to argue that having void main there might have
                        everything to do with the question at hand, since according to clc dogma
                        it invokes UB, and they expect the compiler then to do everything in its
                        power to make your program go wrong.
                        Sometimes UB like this is relevant to the person's question/problem, so
                        ignoring it might be ignoring the problem. Besides, it's an easy fix and
                        why not use the context as an opportunity to educate?
                        The fact that this is complete nonsense in the real world means not a
                        whit to them.
                        Either one is posting a compilable, runnable example, or one is not. If
                        not, why bother with #include <stdio.h>, or a main function at all?

                        Comment

                        • CBFalconer

                          #13
                          Re: function calls, mandatory compiler promotion of int arguments tosize_t?

                          blargg wrote:
                          Antoninus Twink <nospam@nospam. invalidwrote:
                          >
                          .... snip ...
                          >
                          Sometimes UB like this is relevant to the person's question/problem
                          >, so ignoring it might be ignoring the problem. Besides, it's an
                          easy fix and why not use the context as an opportunity to educate?
                          >
                          >The fact that this is complete nonsense in the real world means
                          >not a whit to them.
                          >
                          Either one is posting a compilable, runnable example, or one is
                          not. If not, why bother with #include <stdio.h>, or a main
                          function at all?
                          Ignoring the fact that Twink is a troll, if not posting a complete
                          compilable and runnable program, why bother posting at all? Think
                          of the electrons that could be saved. You will save time and be
                          able to contribute to PETE.

                          --
                          [mail]: Chuck F (cbfalconer at maineline dot net)
                          [page]: <http://cbfalconer.home .att.net>
                          Try the download section.


                          Comment

                          • s0suk3@gmail.com

                            #14
                            Re: function calls, mandatory compiler promotion of int arguments tosize_t?

                            On Aug 3, 3:23 am, blargg....@gish puppy.com (blargg) wrote:
                            In article <slrng97476.438 .nos...@nospam. invalid>, Antoninus Twink
                            >
                            >
                            >
                            <nos...@nospam. invalidwrote:
                            On 1 Aug 2008 at 22:29, David Mathog wrote:
                            Eric Sosman wrote:
                            >David Mathog wrote:
                            >>void main(void){
                            >
                            > Tut. Tut, tut, tut. Consider your wrist slapped.
                            >
                            Exit status and error checking were intentionally sacrificed for a
                            shorter example program. I agree that real programs shouldn't do this,
                            but by going with "void main" and throwing out the one status value
                            returned the example program was able to drop a few lines which had
                            nothing to do with the question at hand.
                            >
                            Unfortunately that won't wash with many of the "regulars" around here.
                            They don't know much about C, but they do have a religious zeal for
                            getting the return type of main "correct".
                            >
                            Many of them will try to argue that having void main there might have
                            everything to do with the question at hand, since according to clc dogma
                            it invokes UB, and they expect the compiler then to do everything in its
                            power to make your program go wrong.
                            >
                            Sometimes UB like this is relevant to the person's question/problem, so
                            ignoring it might be ignoring the problem. Besides, it's an easy fix and
                            why not use the context as an opportunity to educate?
                            >
                            The fact that this is complete nonsense in the real world means not a
                            whit to them.
                            >
                            Either one is posting a compilable, runnable example, or one is not. If
                            not, why bother with #include <stdio.h>, or a main function at all?
                            It *is* compilable and runnable, but perhaps not with all compilers.
                            AFAIK, the standard states that an implementation may accept an
                            implementation-defined prototype for main(). I'd expect 'void
                            main(void)' to be a common choice for such prototype, seems it looks
                            fairly natural and is the one used in other languages.

                            Sebastian

                            Comment

                            • santosh

                              #15
                              Re: function calls, mandatory compiler promotion of int arguments to size_t?

                              s0suk3@gmail.co m wrote:

                              <snip>
                              AFAIK, the standard states that an implementation may accept an
                              implementation-defined prototype for main(). I'd expect 'void
                              main(void)' to be a common choice for such prototype, seems it looks
                              fairly natural and is the one used in other languages.
                              I would always return a sensible value back to the system. Returning
                              garbage values (which is what happens when you use void main) breaks
                              scripts and wrapper programs. Just return 0 or EXIT_FAILURE. Why is
                              this so hard?

                              Comment

                              Working...