Preproccessor ignore - c++

I am migrating from Visual Studio 6 to Visual Studio 2008 and I have a function of a component I am using named SetDefaultPrinter.
Unfortunately there is a windows library function now, SetDefaultPrinter, with the same name. And the macro associated with it is getting in the way of me using my function.
This is my workaround I have to call my function:
#undef SetDefaultPrinter
pNova->SetDefaultPrinter();
#ifdef UNICODE
#define SetDefaultPrinter SetDefaultPrinterW
#else
#define SetDefaultPrinter SetDefaultPrinterA
#endif // !UNICODE
Is there a less ugly way around this? And no, I do not have control over that external component to change the name of the function.

This is why C++ added namespaces; too bad the Windows definitions can't use them.
In another source module, where you do NOT include windows.h or any other Windows include files, generate a stub function to call your clashing function.
void MySetDefaultPrinter(CNova * pNova)
{
pNova->SetDefaultPrinter();
}

You could use a wrapper around the external component. This is sometimes called the "Adapter" pattern.
// header file
class NovaWrapper
{
Nova *_nova;
public:
void setDefaultPrinter();
};
// implementation file - this file does not include windows.h - you need to make sure it
// does not have visibility of the "bad" SetDefaultPrinter macro
void NovaWrapper::setDefaultPrinter()
{
_nova->SetDefaultPrinter();
}
Now, modify your client code to use NovaWrapper instead of the underlying instance.

This was, in the end, fixed by simply swapping the order of includes. Apparently, the developers of this component realized the problem before me, so they included SetDefaultPrinterA and SetDefaultPrinterW in the component that are just aliases for SetDefaultPrinter. So that if windows.h renames the function, it's not a problem.

Related

What does adding a pre-processor variable before a function declaration means?

I'm reading the Dear ImGui API, and i'm wondering what does it mean to add a pre-processor variable (here IMGUI_API) before the function declaration like this :
#ifndef IMGUI_API
#define IMGUI_API
#endif
...
namespace ImGui
{
...
IMGUI_API float GetWindowWidth();
...
};
Thanks in advance !
Like Hans Passant said - it won't always be empty.
One of the main properties of dynamic shared objects (and DLLs in Windows) is that the internal symbols of the library are not exposed to the user. In GCC, this is done by specifying the default symbol visibility to "hidden" on the command line when building the library. However, this has the undesirable effect of making all symbols, including the ones you want users to call, hidden, which makes your library effectively useless.
GCC provides a way to manually control visibility - __attribute__((visibility("default"))). This marks a function as having default visibility, meaning it will be exposed by the DSO. This attribute is specified before the function declaration.
This creates a new problem - the users of your library don't need/want this attribute specified on your library functions when they include your header file. When your header is included by the user, these definitions should be removed, leaving just a bare function declaration.
There's two ways to solve this - have two copies of your header, or use the preprocessor to change the code before compilation. Most (almost all) library programmers choose the latter, as keeping two copies of the same file synced is very difficult.
The way the writers of ImGui have implemented the latter option is rather elegant - rather than defining their API marker inline, like so:
#ifdef IMGUI_API_BUILD
#define IMGUI_API __attribute__((visibility("default")))
#else
#define IMGUI_API
#endif
They've defined it as follows:
#ifndef IMGUI_API
#define IMGUI_API
#endif
This has the effect of defining the symbol to a default value if it hasn't been overridden.
The genius of this is actually in the compilation process - by specifying the definition of IMGUI_API on the command line, they can change the behavior of the code without exposing elements of their build process to the world.
All they have to do is add -D IMGUI_API=__attribute((visibility("default"))) to the compiler command line and the header file magically marks every API function as being exported from the shared object.
In fact, they can change the definition to any value they want without exposing that detail in the header file used by other programmers in this way. Debug information, additional function options, specifying hot/cold path info... all of this can be specified on the command line without needing to place that information into the header file.
Edit:
Looking through their code now, it seems they haven't realized this, and have created a very powerful shared-library solution for Linux without meaning to. Despite that, all of the above is still valid - other libraries can do the same thing.

MS Visual Studio 2010 C++ Preprocessor - If function is defined in macro with calls elsewhere, is there any overhead hit when undefined

I have a quick question, which I am sure has been asked so I do apologize if it is a duplicate. I tried searching google and stackoverflow but the results were unrelated to my question.
The scenario:
I have a Visual Studio 2010 project configuration that defines a preprocessor named DBG.
In the code, I have a #ifdef DBG section that declares a function signature in the header file (let's call it writeToFile) and defines that function within another #ifdef DBG/#endif section in the cpp file.
Throughout the rest of the project are calls to writeToFile.
The questions:
When the project is compiled under a different configuration (one that doesn't define DBG), how is this handled by the compiler? I know that the portions within the #ifdef/endif directives are pretty much ignored, but what happens to all the function calls to writeToFile? Does the compiler ignore these, too? Or during run time, do these calls actually occur and do nothing?
Thanks in advance
I suspect that the compiler should throw an error (undefined function writeToFile()). But you should be able to battle this by specifying #else section that defines the same function with an empty body. ie.
#ifdef DBG
void fun() { cout << "hello"; }
#else
void fun() { };
#endif //DBG
EDIT:
I personally would just define the function you want, and put the #ifdef/#endif block inside it's body.

C++ defined ?macro? visible in header yet missing in implementation (linker reports unresolved external)

I have some class for specific debug purposes, so I use it only when interested in given functionality
to prevent source rubbish when not needed, I tried to handle it by preprocessor,
so the structure is something like this:
===main.cpp===
#define nowUseTmp
#include "tmp.h"
/*normal code which accesses tmp via macros*/
===EOF===
===tmp.h===
#ifdef nowUseTmp
/* class declaration */
/* macros to use static methods on class*/
#else
/*empty macro variants, so they may freely stay in code where needed*/
#endif
===EOF===
===tmp.cpp===
/*EXPECTED PLACE OF PROBLEM*/
#ifdef nowUseTmp
/* definitions */
#endif
===EOF===
problem is, that when I enable nowUseTmp (before the_very_first/each include), linker reports unresolved external (like if the macro was defined in header and NOT defined in the cpp file)
Question:
Why / How / What is better approach
I expect that cpp files are translated individually, without knowledge of include chain (thus cannot have info about the define)
Is that the case?
If so, how to workaround, so I can have constant "tmp.*" files between multiple projects, and manage enabled/disabled individually per project (i.e. not to use define inside relevant header)
Just to clarify
->when I place "#define tmpUseNow" inside relevant header (tmp.h), all works fine
->relevant header (tmp.h) is included from relevant definition file (tmp.cpp)
->same behavior tested with simplified project with only three files as in example
-> relevant files (tmp.h, tmp.cpp) are assumed constant files shared between many projects (so I do not see how to order them to include predetermined third file with definitions, which would be individual for projects that use them)
Yes, each cpp file is processed independently. If I were you, I'd make sure to include tmp.h in tmp.cpp, and I'd only ever define nowUseTmp in tmp.h.
You can add to your tmp.cpp functions (name it use_tmp) additional parameter with default value = nowUseTmp and examine it value for particular behavior:
tmp.h :
/* takes par2 value from the define */
void use_tmp(int par1, int par2 = nowUseTmp);
tmp.cpp :
void use_tmp(int par1, int par2)
{
if(!par2) /*do smth*/ return;
}

How do I avoid name collision with macros defined in Windows header files?

I have some C++ code that includes a method called CreateDirectory(). Previously the code only used STL and Boost, but I recently had to include <windows.h> so I could look-up CSIDL_LOCAL_APPDATA.
Now, this code:
filesystem.CreateDirectory(p->Pathname()); // Actually create it...
No longer compiles:
error C2039: 'CreateDirectoryA' : is not a member of ...
Which corresponds to this macro in winbase.h:
#ifdef UNICODE
#define CreateDirectory CreateDirectoryW
#else
#define CreateDirectory CreateDirectoryA
#endif // !UNICODE
The pre-processor is redefining my method call. Is there any possible way to avoid this naming collision? Or do I have to rename my CreateDirectory() method?
You will be better off if you just rename your CreateDirectory method. If you need to use windows APIs, fighting with Windows.h is a losing battle.
Incidently, if you were consistent in including windows.h, this will still be compiling. (although you might have problems in other places).
You could create a module whose sole purpose is to #include <windows.h> and look up CSIDL_LOCAL_APPDATA wrapped in a function.
int get_CSIDL_LOCAL_APPDATA(void)
{
return CSIDL_LOCAL_APPDATA;
}
btw, Well done for working out what happened!
#undef CreateDirectory
As a developer working on a cross platform codebase, this is a problem. The only way to deal with it is to
ensure that windows.h is - on Windows builds at least - universally included. Then the CreateDirectory macro is defined in every one of your compilation units and is universally substituted with CreateDirectoryW. Precompiled headers are ideal for this
OR, if that is an unpleasant proposition, (and it is for me)
isolate windows.h usage into windows specific utility files. Create files that export the basic required functionality. The header files must use data types that are compatible with, but do NOT depend on the inclusion of windows.h. The cpp implementation file must (obviously) use windows.h.
If your utlility functions need to include project header files with conflicting symbols then the following pattern is a necessity:
#include <windows.h>
#ifdef CreateDirectory
#undef CreateDirectory
#endif
// etc
#include "some_class_with_CreateDirectory_method.h"
// ...
You will need to then explicitly call the non macro version of any windows api functions you have #undef'd - CreateDirectoryA or W etc.
push macro, undef it and pop the macro again:
#pragma push_macro("CreateDirectory")
#undef CreateDirectory
void MyClass::CreateDirectory()
{
// ...
}
#pragma pop_macro("CreateDirectory")
You can take a back up of CreateDirectory, then undefine it, and then define it again when you finish your job with you custom one.
#ifdef CreateDirectory
#define CreateDirectory_Backup CreateDirectory
#undef CreateDirectory
#endif
// ...
// Define and use your own CreateDirectory() here.
// ...
#ifdef CreateDirectory_Backup
#define CreateDirectory CreateDirectory_Backup
#undef CreateDirectory_Backup
#endif
Note that name conflict usually comes from a certain header file being included. Until then stuff like CreateDirectory and GetMessage isn't pulled into visibility and code compiles without a problem.
You can isolate such an inclusion into a wrapper header file and "#undef whatever" at its end. Then, whatever name collision you have will be gone. Unless, of course, you need to use those macros in your own code (yeah, so very likely...)
#pragma push_macro("CreateDirectory")
If nothing works, instead of renaming you could use your own namespace for your functions.

Conflict with DrawText function

I am developing a multi-platform application and in one component I have a class method called DrawText. Unfortunately, I get a linker error (on windows only) saying that there is an unresolved external symbol for a DrawTextW method of this class.
I've seen this before with other methods ending in "Text" where it is looking for either a FooTextW or FooTextA method instead of the FooText method I defined. My assumption is that somewhere in the Windows headers there is a macro definition assigning FooText to FooTextW or FooTextA based on some other definition.
Aside from renaming my function (which is what I did in the past), does anybody have any good ideas for getting around this issue?
Thanks.
Joe
You really only have two choices:
#ifdef DrawText
#undef DrawText
#endif
Or rename your function. Win32 uses macros which have no namespacing or scoping, so you're kinda stuck.
We just re-name our functions.
BTW: It's based on #ifdef UNICODE usually (or _UNICODE or a few other variants).
Yes, this is a real problem with using Windows, and there's no way to turn it off since the headers all look like this:
#ifdef UNICODE
#define GetDlgItemText GetDlgItemTextW
#else
#define GetDlgItemText GetDlgItemTextA
#endif
So you're going to get the symbol defined either way. It would be very nice if you could #define something before #include'ing windows.h that turns this behavior off, but alas none exists.