Stupid or clever hack?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • badc0de4@gmail.com

    Stupid or clever hack?

    Is this a stupid hack or a clever hack?
    Is it a "hack" at all?

    =============== =====

    #include <stdio.h>

    /* !!HACK!! */
    /* no parenthesis on the #define'd expression */
    #define MY_FLOAT_CONSTA NT_HACKED 15 / 4

    int main(void)
    {
    printf("The value is %d.\n", 100 * MY_FLOAT_CONSTA NT_HACKED); /* !!
    HACK!! */
    return 0;
    }

    =============== =

    Is it so much better to do it the proper way, which implies a few type
    conversions, implicit and explicit?

    #define MY_CONSTANT 3.75
    printf( "%d\n", (int)(100 * MY_CONSTANT) );

    Thanks
  • Joachim Schmitz

    #2
    Re: Stupid or clever hack?

    badc0de4@gmail. com wrote:
    Is this a stupid hack or a clever hack?
    Is it a "hack" at all?
    >
    =============== =====
    >
    #include <stdio.h>
    >
    /* !!HACK!! */
    /* no parenthesis on the #define'd expression */
    #define MY_FLOAT_CONSTA NT_HACKED 15 / 4
    >
    int main(void)
    {
    printf("The value is %d.\n", 100 * MY_FLOAT_CONSTA NT_HACKED); /* !!
    HACK!! */
    return 0;
    }
    >
    =============== =
    >
    Is it so much better to do it the proper way, which implies a few type
    conversions, implicit and explicit?
    >
    #define MY_CONSTANT 3.75
    printf( "%d\n", (int)(100 * MY_CONSTANT) );
    >
    Why not
    #define MY_FLOAT_CONSTA NT (15.0/4.0)

    Bye, Jojo


    Comment

    • viza

      #3
      Re: Stupid or clever hack?

      On Jun 10, 7:25 pm, badc0...@gmail. com wrote:
      #define MY_FLOAT_CONSTA NT_HACKED 15 / 4
      >
      100 * MY_FLOAT_CONSTA NT_HACKED
      ( 100 * MY_FLOAT_CONSTA NT_HACKED ) != ( MY_FLOAT_CONSTA NT_HACKED *
      100 )

      which is contrary to what most people would expect, and so is a very
      bad idea if anyone else has to read the code, or even if you want to
      be able to read it in six months time.

      That is not to say that rational number multiplication is not a good
      substitute for floating point multiplication in some circumstances,
      but I would suggest that you do it like this:

      #define MY_FLOAT_MULT(i ) ( ( (i) * 15 ) / 4 )

      printf( "The value is %d.\n", MY_FLOAT_MULT(1 00) );

      HTH

      viza

      Comment

      • user923005

        #4
        Re: Stupid or clever hack?

        On Jun 10, 11:25 am, badc0...@gmail. com wrote:
        Is this a stupid hack or a clever hack?
        Is it a "hack" at all?
        >
        =============== =====
        >
        #include <stdio.h>
        >
        /* !!HACK!! */
        /* no parenthesis on the #define'd expression */
        #define MY_FLOAT_CONSTA NT_HACKED 15 / 4
        >
        int main(void)
        {
          printf("The value is %d.\n", 100 * MY_FLOAT_CONSTA NT_HACKED); /* !!
        HACK!! */
          return 0;
        >
        }
        >
        =============== =
        >
        Is it so much better to do it the proper way, which implies a few type
        conversions, implicit and explicit?
        >
        #define MY_CONSTANT 3.75
        printf( "%d\n", (int)(100 * MY_CONSTANT) );
        My opinion is that it is an utter piece of garbage.

        An unparenthesized macro is a disaster waiting to happen.

        This is ambiguous and mildly misleading as to what is intended (after
        all, MY_FLOAT_CONSTA NT_HACKED is NOT a float constant and a float
        constant would promote the 100 and hence %d would be the wrong
        printf() specifier):
        printf("The value is %d.\n", 100 * MY_FLOAT_CONSTA NT_HACKED);
        This is clear:
        printf("The value is %d.\n", 100 * 15 / 4);
        so what is achieved by the macro is minor obfuscation and the
        introduction of a dangerous construct.

        Don't do that.
        IMO-YMMV

        Comment

        • badc0de4@gmail.com

          #5
          Re: Stupid or clever hack?

          viza wrote:
          On Jun 10, 7:25 pm, badc0...@gmail. com wrote:
          >
          #define MY_FLOAT_CONSTA NT_HACKED 15 / 4
          printf("The value is %d.\n", 100 * MY_FLOAT_CONSTA NT_HACKED);
          [...]
          #define MY_FLOAT_MULT(i ) ( ( (i) * 15 ) / 4 )
          >
          printf( "The value is %d.\n", MY_FLOAT_MULT(1 00) );
          >
          HTH
          It helps a lot. Thank you.

          Thank you for your and the other posters comments too.

          Comment

          • Keith Thompson

            #6
            Re: Stupid or clever hack?

            badc0de4@gmail. com writes:
            Is this a stupid hack or a clever hack?
            Is it a "hack" at all?
            >
            =============== =====
            >
            #include <stdio.h>
            >
            /* !!HACK!! */
            /* no parenthesis on the #define'd expression */
            #define MY_FLOAT_CONSTA NT_HACKED 15 / 4
            >
            int main(void)
            {
            printf("The value is %d.\n", 100 * MY_FLOAT_CONSTA NT_HACKED); /* !!
            HACK!! */
            return 0;
            }
            >
            =============== =
            It's a stupid hack.
            Is it so much better to do it the proper way, which implies a few type
            conversions, implicit and explicit?
            >
            #define MY_CONSTANT 3.75
            printf( "%d\n", (int)(100 * MY_CONSTANT) );
            With your version of the macro, the expression

            100 * MY_FLOAT_CONSTA NT_HACKED

            expands to

            100 * 15 / 4

            which is really

            (100 * 15) / 4

            Using a macro to violate operator precedence is a bad idea.

            What would make sense is to put the entire expression into a macro:

            #define WHATEVER (100 * 15 / 4)

            Or, if you want to parameterize it, perhaps something like this:

            #define WHATEVER(x, y) (100 * (x) / (y))

            BTW, here's my example of How Not To Use Macros (designed for Douglas
            Adams fans):

            =============== =============== ==
            #include <stdio.h>

            #define SIX 1+5
            #define NINE 8+1

            int main(void)
            {
            printf("%d * %d = %d\n", SIX, NINE, SIX * NINE);
            return 0;
            }
            =============== =============== ==

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

            • pete

              #7
              Re: Stupid or clever hack?

              user923005 wrote:
              My opinion is that it is an utter piece of garbage.
              >
              An unparenthesized macro is a disaster waiting to happen.
              >
              This is ambiguous and mildly misleading as to what is intended (after
              all, MY_FLOAT_CONSTA NT_HACKED is NOT a float constant and a float
              constant would promote the 100 and hence %d would be the wrong
              printf() specifier):
              printf("The value is %d.\n", 100 * MY_FLOAT_CONSTA NT_HACKED);
              This is clear:
              printf("The value is %d.\n", 100 * 15 / 4);
              That *is* clear.
              I've written code that way.
              so what is achieved by the macro is minor obfuscation and the
              introduction of a dangerous construct.
              >
              Don't do that.
              IMO-YMMV

              --
              pete

              Comment

              • Sri Harsha Dandibhotla

                #8
                Re: Stupid or clever hack?

                On Jun 11, 12:26 am, Keith Thompson <ks...@mib.orgw rote:
                >
                BTW, here's my example of How Not To Use Macros (designed for Douglas
                Adams fans):
                >
                =============== =============== ==
                #include <stdio.h>
                >
                #define SIX 1+5
                #define NINE 8+1
                >
                int main(void)
                {
                printf("%d * %d = %d\n", SIX, NINE, SIX * NINE);
                return 0;}
                >
                =============== =============== ==
                >
                :-)
                Ahh.. now I realise. There was this same bug in Deep Thought's code.

                Comment

                Working...