I tried to use a library on visual studio in different ways by modify its macros on preprocessor directives. However a logic block inside an #if directive is shown to me inactive as it was comment. Here is the code:
#if defined EBML_DLL
#if defined EBML_DLL_EXPORT
#define EBML_DLL_API __declspec(dllexport)
#else // EBML_DLL_EXPORT
#define EBML_DLL_API __declspec(dllimport)
#endif // EBML_DLL_EXPORT
#else // EBML_DLL
#define EBML_DLL_API
#endif // EBML_DLL
The problems is that visual studio shows the code within if ebml_dll block inactive (as commented). As result, the dll doesn't show the functions in the object browser of VS.
A Hint: if a backslash is added at the end of #if defined EBML_DLL's line, it active the else block only.
There was a bug in older versions of VS about this, but it was just a display issue. VS was not reading the defines correctly (in your case EBML_DLL, etc).
It could also be that the constants you are using in your preprocessor statements are not correct and the are missing characters (usually the ones the compiler uses have underscores at the beginning and end)
To really know for sure which one it is, you can add a random string inside the branch the preprocessor is expected to take and see if the code compiles.
#if defined EBML_DLL
this_should_not_compile //you should get an error on this line
#endif
Hope this helps...
Related
I have two header files. One calls the other after #define-ing a symbol used in the other one with #ifdef [symbol]... lotsa code #endif.
In VS2017, the code between the #ifdef & #endif shows as 'active' (not greyed out), so it thinks [symbol] is true and includes the code in the active code set.
However, If I comment out the #ifdef [symbol] and #endif lines, the result of the compile changes drastically - how can this be? I thought the #ifdef & #endif macros were pre-processor directives and don't exist at all for purposes of compiling the code. If #ifdef [symbol] evaluates as true, I thought they just disappeared. What am I missing?
First header file:
#ifndef _MPU6050_6AXIS_MOTIONAPPS20_H_
#define _MPU6050_6AXIS_MOTIONAPPS20_H_
#include "I2Cdev.h"
#include "helper_3dmath.h"
// MotionApps 2.0 DMP implementation, built using the MPU-6050EVB evaluation board
#define MPU6050_INCLUDE_DMP_MOTIONAPPS20
#include "MPU6050.h"
In the second header file (MPU6050.H), there is a long class definition for 'Class MPU6050' and this definition has a block guarded by
#ifdef MPU6050_INCLUDE_DMP_MOTIONAPPS20
....
....
....
#endif
This (I believe) is the source of some 'one definition rule' violations I've been trying to track down, so as an experiment I commented out the #define & #endif lines, thinking now there would be only one possible definition for 'Class MPU6050' and life would be good. What actually happened is the compiler blew a whole lot of 'undefined symbol' errors, as if the 'MPU6050_INCLUDE_DMP_MOTIONAPPS20' symbol hadn't been defined after all and the guard lines were preventing the guarded code from being compiled, even though VS2017's Intellisense shows it 'active'.
Since the symbol 'MPU6050_INCLUDE_DMP_MOTIONAPPS20' is defined, the guarded code in MPU6050.H should be compiled whether or not the #ifdef & #endif lines are actually there, right??
What am I missing?
The actual files are MPU6050_6Axis_MotionApps20.h and MPU6050.H from the Arduino\MP6050 folder at Jeff Rowberg's i2cDev GitHub account
TIA,
Frank
02/06/19 Addition: As a test, I placed a 'known-bad' line in the #ifdef/#endif guarded block, and the compiler flagged the line as an error. I believe this proves that the guarded block is indeed 'active' from the point of view of the compiler.
In addition, I commented out the line in MPU6050_6Axis_MotionApps20.h that #defined the 'MPU6050_INCLUDE_DMP_MOTIONAPPS20' symbol. Now the editor shows the guarded code as 'inactive' (grayed out), and the compiler acts consistently with that (complains that is is missing the function declarations from the guarded code section).
So, I have what appears to be a paradox; The compiler believes that the guarded code is active, but believes it disappears when I comment out the #ifdef & #endif lines, which should have been removed by the pre-processor ever saw the guarded code.
Any ideas?
I am using mingw to compile C++ code on OSX for Windows. The C++ code is auto generated and includes MS Visual Studio-specific code:
class __declspec(novtable) SomeClass
When I compile, I get lots of warnings:
warning: ‘novtable’ attribute directive ignored [-Wattributes]
I want to suppress these warnings. Mingw does not support the -Wno-microsoft option, so I thought I might be able to get __declspec(notable) to be treated as an identifier pointing to an empty string and have the pre-processor remove it.
i.e.
#define __declspec(novtable)
However, this is treated as a re-definition of the __declspec() macro, which is not the desired behaviour.
Is there a way to get the pre-processor to treat __declspec(novtable) as an identifier, or otherwise suppress this warning? (The offending auto-generated code cannot be modified).
Presumably the compiler has this definition in effect
#define __declspec(x) __attribute__((x))
and also recognizes some (not all) Microsoft-specific attributes like dllexport and dllimport. The following only makes sense if the above hypothesis is true.
You can use
#undef __declspec // to suppress a meessage about macro redefinition
#define __declspec(x) // nothing
(perhaps suitably #ifdefed so as not to break compatibility with MSVC).
This will kill the whole __declspec feature, not just __declspec(novtable). If this is not what you need, read on.
If you only need to kill __declspec(novtable) and leave all the other attributes intact, try this
#define novtable // nothing
The __attribute__ directive may contain a possibly empty list of attributes, so __declspec(novtable) will presumably translate to __attribute__(()), which is perfectly OK. This will also kill all other occurrences of the identifier novtable. If it does occur in any other context, which is not too likely but possible, this option won't work fro you.
Another possibility is to take over the entire feature.
#undef __declspec
#define __declspec(x) my_attribute_ # x
#define my_attribute_dllexport __attribute__((dllexport)) // or whatever you need
#define my_attribute_dllimport __attribute__((dllimport)) // or whatever you need
// ... same for all attributes you do need
#define my_attribute_novtable // nothing
// ... same for all attributes you don't need
Define your __declspec(novtable) with some macro:
#define DECL_SPEC __declspec(novtable)
After that you can use it as:
class DECL_SPEC SomeClass
And redefine DECL_SPEC as empty when required:
#ifdef __MINGW32__
#define DECL_SPEC
#else
#define DECL_SPEC __declspec(novtable)
#endif
typically #define would be used to define a constant or a macro. However it is valid code to use #define in the following way.
#define MAX // does this do anything?
#define MAX 10 // I know how to treat this.
So, if I #define MAX 10, I know my pre-processor replaces all instances of MAX with 10. If someone uses #define MAX by itself however with no following replacement value, it's valid. Does this actually DO anything?
My reason for asking is that I am writing a compiler for c in c++ and handling preprocessor directives is required but I haven't been able to find out if there is any functionality I need to have when this occurs or if I just ignore this once my preprocess is done.
My first instinct is that this will create a symbol in my symbol table with no value named MAX, but it is equally possible it will do nothing.
As an add in question which is kind of bad form I know, but I'm really curious. Are there situations in real code where something like this would be used?
Thanks,
Binx
A typical example are header guards:
#ifndef MYHEADER
#define MYHEADER
...
#endif
You can test if something is defined with #ifdef / ifndef.
It creates a symbol with a blank definition, which can later be used in other preprocessor operations. There are a few things it can be used for:
1) Branching.
Consider the following:
#define ARBITRARY_SYMBOL
// ...
#ifdef ARBITRARY_SYMBOL
someCode();
#else /* ARBITRARY_SYMBOL */
someOtherCode();
#endif /* ARBITRARY_SYMBOL */
The existence of a symbol can be used to branch, selectively choosing the proper code for the situation. A good use of this is handling platform-specific equivalent code:
#if defined(_WIN32) || defined(_WIN64)
windowsCode();
#elif defined(__unix__)
unixCode();
#endif /* platform branching */
This can also be used to dummy code out, based on the situation. For example, if you want to have a function that only exists while debugging, you might have something like this:
#ifdef DEBUG
return_type function(parameter_list) {
function_body;
}
#endif /* DEBUG */
1A) Header guards.
Building on the above, header guards are a means of dummying out an entire header if it's already included in a project that spans multiple source files.
#ifndef HEADER_GUARD
#define HEADER_GUARD
// Header...
#endif /* HEADER_GUARD */
2) Dummying out a symbol.
You can also use defines with blank definitions to dummy out a symbol, when combined with branching. Consider the following:
#ifdef _WIN32
#define STDCALL __stdcall
#define CDECL __cdecl
// etc.
#elif defined(__unix__)
#define STDCALL
#define CDECL
#endif /* platform-specific */
// ...
void CDECL cdeclFunc(int, int, char, const std::string&, bool);
// Compiles as void __cdecl cdeclFunc(/* args */) on Windows.
// Compiles as void cdeclFunc(/* args */) on *nix.
Doing something like this allows you to write platform-independent code, but with the ability to specify the calling convention on Windows platforms. [Note that the header windef.h does this, defining CDECL, PASCAL, and WINAPI as blank symbols on platforms that don't support them.] This can also be used in other situations, whenever you need a preprocessor symbol to only expand to something else under certain conditions.
3) Documentation.
Blank macros can also be used to document code, since the preprocessor can strip them out. Microsoft is fond of this approach, using it in windef.h for the IN and OUT symbols often seen in Windows function prototypes.
There are likely other uses as well, but those are the only ones I can think of off the top of my head.
It doesn't "do" anything in the sense that it will not add anything to a line of code
#define MAX
int x = 1 + 2; MAX // here MAX does nothing
but what an empty define does is allow you to conditionally do certain things like
#ifdef DEBUG
// do thing
#endif
Similarly header guards use the existance of a macro to indicate if a file has already been included in a translation unit or not.
The C Preprocessor (CPP) creates a definitions table for all variables defined with the #define macro. As the CPP passes through the code, it does at least two things with this information.
First, it does a token replacement for the defined macro.
#define MAX(a,b) (a > b) ? (a) : (b)
MAX(1,2); // becomes (1 > 2) ? (1) : (2);
Second, it allows for those definitions to be searched for with other preprocessor macros such as #ifdef, #ifndef, #undef, or CPP extensions like #if defined(MACRO_NAME).
This allows for flexibility in using macro definitions in those cases when the value is not important, but the fact that a token is defined is important.
This allows for code like the following:
// DEBUG is never defined, so this code would
// get excluded when it reaches the compiler.
#ifdef DEBUG
// ... debug printing statements
#endif
#define does a character-for-character replacement. If you give no value, then the identifier is replaced by...nothing. Now this may seem strange. We often use this just to create an identifier whose existence can be checked with #ifdef or #ifndef. The most common use is in what are called "inclusion guards".
In your own preprocessor implementation, I see no reason to treat this as a special case. The behavior is the same as any other #define statement:
Add a symbol/value pair to the symbol table.
Whenever there is an occurrence of the symbol, replace it with its value.
Most likely, step 2 will never occur for a symbol with no value. However, if it does, the symbol is simply removed since its value is empty.
According to cplusplus.com, the syntax to define a macro is:
#define identifier replacement
However, I sometimes stumble upon a macro definition which doesn't contain a replacement. For example in afxwin.h, there is the following preprocessor definition:
#define afx_msg // intentional placeholder
My questions:
What happens at compile-time when a preprocessor definition that doesn't have a replacement is used? Is it simply ignored? For example, does the line afx_msg void OnAddButton(); become void OnAddButton();?
What is the purpose of using preprocessor without replacement? Is it simply to make code more clear?
"Nothing" (no text) is a valid replacement text for a macro. It will simply be removed (more precisely, replaced by nothing) by the preprocessor.
There are multiple reasons why you'd use something like this. One is to simply use the macro in #ifdef and similar constructrs.
Another is conditional compilation. A typical use case is public APIs and DLL exports. On Windows, you need to mark a function as exported from a DLL (when building the DLL) or as imported from a DLL (when linking against the DLL). On ELF systems, no such declarations are necessary. Therefore, you'll often see code like this in public library headers:
#ifdef _WIN32
#ifdef BUILDING_MYLIB
#define MYLIB_API __declspec(dllexport)
#else
#define MYLIB_API __declspec(dllimport)
#endif
#else
#define MYLIB_API
#endif
void MYLIB_API myApiFunction();
Yet another reason could be code processing tools. Perhaps you have a tool which parses source code, extracting a list of functions with a certain marker. You can define such a marker as an empty macro.
#define bla
simply defines bla.
you can use it with
#ifdef bla
...
place some code here
...
#endif
a typical use case is #define DEBUG to enable special code parts in debugging mode.
Another way to set such things from "outside" is:
g++ -DDEBUG x.cpp
which also sets the macro DEBUG defined.
And every header file should have something like:
#ifndef THIS_HEADER_INCLUDE_GUARD
#define THIS_HEADER_INCLUDE_GUARD
...
rest of header file
...
#endif
This simply protects your header file for (recursivly) read more the once.
Some can be done with implementation specific #pragma once.
the preprocessor processes it, removing it and replacing it with nothing
could be a variety of reasons, including readability, portability, custom compiler features, etc.
What I'm talking about is to find a way to avoid the macros in <windows.h> from polluting whatever project I'm writing.
Excerpts from windows.h:
#ifdef UNICODE
#define LoadImage LoadImageW
#else
#define LoadImage LoadImageA
#endif // !UNICODE
#ifdef UNICODE
#define GetMessage GetMessageW
#else
#define GetMessage GetMessageA
#endif // !UNICODE
The majority of macros (over 99%) I'm okay with, but some of them I just couldn't find a way to avoid.
My idea is that since I always qualify the functions calls in my particular framework, e.g. ImageTool::LoadImage, Visual Studio should have enough clue that I'm not referencing the Windows API, which are all in the root namespace, i.e. ::LoadImage. But the MACRO system does not seem to be that smart.
Is there a compiler or preprocessor option that will just enable that?
Macro substitution are basically simple textual replacements, done before the proper compiler even starts to parse the code. Therefore they are not aware of namespaces or any other parts of the C++ syntax above the pure lexical level.
The straight forward way to avoid replacement of your identifiers is to remove the macros:
#ifdef LoadImage
#undef LoadImage
#endif
This of course will also stop following code from accessing the Windows API with the name LoadImage.
You will to live with it - you cannot avoid these macros on Windows platform. There is no macro-name-spacing in C/C++ pre-processor world. You may however, have all of your code defined and implemented before including any windows header - but that's wouldn't be possible, I believe.