DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Page 1 of 2 12 LastLast
Results 1 to 15 of 18

Thread: #define replacing functions.

  1. #1
    Join Date
    Sep 2006
    Posts
    15

    #define replacing functions.

    I've recently started using #define statements to replace some simple functions, like
    Code:
    float cosd (float theta)
    {
        return cos (theta * M_PI/180.0f);
    }
    
    // equivelant to-
    
    #define cosd(x) cos(x*M_PI/180.0f);
    As far as I understand, using the #define version saves time and space as opposed to copying a variable to the function then to a return value. So I went ahead and changed some larger functions over to #define statements-

    Code:
    matrix MatrixTranslate (float x, float y, float z)
    {
        return matrix (1, 0, 0, 0,
                           0, 1, 0, 0,
                           0, 0, 1, 0,
                           x, y, z, 1);
    }
    
    // same as-
    
    #define MatrixTranslate(x,y,z) matrix(1,0,0,0,0,1,0,0,0,0,1,0,x,y,z,1)
    It all seems to work fine, but is there any catch to using #define statements? I haven't seen them used much, if at all, in other code where they could be used easily. I just wanted a little more confidence on the subject. Perhaps some feedback could do the trick...

    Also and unrelated, is there somewhere handy to post some 3D c++ stuff? I've got a few cool programs I'd like to show off... :D

  2. #2
    Join Date
    Jan 2005
    Location
    UK
    Posts
    604
    BAD MOVE!!!
    C++ gives you far better alternatives than using #defines. If I were you I'd completely forget about them before you get into a bad habit!
    just consider a #define like this:

    Code:
    #define calcSquare(x) ((x)*(x))
    void f()
    {
       int i=0;
       while(i<10)
          cout << calcSquare(i++) << endl;
    
    }
    the output probably won't be what you expect...
    #define's are preprocessor instructions to *TEXTUALLY REPLACE* strings in your source code with other strings. There is no typechecking involved so your functions
    might not even be doing what you want. And how are you going to debug?
    Forget about #defines or at least use them VERY sparingly. Use const variables and template functions instead.

    Cheers,

    Dieter
    DKyb
    -------------------------------
    Life is a short warm moment -
    Death is the long cold rest.
    Pink Floyd
    -------------------------------

  3. #3
    Join Date
    Nov 2003
    Posts
    4,118
    Once more: BAD MOVE! I don't know why you think macros save time and space; they do exactly the opposite. They bloat the exe file, they cause it to be slower and they also lead to various nasty bugs. Simply don't.

    I know that at this point I'm supposed to recommend inline functions as a superior alternative but here again, I say "don't!". Just leave the functions as-is. The compiler is smart enough to inline functions when it sees fit, and avoid inlining otherwise. Let the compiler do the right thing, and never ever use macros as functions.
    Danny Kalev

  4. #4
    Join Date
    Sep 2006
    Posts
    15
    Thanks. I hadn't considered an event like what you posted. Definently some bad consequences there. Not only is the result from the "function" unexpected (1*2, 3*4,... If I guess right) but the entire loop is thrown off whack (or it's expected whack anyway)...

    I guess it's just a matter of paying attention though, since some functions will behave the same way in function form or #define (unless I'm mistaken...). Like the MatrixTranslate function in the first post- whether you use MatrixTranslate (10*y-30*x, i++, z*33) with the #define or a normal function, you'd get the same result (since each part is existant only once after the text replacement).

    The cosd could even work if with an extra set of parenthesis around the x, like
    Code:
    #define cosd cos ((x)*M_PI/180)
    to prevent something like "cosd (x-y)" from encountering problems.


    I don't think I'll stop using them alltogether unless somebody suggests a better way to speed up simple functions, other than manually replacing the code. I won't use them as liberally as I've been though...

  5. #5
    Join Date
    May 2006
    Posts
    176
    Rephrasing the previous suggestions, I think if you believe that a macro version works faster then a function, you should make that function "inline" using a directive:

    Code:
    inline float cosd (float theta)
    {
        . . .
    }
    
    inline  matrix MatrixTranslate (float x, float y, float z)
    {
        . . .
    }
    Now the body of these functions should replace the calling expressions, obtaining the same effect as in case of macros, but in safer manner.

    Use macros only when inline functions cannot be used. (For example, the _T macro in Windows API cannot be replaced with a function).

    I hope this helps.

  6. #6
    Join Date
    Sep 2006
    Posts
    15
    *To Danny-

    I assumed that eliminating a function would save time for the variable to be copied to whatever the function's paramaters are, as well as save space since a new variable wouldn't have to be added to the stack while the function is called. (even though the space is reclaimed when the function is complete).

    The "cosd()" function for example-
    Code:
    float cosd (float theta)
    {
        return cos (theta*M_PI/180);
    }
    // Then to use the function-
    float x = cosd (45);
    
    // As apposed to -
    
    #define PI_180 0.01745329
    #define cosd(x) cos((x)*PI_180)
    float x = cosd (45);
    So, the first one copies 8 bytes onto the stack for the variable "theta" in the function, calculates the value, then sends back the result as another 8 bytes. The second replaces cosd (45) with cos ((45)*PI_180), leading to absolutely no extra memory use but the exact same result. Even more so, the MatrixTranslate function would need to copy 128 bytes! I'm not sure exactly how fast stuff's copied, but I don't see how using the #define version of the MatrixTranslate could be any slower than the normal version...

  7. #7
    Join Date
    Sep 2006
    Posts
    15
    I haven't used inline functions yet (been codin' in c++ for about 3 months) but I'm going to check them out. And it also seems like I'll be dropping the use of #define's, if not for the inherent problems but because of the bad rep the seem to have! :)

  8. #8
    Join Date
    Nov 2003
    Posts
    4,118
    You give your compiler too little credit... When you pass a variable to a function, the compiler may optimize the call by passing that variable on a register. This is the fastest you can get! As for the size optimization: when you replace a function with a macro, every time you "call" the macro, the code is expanded into the place of call, which means that the program contains many instances of duplicate code, and hence, the executable's size becomes larger. A large exe file is a bad thing because the OS can't load it all at once, nor can't it cache hot spots optimally. Trust me, modern compilers are so smart that they outsmart any optimization you can obtain by using macros, if any.
    Danny Kalev

  9. #9
    Join Date
    Dec 2003
    Posts
    3,366
    Macros are for C. Leave all but trivial macros (#include, include guards, maybe rename something incompatible, compiler switches) out of C++ unless you have very very good reason to do it.

    They are powerful in C -- you can use them like templates (the parameters are typeless in macros) and use them to force inline (c++ is a more complex language, and the compiler should know best what to inline most of the time).
    Last edited by jonnin; 09-05-2006 at 08:30 AM.

  10. #10
    Join Date
    May 2006
    Posts
    176
    Quote Originally Posted by Danny
    [...] modern compilers are so smart that they outsmart any optimization you can obtain by using macros, if any.
    (In my opinion the compilers cannot yet automatically inline any of simple function: it seems this cannot be done if a function was declared and compiled in a different source file, obtaining a separate OBJ or LIB file. I presume linkers cannot inline functions on linking phase.

    Therefore, explicit inlining in header files seems to be justified in certain circumstances.)

  11. #11
    Join Date
    Nov 2003
    Posts
    4,118
    inline is not confined to the compiler. linkers may (and do!) inline functions too, and even the loaders can do that at runtime. Besides, many compilers nowadays offer whole program optimization, whereby the compiler and linker access the entire program and optimize it, so inline is certainly possible even if a function is only declared and not defined in a certain translation unit. This is a fascinating topic on which I can't elaborate here, but as I said, you should give yoru compilers (or IDEs more precisely) more credit. They do amazing things.
    Danny Kalev

  12. #12
    Join Date
    May 2006
    Posts
    176
    Quote Originally Posted by Danny
    inline is not confined to the compiler. linkers may (and do!) inline functions too, and even the loaders can do that at runtime. Besides, many compilers nowadays offer whole program optimization, whereby the compiler and linker access the entire program and optimize it, so inline is certainly possible even if a function is only declared and not defined in a certain translation unit. This is a fascinating topic on which I can't elaborate here, but as I said, you should give yoru compilers (or IDEs more precisely) more credit. They do amazing things.
    I think I agree with this statement and I am wondering why the keywords for explicit inlining (like inline, __forceinline, noinline and so on) are still kept.

  13. #13
    Join Date
    Nov 2003
    Posts
    4,118
    They are kept for various reasons: sometimes, you want to force the compiler to inline a function even though it's not what the compiler considers the best option. For example, when you want that the dll shall not contain the function's name, or when the function is a poor candidate for inlining (it's long, it has loops, it declares static variables etc.) Noinine is required when you want to create an optimized app that can still be debugged safely, i.e., you can still step into every function. Without noinline the function might be inlined. Remember however that only inline is a standard keyword. __forceinline is a kludge, and today it's less and less used anyway.
    My advice: don't use any of these keywords. Let the compiler do its job. In most cases, it knows better than the average programmer what works best.
    Danny Kalev

  14. #14
    Join Date
    Dec 2003
    Posts
    3,366
    .Net help says it ignores "inline" -- if you want to override its internal decisions, you must use forceinline. No inline seems useless, as it does not inline in debug mode anyway.

    Why are loops considered bad for inline anyway? I could type a loop in that same location to do that same task. The point of inline is to avoid function call overhead when the function is invoked very often, and when the program has realtime requirements or performance requirements. If a significant amount of time is used just for the function call (time inline and function versions of the code) then it needs to be inlined (if the compiler failed to do so, you should over-rule it).

  15. #15
    Join Date
    Sep 2006
    Posts
    2
    Hi xenovacivus.

    My recommendation, let the compiler do its work. For present compilers, most applications will produce no time or speed related problems.

    Develop your code in the more simple and straight way possible and be sure that this straightforward impementation works properly.

    After this if you get any timiing or speed problem, try to solve it later using performance measurement tests.

Similar Threads

  1. Need Help for a hook subclass issue in Word
    By hcadieu in forum VB Classic
    Replies: 0
    Last Post: 02-14-2006, 01:39 AM
  2. VB/C Array parameters
    By Gastao Woelfert in forum VB Classic
    Replies: 2
    Last Post: 09-01-2000, 11:36 AM
  3. VB/C Array parameters
    By Gastao Woelfert in forum VB Classic
    Replies: 0
    Last Post: 09-01-2000, 08:59 AM
  4. resize a picture or image box
    By Rally in forum VB Classic
    Replies: 2
    Last Post: 06-30-2000, 01:10 PM
  5. Adding Columns to comboboxes through API
    By Lori Taylor in forum VB Classic
    Replies: 20
    Last Post: 06-14-2000, 11:06 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center