How to suppress #define locally? - c++

Just caught a silly bug. I have a zip processing library with a CreateFile() function in it. Winbase.h, included somewhere deep in my headers, redefines it as CreateFileW and linker goes nuts.
Of course I will exclude winbase in this particular case. It just shouldn't be in the scope in the first place. But the theoretical question is still interesting,
Is there a way to suppress some defines locally?

You can get around the macro by putting parentheses around the name:
(CreateFile)(arguments);
This works because the macro CreateFile is a function-like macro (i.e. it takes a list of arguments in parentheses); the right parenthesis after the name doesn't match the syntax for using a function-like macro, so the preprocessor does not expand it.
Of course, the "right" solution is to name the function properly, i.e., create_file. <g>

Removing the offending header file is ALWAYS the best solution for this (especially one as large as windows.h or winbase.h - they are included far too freely for my taste in many projects).
The only other solution is #undef offending_symbol.
Of course, another important thing is "do not use names that match the Windows/Linux system call names" - but CreateFile is a very obvious name for a function that creates a file, so I can see the temptation.

Preprocessor macros have no notion of C++ scope. #defines are just text replacements. If you want to have a 'local' #define, you do something like this:
#define CreateFileW CreateFile
... // here I can use the macro
#undef CreateFileW
Or in your case
#undef CreateFileW
... // Here the macro is not available
#define CreateFileW CreateFile

There is
#undef
which removes defines (but nothing else).

Apart from the aforementioned #undef there technically is not much you can do against #defines, at least not portably.
The best way is to not use #define at all, or at least as little as possible and as constrained as possible. Sometimes you just need a macro to generate some boilerplate code a few times. Be sure to #undef that macro once you are done. The only other valid applications of #define I can think of are include guards and flags for conditional preprocessing.
For #define-deseases like the WinAPI headers you just should constrain them as much as possible. Don't use the #defined types of that API in your headers. You almost never want to use an API all over your application, so use it only in the cpps of a small layer around the API. Reducing the dependencies that way gives a lot more than just disinfecting the rest of your code.

Related

Using C Functions in preprocessor statements

I'm programming a c++ application on an stm32f4 chip which has several IOs to control. One of my colleagues suggested to make preprocessor statements to all of these IOs to make the code more readable.
For example:
#define FAN_ON GPIO_SetBits(GPIOD, GPIO_Pin_0);
#define FAN_OFF GPIO_ResetBits(GPIOD, GPIO_Pin_0);
Is this ok this way, and if not, why?
I have not that much microcontroller experience yet, but I read that semicolons shouldn't be used in preprocessor statements and I'm also not sure if it is a good style to use functions in precompiler statements?
Thank you for your help!
It's fine in theory, but you're right in that the semicolons should be avoided.
It's best to wrap the code in a dummy loop:
#define FAN_ON do { GPIO_SetBits(GPIOD, GPIO_Pin_0); } while(false)
This makes the macro behave like a single statement.
To answer your first question, even though this is common, it is pretty bad style to use preprocessor statements to define functions, except when you really need the preprocessor. You really need the preprocessor when you need things like __LINE__, or preprocessor substitutions tricks like put the function name in a char * variable. You could define a function void fan_on(void) and void fan_off(void) instead of those macros, you can even declare them static inline if you want to declare them in a header like you would do with macros. Functions can be better used by the debugger than macros, and better debugged.
As you said if you still want to use macros you should not use semicolons, and use a do while(0) structure, if you don't using the macro if a single-line if block will only execute the first line of the macro.

Avoid macro to be usable from client code

I'm currently working on a header only library and I'd like to be able to use some macros without them being usable from client code. Example:
// library_header1.h
#define MACRO_NUMBER_1(__X__) doSomethingWith(__X__) // etc...
class LibraryClass1
{
// We'll use the macro somewhere in here.
};
Now, if I include library_header1.h i'm able to use MACRO_NUMBER_1. Is there any way I can avoid that?
Others already mentioned #undef but what if you have many macros you need to undefine and you need to use them in many headers? This situation can be dealt with by having a header define and undefine macros and bewteen that include a specified header. For example:
// temp-macros.h
#if defined(OUTER)
# define MACRO x
# include OUTER
# undef MACRO
# undef OUTER
#endif
The idea is to set up OUTER from the header where the macros are neede, include temp-macros.h and use the macros in the second inclusion:
// macro-use.h
#if !defined(OUTER)
# define OUTER "macro-use.h"
# include "temp-macros.h"
#elif !defined(INCLUDED_MACRO_USE)
# define INCLUDED_MACRO_USE
void use(int MACRO) { /*...*/ }
#endif
Of course, this example uses just one trivial macro but if there are more macros and they are more complicated this approach could be useful.
To prevent the library user from accessing the macro - you can put #undef when you know you won't need your macro anymore.
If you want to prevent intellisense/autocompletion from ever seeing your macro, you may try to trick it by skipping it over the macro definition. Usually you can do it as follows:
set up your compilation project (visual solution, makefile, ...) so that you pass an extra "identification" macro. Something like -DIAMCOMPILING
Guard your macro definition with #ifdef IAMCOMPILING ... #endif
your IDE will most likely not recognise IAMCOMPILING and skip over the definition of your macro.
Do note however, that then IDE will get confused when your actually use the macro in the header file and some nonexistent errors will be flagged.
Whilst it won't stop the macro from being noticed by the IDE, if you use a unusual prefix to the macro, it will be less likely to collide with something that the user will want to do, and thus be less offensive. It may not be the ideal solution, but prefixing the macro with CCC or XWX or something else that is unlikely to be used by the normal programmer may help.
(Or, don't use macros is always a solution that works!)

Using the function of a specific library

I have a problem: I would like to use the function abs of the library complex.
However, I undergo an error warning me the function abs used is #define abs(x) (x > 0) ? x : -(x).
Thus, I think the problem comes from my imports. Because of I also include the stdio and stdlib libraries, the compiler may use the function abs defined in one of these libraries.
So my question is: how can I use the function abs of the library complex without removing any import ?
Thanks a lot in advance for your response.
Wrap parens around it.
(abs)(whatever);
This will force the compiler to use the function version because the macro no longer matches.
Function-like macros work by matching an identifier followed by a left paren (. Since we've wrapped the function name itself in parens, we have instead an identifier followed by a right paren ), which fails to match the macro. The parens are semantically transparent, but they inhibit the macro syntax.
IIRC, it was splint the C checker which taught this to me. While writing a postscript interpreter, I created nice short macros to access the stack.
#define push(o) (*tos++ = (o))
#define pop() (*--tos)
Which were great until the tricky parts where they were part of an expression involving tos. To avoid undefined behavior, I had to create function versions and use those for those tricky spots. For the new design, I skipped the macros altogether.
Edit: I've got a nagging feeling that it was actually the Coelocanthe book (Peter Van Der Linden's Deep C Secrets) where I learned this, the above situation being where I first needed it. IIRC his example involved putchar or getchar which are often implemented as both functions and macros in conforming C implementations.
Use #undef
#include "header1.h"
#include "header2.h"
#undef abs // remove abs macro
x = std::abs(y);
Whilst several suggestions above are very good, I would take a completely different angle. It is almost certainly something like windows.h that causes the "bad" macro definition of abs(). You should be able to NOT include "windows.h" in the file that does the complex math [in most types of programs, at least] (I'm not aware of a single function in Windows that takes complex<T> as an argument, so I'm pretty certain you don't need both "complex.h" and "windows.h" in the same source file. This method is called "isolating the system dependencies", and doing that is a very good thing.
Have a look at your code, and find where you are ACTUALLY using windows functions, and then only include "windows.h" in the files that actually need it. You'll probably find, if you are using Visual Studio, that "windows.h" is included as part of "stdafx.h", which means that all sort of interesting macros etc are being included all over the place, because "stdafx.h" is included in ALL source files.
Both #undef and parentheses solutions will work but I would advise to have something a little stronger, because both those solutions will required you to do them every time you want to call abs and next time you may forget and result in a bug.
what you can do:
change the name of your function to less common name : absolute, myAbs etc...
put you function\class under a name space (for C++ not for C) then the calls are explicit myNameSpace::abs(x)
If it won't work as the comment here suggested I would still warp the call in my function:
type myAbs(type param)
{
return (abs)(param);
}

Is preprocessor blindly replace the defines?

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 ?
The Preprocessor runs through your code before compilation.
So any SendMessage would be converted into a SendMessageA. The compiler will then look for a function called SendMessageA and call it.
How C++ preprocessor works
In case of #define A B preprocessor replaces ALL occurences of A with B. It is pure substitution.
Will my project call SendMessage or SendMessageA ?
Your project will call either SendMessageA or SendMessageW - depending on whether it was compiled with unicode support or not. There's no SendMessage function - it doesn't exist.
f the replace is made the project should not compile.
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 #included from somewhere, and corresponding *.lib is already in linker dependencies.
--EDIT--
A more specific question: is preprocessor blindly replace the defines ?
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.
My problem is why sometimes the member function SendMessage is called because the code works (most of the time)
If you have SendMessage method in your code (BAD idea on windows platform - clashes with system macro, replace with sendMessage() or use different name, because even namespaces won't help you to avoid omnipresent preprocessor) your method (not SendMessageA/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 about SendMessage #define (from <windows.h>). If <windows.h> is included, then ALL occurences of SendMessage will be replaced with SendMessageA/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/max macros.
The preprocessor works as a text macro processor. If a macro is defined, all occurrences of the macro are replaced with it's definition.
#define blabla some_real_stuff
struct blabla /* blabla will be replaced with some_real_stuff */
{
void method();
};
int main()
{
some_real_stuff x;
x.method();
}
In the Windows API, there are the two functions SendMessageA and SendMessageW. You will be calling one of these two, depending on what #defines you have in your program.
Are you sure that is not what happens?
Edit: oh wait. Is your #define SendMessage SendMessageA before the definition of the SendMessage member function in your source? If so, the compiler will simply use SendMessageA for the name of the member. Otherwise, your function will be SendMessage, but the rest of your program will call the built in Windows function SendMessageA.
If you have many source files, maybe some of them will know about the #define, while others won't.
My recommendation is to rename the member function to something else and dispense with the #define.

Can I redefine a C++ macro then define it back?

I am using both the JUCE Library and a number of Boost headers in my code. Juce defines "T" as a macro (groan), and Boost often uses "T" in it's template definitions. The result is that if you somehow include the JUCE headers before the Boost headers the preprocessor expands the JUCE macro in the Boost code, and then the compiler gets hopelessly lost.
Keeping my includes in the right order isn't hard most of the time, but it can get tricky when you have a JUCE class that includes some other classes and somewhere up the chain one file includes Boost, and if any of the files before it needed a JUCE include you're in trouble.
My initial hope at fixing this was to
#undef T
before any includes for Boost. But the problem is, if I don't re-define it, then other code gets confused that "T" is not declared.
I then thought that maybe I could do some circular #define trickery like so:
// some includes up here
#define ___T___ T
#undef T
// include boost headers here
#define T ___T___
#undef ___T___
Ugly, but I thought it may work.
Sadly no. I get errors in places using "T" as a macro that
'___T___' was not declared in this scope.
Is there a way to make these two libraries work reliably together?
As greyfade pointed out, your ___T___ trick doesn't work because the preprocessor is a pretty simple creature. An alternative approach is to use pragma directives:
// juice includes here
#pragma push_macro("T")
#undef T
// include boost headers here
#pragma pop_macro("T")
That should work in MSVC++ and GCC has added support for pop_macro and push_macro for compatibility with it. Technically it is implementation-dependent though, but I don't think there's a standard way of temporarily suppressing the definition.
Can you wrap the offending library in another include and trap the #define T inside?
eg:
JUICE_wrapper.h:
#include "juice.h"
#undef T
main.cpp:
#include "JUICE_wrapper.h"
#include "boost.h"
rest of code....
I then thought that maybe I could do some circular #define trickery like so:
The C Preprocessor doesn't work this way. Preprocessor symbols aren't defined in the same sense that a symbol is given meaning when, e.g., you define a function.
It might help to think of the preprocessor as a text-replace engine. When a symbol is defined, it's treated as a straight-up text-replace until the end of the file or until it's undefined. Its value is not stored anywhere, and so, can't be copied. Therefore, the only way to restore the definition of T after you've #undefed it is to completely reproduce its value in a new #define later in your code.
The best you can do is to simply not use Boost or petition the developers of JUCE to not use T as a macro. (Or, worst case, fix it yourself by changing the name of the macro.)