Thread: macros???

  1. #1
    Registered User I C everything's Avatar
    Join Date
    Apr 2019
    Posts
    101

    Question macros???

    Hi
    I want to use macros as tool to shorten typing
    for example almost similar calls,for example sendmessage,to be exchanged for example sendm with only the variables thats changing to be inside sendm(wchar) instead of whole sendmessage(hwnd,WM_SETTEXT,wcharlength,wchar)
    or I need to use some inlined function todo this?
    you tell me you can C,why dont you C your own bugs?

  2. #2
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,106
    Yes, you could use a simple #define macro, but debugging the code and maintaining it later, especially by a different programmer would be a nightmare! Not recommended!

    Copy & Paste would be a better solution, or an editor macro, but not a #define macro.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    I'd suggest you get an auto-completion editor to save the typing.

    Code is read 100s or 1000s of times more often than it is written.
    Riddling it with cryptic abbreviations only you understand at the moment you wrote it won't do anyone any good.
    Question 10.2

    Even you will forget what the original intent was.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Apr 2021
    Posts
    138
    If you are going to do this, you have a couple of choices.

    First, would be a preprocessor macro. Something like:

    Code:
    #define sendmsg(wc)  sendmsg(hwnd, WM_SETTEXT, wcharlength, wc)
    The other possibility would be a static inline function. This technically is a function in C, but it will behave as a really good macro:

    Code:
    static inline void sendmsg(HWND hwnd, size_t wclen, wchar_t wc) { sendmsg(hwnd, WM_SETTEXT, wclen, wc); }
    The problem is obvious: the macro will allow you to implement a "naming convention" as though it were part of the language, using the variable names that you will just always use (hwnd, wcharlength). The static inline function, on the other hand, is still a C function - if you don't pass something in as a parameter, it has to be accessed as a global variable, or you can't use it.

    Another alternative might be to put the call to get the length into the function/macro, which eliminates the need for the wcharlength parameter. You're still left with hwnd and wchar, but that might be good enough? It's your call.

    Some people have posted reasonable-sounding objections. I'm not convinced by them, but I do agree that you need to be aware of, and willing to spend a lot of time taking care of, the needs of the maintenance programmer who will have to work with this code 6-12 months from now. (Especially because there's a good chance that poor dumb schmuck is going to be YOU.) You don't want someone, especially "future you," sitting at their desk screaming "Curse you, I C Everything! Damn you for all eternity! To the last, I grapple with thee; From Hell's heart, I stab at thee; For hate's sake, I spit my last breath at thee!"

    To this end, I recommend that you define your macros in an easily-findable place. I have used three approaches:

    1. When I am using a macro in a single place, like a single function, I just #define and #undef them at the top/bottom of the function. This lets the definitions be seen quickly, and also makes it clear that they are used noplace else. This is what I do for one-off macros to initialize structures, for example: #define macro, 55 invocations of macro in an array initializer, #undef macro.

    2. When I am using a macro like your sendmsg in many places within a file, put the macro definitions at the top of the file. If you're only using the macros in one file, don't put the #define's in a header, put them directly in the file. Again, this makes them easy to find, and also tells the maintainer that they're local to the file. (If they're used throughout the file, don't bother #undef'ing them.)

    3. If I am going to use a macro across multiple files, it has to be a really good, really generic, really useful macro. My first inclination is to make any such macro into a function. If it can't be a function, then it has to be both clean and generic. You should have very few of these, mainly because there are so few really clean, really generic, really useful macros that are also impossible to convert to a function. These macros go into a header. For me, they usually go into my private utility library header(s).

  5. #5
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    For what aghast means in the 3rd approach I believe the below extract from my own code is a relatively good example:

    Code:
    typedef enum _IMAGE_CHANNELS
    {
    	IMAGE_CHANNEL_R = 0,
    	IMAGE_CHANNEL_G,
    	IMAGE_CHANNEL_B,
    	IMAGE_CHANNEL_A,
    	IMAGE_CHANNEL_COUNT
    } IMAGE_CHANNELS;
    
    #define ImageRows(IMAGE) ((IMAGE)->Rows)
    #define ImageCols(IMAGE) ((IMAGE)->Cols)
    #define ImagePfxRows 1
    #define ImagePfxCols 1
    #define ImageColX(IMAGE,COL) ((COL) + ImagePfxCols)
    #define ImageRowX(IMAGE,ROW) ((ROW) + ImagePfxRows)
    
    #define ImageColOffset( IMAGE, COL ) \
    	(ImageColX(IMAGE,COL) * IMAGE_CHANNEL_COUNT)
    
    #define ImageRowOffset( IMAGE, ROW ) \
    	(ImageRowX(IMAGE,ROW) * ImageColOffset(IMAGE,ImageCols(IMAGE)))
    
    #define ImagePixelX( IMAGE, ROW, COL ) \
    	(ImageRowOffset(IMAGE,ROW) + ImageColOffset(IMAGE,COL))
    /* Adds any offset/s for local pixel indices, index 0 is used for nil, do NOT
     * fill that index */
    
    #define ImagePixelA(IMAGE, ROW, COL ) \
    	(ImagePixelX(IMAGE,ROW,COL) - IMAGE_CHANNEL_COUNT)
    
    #define ImagePixelB(IMAGE, ROW, COL ) \
    	(ImagePixelX(IMAGE,ROW,COL) - ImageColOffset(IMAGE,ImageCols(IMAGE)))
    
    #define ImagePixelC(IMAGE, ROW, COL ) \
    	(ImagePixelB(IMAGE,ROW,COL) - IMAGE_CHANNEL_COUNT)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Macros...
    By koudis in forum C Programming
    Replies: 1
    Last Post: 09-22-2015, 03:35 PM
  2. C macros
    By rendezed in forum C Programming
    Replies: 4
    Last Post: 01-26-2011, 08:36 AM
  3. Macros inside of macros
    By Chewie8 in forum C Programming
    Replies: 2
    Last Post: 02-24-2008, 03:51 AM
  4. Macros
    By silentkarma in forum C++ Programming
    Replies: 2
    Last Post: 09-16-2006, 01:26 PM
  5. macros
    By Chaplin27 in forum C++ Programming
    Replies: 7
    Last Post: 03-02-2005, 01:06 PM

Tags for this Thread