Why are C macros not type-safe?

后端 未结 7 1746
礼貌的吻别
礼貌的吻别 2021-02-18 16:01

If have encountered this claim multiple times and can\'t figure out what it is supposed to mean. Since the resulting code is compiled using a regular C compiler it will end up b

7条回答
  •  闹比i
    闹比i (楼主)
    2021-02-18 16:31

    Since macros are handled by the preprocessor, and the preprocessor doesn't understand types, it will happily accept variables that are of the wrong type.

    This is usually only a concern for function-like macros, and any type errors will often be caught by the compiler even if the preprocessor doesn't, but this isn't guaranteed.

    An example

    In the Windows API, if you wanted to show a balloon tip on an edit control, you'd use Edit_ShowBalloonTip. Edit_ShowBalloonTip is defined as taking two parameters: the handle to the edit control and a pointer to an EDITBALLOONTIP structure. However, Edit_ShowBalloonTip(hwnd, peditballoontip); is actually a macro that evaluates to

    SendMessage(hwnd, EM_SHOWBALLOONTIP, 0, (LPARAM)(peditballoontip));
    

    Since configuring controls is generally done by sending messages to them, Edit_ShowBalloonTip has to do a typecast in its implementation, but since it's a macro rather than an inline function, it can't do any type checking in its peditballoontip parameter.

    A digression

    Interestingly enough, sometimes C++ inline functions are a bit too type-safe. Consider the standard C MAX macro

    #define MAX(a, b) ((a) > (b) ? (a) : (b))
    

    and its C++ inline version

    template
    inline T max(T a, T b) { return a > b ? a : b; }
    

    MAX(1, 2u) will work as expected, but max(1, 2u) will not. (Since 1 and 2u are different types, max can't be instantiated on both of them.)

    This isn't really an argument for using macros in most cases (they're still evil), but it's an interesting result of C and C++'s type safety.

提交回复
热议问题