I have a class that has a member function called SendMessage. No member function named SendMessageA exists in the project.
Project is multibite, so I have a define
#define SendMessage SendMessageA
If I call SendMessage somewhere in that class, will my project call SendMessage or SendMessageA ?
If the replace is made by preprocessor,the project should not compile. Right ?
But I see in a dump that SendMessageA is called … end eip register is not in any VAD
EDIT
A more specific question: is preprocessor blindly replace the defines ? or first checks for a match in the class ?
In case of
#define A Bpreprocessor replaces ALL occurences ofAwithB. It is pure substitution.Your project will call either
SendMessageAorSendMessageW– depending on whether it was compiled with unicode support or not. There’s noSendMessagefunction – it doesn’t exist.SendMessageA is declared within
<widnows.h>(or in a header that is included from windows.h) – somewhere, and its linking info is within one of base system libraries (User32.lib, I think). If you’re on windows, there’s a very good chance<windows.h>is#includedfrom somewhere, and corresponding *.lib is already in linker dependencies.–EDIT–
Yes, preprocessor blindly replaces defines. For non-blind replacement you have templates, but they have their own limitations. Some thing that can be done with preprocessor cannot be done with templates and vice versa. Preprocessor have stringize operator, templates have type-checking and metaprogramming.
If you have
SendMessagemethod in your code (BAD idea on windows platform – clashes with system macro, replace withsendMessage()or use different name, because even namespaces won’t help you to avoid omnipresent preprocessor) your method (notSendMessageA/SendMessageW) will be called from *.cpp ONLY if<windows.h>was not included in that *.cpp.Compiler operates at one file at a time, and has no knowledge of thing that go on in other files, so if there’s no
<windows.h>#included, your method will be called, because preprocessor won’t have any knowledge aboutSendMessage#define(from<windows.h>). If<windows.h>is included, then ALL occurences ofSendMessagewill be replaced withSendMessageA/SendMessageW, because preprocessor does its job first.One possible solution in your situation would be to avoid using naming convention similar to the one in Win API. I.e. make sure that function names don’t start with capital letter. That’ll solve many problems, but you’ll still get minor trouble from
min/maxmacros.