Simple Casting Question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Pietro Cerutti

    #16
    Re: Simple Casting Question

    Bart wrote:
    But for setting to 9.82 for example, only (2) and (4) can be used. And
    when PRECISION is int, you may find it rounds wrongly (to 9 not 10).
    It doesn't round, it truncates.

    Bartc
    --
    Pietro Cerutti

    Comment

    • alex.j.k2@gmail.com

      #17
      Re: Simple Casting Question

      On May 19, 8:33 am, Barry Schwarz <schwar...@yaho o.comwrote:
      On May 18, 7:17 pm, alex.j...@gmail .com wrote:
      >
      I do make sure in the preprocessor code that all casting is done
      only in the form (int to float), (float to double), (int to double),
      or just casting identical types, so I hope that I can avoid some
      errors that way.
      >
      How did you avoid the equally emphatic consensus that superfluous
      casting is a very bad idea? None of the conversions you describe
      needs a cast as long as there are prototypes in scope when you call
      the functions involved.
      What I meant by my paragraph above is that I force the user to
      define the types such that most type conversions / casts are of the
      kind described above. Based on the replies here I do plan to rely
      more on implicit conversions rather than casting.

      I would still like to know more examples of the types of errors
      introduced by casting.
      Relying on expert opinion is wise, but learning from examples is
      more educative.

      Alex

      Comment

      • Bart

        #18
        Re: Simple Casting Question

        On May 19, 1:42 pm, Pietro Cerutti <g...@gahr.chwr ote:
        Bart wrote:
        But for setting to 9.82 for example, only (2) and (4) can be used. And
        when PRECISION is int, you may find it rounds wrongly (to 9 not 10).
        >
        It doesn't round, it truncates.
        Exactly.

        --
        Bartc

        Comment

        • Nick Keighley

          #19
          Re: Simple Casting Question

          On 19 May, 03:17, alex.j...@gmail .com wrote:
          First of all, thank you to all that answered.
          On May 18, 8:58 pm, Keith Thompson <ks...@mib.orgw rote:
          All four are correct.  The third is preferred, IMHO.
          >
          This is the consensus.
          >
          It does seem odd that PRECISION can be either an integer type or a
          floating-point type.  Integer and floating-point types behave in very
          different, and sometimes quite subly different, ways.  I would think
          that writing code that doesn't know whether it's dealing with integers
          or floating-point values would be difficult and error-prone.
          he *could* be using floating point as large integers.

            I have a function that does large amounts of computations
          (divisions, square roots, etc.) for large datasets.
          not so good...

          #include <math.h>
          #include <stdio.h>

          int main (void)
          {
          double d1 = 5, d2;
          int i1 = 5, i2;

          d2 = sqrt(d1);
          i2 = sqrt(i1);

          printf ("square root 5 is %f\n", d2);
          printf ("square root 5 is %d\n", i2);

          return 0;
          }

          I submit if you did a series of computations
          using d2 then i2 you'd get wildly diverging results.

          For efficiency reasons
          more sins have been committed in the name of efficiency...
          Do you mean faster? How do you know the floating point
          version is too slow? Have you measured it?

          I allow the option to format the data differently.
          I also have a large dataset of integers which I have to feed to the
          function.
          >
            I do make sure in the preprocessor code that all casting is done
          only in the form (int to float), (float to double), (int to double),
          I don't see how this helps. If you don't know the type how can you
          ensure this?

          or just casting identical types, so I hope that I can avoid some
          errors that way.
          why would you cast identical types?

            I am curios about the subtle and not so subtle bugs introduced
          by overenthusiasti c uses of casting.
            Do you have a reference/link/short paragraph related to this theme?
          there's the malloc example.

          I once saw this code:

          void f (char str)
          {
          strcpy (str, "bing");
          }

          It failed to compile. So the programmer fixed it thus:-

          void f (char str)
          {
          strcpy ((char*)str, "bing");
          }


          To summerise:

          1. I think your PRECISION macro is a bad idea
          2. avoid casting as much as possible


          --
          Abuse of casting leads to abuse of the type system
          leads to sloppy programming leads to
          unreliably, even undefined, behaviour.
          And that is the path to the dark side....
          Richard Bos/John Hascall

          Comment

          • alex.j.k2@gmail.com

            #20
            Re: Simple Casting Question

            On May 19, 10:06 am, Nick Keighley <nick_keighley_ nos...@hotmail. com>
            wrote:
            I have a function that does large amounts of computations
            (divisions, square roots, etc.) for large datasets.
            >
            not so good...
            >
            #include <math.h>
            #include <stdio.h>
            >
            int main (void)
            {
            double d1 = 5, d2;
            int i1 = 5, i2;
            >
            d2 = sqrt(d1);
            i2 = sqrt(i1);
            >
            printf ("square root 5 is %f\n", d2);
            printf ("square root 5 is %d\n", i2);
            >
            return 0;
            >
            }
            >
            I submit if you did a series of computations
            using d2 then i2 you'd get wildly diverging results.
            >
            There is not a single place in my code where the
            returned value of sqrt() can be attributed to an integer.
            For efficiency reasons
            >
            more sins have been committed in the name of efficiency...
            Do you mean faster? How do you know the floating point
            version is too slow? Have you measured it?
            >
            It's mainly about the size of the input data. Some of
            my datasets are large enough that storing it as float or int
            is significantly more efficient that storing it as double.

            I do make sure in the preprocessor code that all casting is done
            only in the form (int to float), (float to double), (int to double),
            >
            I don't see how this helps. If you don't know the type how can you
            ensure this?
            >
            It helps for instance by avoiding the need for casting
            and thus relying on implicit conversions. As another example,
            all the types that may store square roots, are forced to be
            either float or double.

            I do know the type in the preprocessor code. I just want
            to allow the ability to change the type in said preprocessor
            code.
            I am curios about the subtle and not so subtle bugs introduced
            by overenthusiasti c uses of casting.
            Do you have a reference/link/short paragraph related to this theme?
            >
            there's the malloc example.
            >
            I once saw this code:
            >
            void f (char str)
            {
            strcpy (str, "bing");
            }
            >
            It failed to compile. So the programmer fixed it thus:-
            >
            void f (char str)
            {
            strcpy ((char*)str, "bing");
            }
            >
            That's funny. Thanks for the examples.
            To summerise:
            >
            1. I think your PRECISION macro is a bad idea
            Well, some think coding in C is a bad idea. I think
            the macro is useful for my purposes.
            2. avoid casting as much as possible
            >
            That I will do.

            Alex

            Comment

            • Keith Thompson

              #21
              Re: Simple Casting Question

              vippstar@gmail. com writes:
              On May 19, 1:05 pm, pete <pfil...@mindsp ring.comwrote:
              >alex.j...@gmai l.com wrote:
              I am curios about the subtle and not so subtle bugs introduced
              by overenthusiasti c uses of casting.
              Do you have a reference/link/short paragraph related to this theme?
              >>
              >Whenever <stdlib.hwas not #included and malloc was used,
              >C89 compilers tended to recommend casting the return value of malloc.
              >The use of such a cast would suppress that warning,
              >but yield undefined behavior.
              >>
              >The proper advice, is to #include <stdlib.hprio r to using malloc.
              >That also suppresses whatever warning
              >would result from the non-inclusion, but helps make for correct code.
              It is also possible to include just the prototype of malloc
              void *malloc(size_t) ; and not <stdlib.h>.
              Yes, it's possible, but there's no advantage over ``#include <stdlib.h>''.

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

              • Keith Thompson

                #22
                Re: Simple Casting Question

                alex.j.k2@gmail .com writes:
                On May 19, 8:33 am, Barry Schwarz <schwar...@yaho o.comwrote:
                >On May 18, 7:17 pm, alex.j...@gmail .com wrote:
                I do make sure in the preprocessor code that all casting is done
                only in the form (int to float), (float to double), (int to double),
                or just casting identical types, so I hope that I can avoid some
                errors that way.
                >>
                >How did you avoid the equally emphatic consensus that superfluous
                >casting is a very bad idea? None of the conversions you describe
                >needs a cast as long as there are prototypes in scope when you call
                >the functions involved.
                >
                What I meant by my paragraph above is that I force the user to
                define the types such that most type conversions / casts are of the
                kind described above. Based on the replies here I do plan to rely
                more on implicit conversions rather than casting.
                >
                I would still like to know more examples of the types of errors
                introduced by casting.
                Relying on expert opinion is wise, but learning from examples is
                more educative.
                In most cases where a cast is (mis-)used, assuming the writer got the
                type right, the code would mean exactly the same thing without the
                cast, because the same conversion will be done explicitly. In such
                cases, the cast does nothing but add clutter and introduce a risk of
                error that wouldn't be there without the cast. (I suggest, therefore,
                that the burden is on the advocate of a cast to demonstrate that it's
                useful.)

                An example where a cast can introduce an error:

                x = (float)y;

                Assume y is of some arithmetic type. If x is of type float, this is
                ok (but unnecessary). But suppose x is of type double (maybe you
                changed the declaration a year after you wrote the original code).
                Then the explicit conversion to float will lose precision -- and it
                will do so without a peep of complaint from the compiler. If you had
                just written:

                x = y;

                the the implicit conversion would have done the right thing.

                A cast tells the compiler, "Shut up, I know what type I want" -- and
                sometimes you don't, especially as your code is maintained over time.

                C90's "implicit int" rule presents another problem. For example:

                some_type *ptr = (some_type*)mal loc(sizeof(some _type));

                If you forgot the required ``#include <stdlib.h>'', then the compiler
                (under C90 rules, changed in C99) *assumes* that malloc is a function
                returning int. It actually returns void*. One possibility is that
                the call will interpret the void* result as if it were of type int,
                and then convert the int value to some_type* (which may or may not
                "work" depending on the implementation) . Or, if integers and pointers
                are returned in different registers, you might get complete garbage.

                Most compilers these days will warn about this error if you ask them
                nicely, but if you just omit the cast the assignment of an int to
                a pointer is illegal.

                Of course there are cases where casts are necessary and appropriate.
                If you need to convert a pointer to an integer, or vice versa, or
                between two different pointer types, you need a cast, since those
                conversions aren't done explicitly (other than the special case of a
                null pointer constant). Such conversions are implementation-defined,
                so you'd better know what you're doing. If you're passing an argument
                to a variadic function, the compiler doesn't know the target type,
                so you have to specify it yourself:

                printf("sizeof( double) = %d\n", (int)sizeof(dou ble));

                But in these cases, you *have* to get the target type right; the
                compiler won't diagnose an error.

                See also the comp.lang.c FAQ, <http://www.c-faq.com/>.

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

                • Keith Thompson

                  #23
                  Re: Simple Casting Question

                  Bart <bc@freeuk.comw rites:
                  On May 19, 1:42 pm, Pietro Cerutti <g...@gahr.chwr ote:
                  >Bart wrote:
                  But for setting to 9.82 for example, only (2) and (4) can be used. And
                  when PRECISION is int, you may find it rounds wrongly (to 9 not 10).
                  >>
                  >It doesn't round, it truncates.
                  >
                  Exactly.
                  I think Pietro's point was that it doesn't "round wrongly", it
                  truncates correctly. Your point was correct, but oddly stated.

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

                  • CBFalconer

                    #24
                    Re: Simple Casting Question

                    vippstar@gmail. com wrote:
                    pete <pfil...@mindsp ring.comwrote:
                    >
                    .... snip ...
                    >>
                    >The proper advice, is to #include <stdlib.hprio r to using
                    >malloc. That also suppresses whatever warning would result from
                    >the non-inclusion, but helps make for correct code.
                    >
                    It is also possible to include just the prototype of malloc
                    void *malloc(size_t) ; and not <stdlib.h>.
                    I believe this is defined to lead to undefined behaviour (which may
                    work as you want it). In this case it will usually work, but no
                    guarantees.

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


                    ** Posted from http://www.teranews.com **

                    Comment

                    • Keith Thompson

                      #25
                      Re: Simple Casting Question

                      CBFalconer <cbfalconer@yah oo.comwrites:
                      vippstar@gmail. com wrote:
                      >pete <pfil...@mindsp ring.comwrote:
                      >>
                      ... snip ...
                      >>>
                      >>The proper advice, is to #include <stdlib.hprio r to using
                      >>malloc. That also suppresses whatever warning would result from
                      >>the non-inclusion, but helps make for correct code.
                      >>
                      >It is also possible to include just the prototype of malloc
                      >void *malloc(size_t) ; and not <stdlib.h>.
                      >
                      I believe this is defined to lead to undefined behaviour (which may
                      work as you want it). In this case it will usually work, but no
                      guarantees.
                      No, if you provide a correct prototype for a standard function, it
                      will work correctly. (If you get the prototype wrong, of course, the
                      behavior is undefined.)

                      Having said that, I can't think of any good reason to write the
                      prototype yourself rather than getting it from the standard header.

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

                      • Ian Collins

                        #26
                        Re: Simple Casting Question

                        Keith Thompson wrote:
                        CBFalconer <cbfalconer@yah oo.comwrites:
                        >vippstar@gmail. com wrote:
                        >>pete <pfil...@mindsp ring.comwrote:
                        >>>
                        >... snip ...
                        >>>The proper advice, is to #include <stdlib.hprio r to using
                        >>>malloc. That also suppresses whatever warning would result from
                        >>>the non-inclusion, but helps make for correct code.
                        >>It is also possible to include just the prototype of malloc
                        >>void *malloc(size_t) ; and not <stdlib.h>.
                        >I believe this is defined to lead to undefined behaviour (which may
                        >work as you want it). In this case it will usually work, but no
                        >guarantees.
                        >
                        No, if you provide a correct prototype for a standard function, it
                        will work correctly. (If you get the prototype wrong, of course, the
                        behavior is undefined.)
                        >
                        Is it legal for an implementation to include implementation specific
                        magic (calling conventions for example) in its standard library function
                        declarations?

                        --
                        Ian Collins.

                        Comment

                        • Harald van =?UTF-8?b?RMSzaw==?=

                          #27
                          Re: Simple Casting Question

                          On Tue, 20 May 2008 08:57:10 +1200, Ian Collins wrote:
                          Keith Thompson wrote:
                          >No, if you provide a correct prototype for a standard function, it will
                          >work correctly. (If you get the prototype wrong, of course, the
                          >behavior is undefined.)
                          >>
                          Is it legal for an implementation to include implementation specific
                          magic (calling conventions for example) in its standard library function
                          declarations?
                          This is allowed if without including the function's header, you can still
                          call the function by declaring it manually with a compatible function
                          declaration, with or without a prototype, and if after including the
                          function's header the function can be assigned to a compatible function
                          pointer and called like that. This allows alternate calling conventions,
                          if the calling convention specifies that the function saves more
                          registers than usual, for example. It does not allow alternate calling
                          conventions if arguments are passed via a different mechanism.

                          Comment

                          • Keith Thompson

                            #28
                            Re: Simple Casting Question

                            Ian Collins <ian-news@hotmail.co mwrites:
                            Keith Thompson wrote:
                            >CBFalconer <cbfalconer@yah oo.comwrites:
                            >>vippstar@gmail. com wrote:
                            >>>pete <pfil...@mindsp ring.comwrote:
                            >>>>
                            >>... snip ...
                            >>>>The proper advice, is to #include <stdlib.hprio r to using
                            >>>>malloc. That also suppresses whatever warning would result from
                            >>>>the non-inclusion, but helps make for correct code.
                            >>>It is also possible to include just the prototype of malloc
                            >>>void *malloc(size_t) ; and not <stdlib.h>.
                            >>I believe this is defined to lead to undefined behaviour (which may
                            >>work as you want it). In this case it will usually work, but no
                            >>guarantees.
                            >>
                            >No, if you provide a correct prototype for a standard function, it
                            >will work correctly. (If you get the prototype wrong, of course, the
                            >behavior is undefined.)
                            >>
                            Is it legal for an implementation to include implementation specific
                            magic (calling conventions for example) in its standard library function
                            declarations?
                            Only if the magic doesn't violate C99 7.1.4p2:

                            Provided that a library function can be declared without reference
                            to any type defined in a header, it is also permissible to declare
                            the function and use it without including its associated header.

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

                            • Peter Nilsson

                              #29
                              Re: Simple Casting Question

                              Keith Thompson wrote:
                              CBFalconer <cbfalconer@yah oo.comwrites:
                              vippstar@gmail. com wrote:
                              pete <pfil...@mindsp ring.comwrote:
                              >
                              ... snip ...

                              The proper advice, is to #include <stdlib.hprio r to
                              using malloc. That also suppresses whatever warning
                              would result from the non-inclusion, but helps make
                              for correct code.
                              >
                              It is also possible to include just the prototype of malloc
                              void *malloc(size_t) ; and not <stdlib.h>.
                              I believe this is defined to lead to undefined behaviour
                              (which may work as you want it). In this case it will usually
                              work, but no guarantees.
                              Chalk another one up to the anti-malloc casters FUD file. ;-)
                              No, if you provide a correct prototype for a standard function,
                              it will work correctly. (If you get the prototype wrong, of
                              course, the behavior is undefined.)
                              >
                              Having said that, I can't think of any good reason to write
                              the prototype yourself rather than getting it from the standard
                              header.
                              On a freestanding environment, the function may be available,
                              but the header needn't be. Of course, I can't think of a good
                              reason why that would be the case...

                              --
                              Peter

                              Comment

                              • Keith Thompson

                                #30
                                Re: Simple Casting Question

                                Peter Nilsson <airia@acay.com .auwrites:
                                Keith Thompson wrote:
                                [...]
                                >No, if you provide a correct prototype for a standard function,
                                >it will work correctly. (If you get the prototype wrong, of
                                >course, the behavior is undefined.)
                                >>
                                >Having said that, I can't think of any good reason to write
                                >the prototype yourself rather than getting it from the standard
                                >header.
                                >
                                On a freestanding environment, the function may be available,
                                but the header needn't be. Of course, I can't think of a good
                                reason why that would be the case...
                                I've seen implementations where, for some functions, the declaration
                                in the header was inconsistent with the actual implementation. You
                                could work around this by declaring the function yourself. (I don't
                                remember the details; might have been gcc under SunOS 4.1.3.)

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

                                Working...