Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. defining a function with #define

defining a function with #define

Scheduled Pinned Locked Moved C / C++ / MFC
helptutorialquestion
7 Posts 6 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    coco243
    wrote on last edited by
    #1

    Hi, Please help me understanding the following declaration:

    #define EVENBYTE( i ) ((i+7)/8*8)

    It represents the definition of function? If for example I call EVENBYTE( 1 ), the result will be ((1+7)/8*8)? From where I have extracted de code, the EVENBYTE was called in that way:

    int nIconBytes = (EVENBYTE(nWidth)/8)*nHeight;

    I don't understand what this kind of declaring is and why to do it in that mode? Thank you in advance.

    Mircea NeacsuM L 2 Replies Last reply
    0
    • C coco243

      Hi, Please help me understanding the following declaration:

      #define EVENBYTE( i ) ((i+7)/8*8)

      It represents the definition of function? If for example I call EVENBYTE( 1 ), the result will be ((1+7)/8*8)? From where I have extracted de code, the EVENBYTE was called in that way:

      int nIconBytes = (EVENBYTE(nWidth)/8)*nHeight;

      I don't understand what this kind of declaring is and why to do it in that mode? Thank you in advance.

      Mircea NeacsuM Offline
      Mircea NeacsuM Offline
      Mircea Neacsu
      wrote on last edited by
      #2

      No, it is not a function, it is a macro definition. While, in your case a function defined as:

      int evenbyte (int i) {return (i+7)/8*8;}

      would do the same thing, there is an important difference: a macro definition is expanded at compile time while a function is compiled and later on called at runtime. When to use one over the other is a question of optimization speed vs memory: a macro definition like your would not incur the overhead of a call but might produce larger code. Meanwhile a function definition would produce smaller code but might take longer to execute. To solve these type of issues, C++ has introduced inline functions, so in C++ you can write

      inline int evenbyte (int i) {return (i+7)/8*8;}

      and you leave the compiler the choice of expanding it inline (like a macro definition) or make it a function and call it. One more thing: the macro definition is insensitive to the type of argument. That is both a good thing and a bad thing like in the examples below:

      int i1 = 3;
      int e1 = EVENBYTE (i1); //calling macro with an int argument yields an int result
      long i2 = 129;
      long e2 = EVENBYTE (e2); //calling macro with a long argument yields a long result

      int e3 = EVENBYTE ("abc"); //generates some obscure error message

      To accomplish the same thing in C++ you would have to use a function template:

      template
      T evenbyte (T i) { return (i+7)/8*8;}

      Mircea

      T 1 Reply Last reply
      0
      • C coco243

        Hi, Please help me understanding the following declaration:

        #define EVENBYTE( i ) ((i+7)/8*8)

        It represents the definition of function? If for example I call EVENBYTE( 1 ), the result will be ((1+7)/8*8)? From where I have extracted de code, the EVENBYTE was called in that way:

        int nIconBytes = (EVENBYTE(nWidth)/8)*nHeight;

        I don't understand what this kind of declaring is and why to do it in that mode? Thank you in advance.

        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #3

        coco243 wrote:

        Please help me understanding the following declaration

        Kinda looks like something used for calculating Image stride[^].

        C 1 Reply Last reply
        0
        • Mircea NeacsuM Mircea Neacsu

          No, it is not a function, it is a macro definition. While, in your case a function defined as:

          int evenbyte (int i) {return (i+7)/8*8;}

          would do the same thing, there is an important difference: a macro definition is expanded at compile time while a function is compiled and later on called at runtime. When to use one over the other is a question of optimization speed vs memory: a macro definition like your would not incur the overhead of a call but might produce larger code. Meanwhile a function definition would produce smaller code but might take longer to execute. To solve these type of issues, C++ has introduced inline functions, so in C++ you can write

          inline int evenbyte (int i) {return (i+7)/8*8;}

          and you leave the compiler the choice of expanding it inline (like a macro definition) or make it a function and call it. One more thing: the macro definition is insensitive to the type of argument. That is both a good thing and a bad thing like in the examples below:

          int i1 = 3;
          int e1 = EVENBYTE (i1); //calling macro with an int argument yields an int result
          long i2 = 129;
          long e2 = EVENBYTE (e2); //calling macro with a long argument yields a long result

          int e3 = EVENBYTE ("abc"); //generates some obscure error message

          To accomplish the same thing in C++ you would have to use a function template:

          template
          T evenbyte (T i) { return (i+7)/8*8;}

          Mircea

          T Offline
          T Offline
          trønderen
          wrote on last edited by
          #4

          Also worth noting: A macro does not define its own scope, the way a function does. It could refer to other symbols, say,

          #define PLUSX(i) (i + x)

          Which x is added? That depends on where PLUSX is used. In one place it could be a different x than in another place. In a third place, there may be no x defined at all, and you get a compilation error, even if the two first uses of PLUSX went without any error. A define is a pure textual replacement. If you in your code editor replace 'PLUSX(i)' with '(i + x)' (and change the 'i' in the replacement text to whatever was the name of your actual argument), you are doing by hand the work of the C preprocessor. Or in your case, if in your editor you replace

          int nIconBytes = (EVENBYTE(nWidth)/8)*nHeight;

          with

          int nIconBytes = (((nWidth+7)/8*8)/8)*nHeight;

          then you get the exact same result as with the #define. Note: I am certainly not suggesting that referring to non-argument variables from macros is a good idea (usually is is not), but understanding how macros differ from functions includes understanding how such references would work. Personal opinion: #define is among the most mis-used features of the C language. Except for giving symbolic names to simple constants, you should try to avoid it as far as possible.

          Greg UtasG 1 Reply Last reply
          0
          • T trønderen

            Also worth noting: A macro does not define its own scope, the way a function does. It could refer to other symbols, say,

            #define PLUSX(i) (i + x)

            Which x is added? That depends on where PLUSX is used. In one place it could be a different x than in another place. In a third place, there may be no x defined at all, and you get a compilation error, even if the two first uses of PLUSX went without any error. A define is a pure textual replacement. If you in your code editor replace 'PLUSX(i)' with '(i + x)' (and change the 'i' in the replacement text to whatever was the name of your actual argument), you are doing by hand the work of the C preprocessor. Or in your case, if in your editor you replace

            int nIconBytes = (EVENBYTE(nWidth)/8)*nHeight;

            with

            int nIconBytes = (((nWidth+7)/8*8)/8)*nHeight;

            then you get the exact same result as with the #define. Note: I am certainly not suggesting that referring to non-argument variables from macros is a good idea (usually is is not), but understanding how macros differ from functions includes understanding how such references would work. Personal opinion: #define is among the most mis-used features of the C language. Except for giving symbolic names to simple constants, you should try to avoid it as far as possible.

            Greg UtasG Offline
            Greg UtasG Offline
            Greg Utas
            wrote on last edited by
            #5

            In C, #define is sometimes used to do the same thing as templates in C++, which I can understand. In C++, #define shouldn't be used that way, but C hackers use their preprocessor crapola in C++. It shouldn't even be used to define constants, especially after constexpr showed up.

            Robust Services Core | Software Techniques for Lemmings | Articles
            The fox knows many things, but the hedgehog knows one big thing.

            <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
            <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

            I 1 Reply Last reply
            0
            • Greg UtasG Greg Utas

              In C, #define is sometimes used to do the same thing as templates in C++, which I can understand. In C++, #define shouldn't be used that way, but C hackers use their preprocessor crapola in C++. It shouldn't even be used to define constants, especially after constexpr showed up.

              Robust Services Core | Software Techniques for Lemmings | Articles
              The fox knows many things, but the hedgehog knows one big thing.

              I Offline
              I Offline
              itcentral
              wrote on last edited by
              #6

              Great Thanks For Sharing

              1 Reply Last reply
              0
              • L Lost User

                coco243 wrote:

                Please help me understanding the following declaration

                Kinda looks like something used for calculating Image stride[^].

                C Offline
                C Offline
                coco243
                wrote on last edited by
                #7

                Thank you all for your responses.

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups