Can someone please clarify if I must add this code to the top of all my CPP files, or will it be sufficient if only one CPP file defines it?
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
You need to place this macro at the top of every translation unit1 for which you wish to track memory allocations. Macros are in effect from the point where they are defined to the end of the currently compiled translation unit (unless they are undefined prior to the end).
Also note that there's a __FILE__ macro involved, which already is a strong hint that the (non-compliant) replacement of new is per-file.
1 Translation units are the input to the compiler for which it generates object code. You can roughly think of a translation unit as a preprocessed source file (commonly with a file extension of .cpp, .cc, or .cxx).
Related
Got a new issue I've not come across before that's appeared when using the Espressif ESP32 ESP-IDF standard setup under VSCode. It uses the GNU compiler.
I'm getting "multiple definition of" errors on variables that share the same name, but which should be local.
So I use a .c and .h pair of files approach.
In my .c files I do this at the top
#define IO_EXPANDER_C //<<<This is a unique define for this file pair
#include "io-pca9539.h"
In my .h files I do this:
#ifdef IO_EXPANDER_C
//----- INTERNAL ONLY MEMORY DEFINITIONS -----
uint8_t *NextReadDataPointer;
//----- INTERNAL & EXTERNAL MEMORY DEFINITIONS -----
//(Also defined below as extern)
int SomeVariableIWantAvailableGlobally;
#else
//----- EXTERNAL MEMORY DEFINITIONS -----
extern int SomeVariableIWantAvailableGlobally;
#endif
It's a great simple system, any other .c file that includes the .h file (without the #define above its include statemnt), gets all of its extern variables, none of its local variables.
But, compiling in VSCode with my ESP-IDF based project, I'm getting "multiple definition of" errors relating to "NextReadDataPointer"
I use the same variable name NextReadDataPointer in another file pair in just the same way, but it's never declared anywhere as extern and each file pair uses a separate #define (IO_EXPANDER_C and LED_C). I do this all the time normally and I can't see any obvious mistakes.
I've never seen a C compiler do this before, it's as if it's mixing up the local definitions somehow. A #define should only have scope in the file it is declared in and in any includes within that file.
Even odder, the error is not generated if the project is built but a function is called from just one of the file pairs that share the same local variable name. It's only generated when functions are called from both file pairs from my main application.
Can anyone shed light on whether the GNU C compiler does something funky for a standard ESP-IDF project as it's got me baffled?
uint8_t *NextReadDataPointer; creates a variable which is visible across all translation units, i.e. it's the opposite of "private". If you include this header in multiple c files and the linker tries to link those together; it'll see a conflict. The keyword you're looking for is static, for example static uint8_t *NextReadDataPointer; creates a variable that is not visible across translation units. The reason you don't see the problem if calling a function from only one of those two files is because in this case the linker doesn't bother looking into the other one.
Personally I'd avoid such clever preprocessor hacks because it's quite difficult to see how files include one another and debug the resulting problems. I'd suggest sticking to the standard way of declaring shared things in header files and keeping the private stuff inside the c file (prepended by static).
Working on a Qt app on Windows. I include QVboxLayout in my source file only and this causes errors because its macro overwrites my method name.
foo.hpp
class foo
{
ChangeMenu();
}
foo.cpp
#include "foo.hpp"
#include "QVBoxLayout" // <--- this includes winuser.h
foo::ChangeMenu(){};
Now what happens is winuser.h has a macro
#ifdef UNICODE
#define ChangeMenu ChangeMenuW
#else
#define ChangeMenu ChangeMenuA
#endif // !UNICODE
This changes my function definition to ChangeMenuW but my declaration is still ChangeMenu.
How should I solve this? How can winuser.h define such a "normal" name as a macro?
Version of winuser.h is "windows kits\10\include\10.0.16299.0"
Pretty much any Windows API that deals with strings is actually a macro that resolves to a A or W version. There's no way around, you can either:
avoid including windows.h, but as you noticed, it creeps through;
brutally #undef the macro before defining/using your function; this is a fit punishment for hoarding such normal and non-macro-looking identifiers, but is tedious and some other code may actually need the Win32 function;
just accept it as a sad fact of life and avoid all the relevant Win32 APIs names; if you use Qt and follow its naming convention, it should be easy, as Qt functions use lowerCamelCase (as opposed to Win32 UpperCamelCase);
include windows.h explicitly straight in your header (possibly under an #ifdef _WIN32); this will make sure that your identifier will get replaced by the macro in all instances, so everything will work fine even if the compiler will actually compile a function with a different name; suitable for standalone projects, not suitable for libraries. (Thanks #Jonathan Potter for suggesting this)
You could take no care about this issue, Although your method name will be the same as the windows API, but the system will not mix them(just unify Unicode on both the place to define/call). If you call the ChangeMenu() directly, you will call the winapi, and if
foo f;
f.ChangeMenu();
or
foo::ChangeMenu();(static)
You will call your method.
And if you want to disable the winapi:
#ifdef ChangeMenu
#undef ChangeMenu
//code place that you define/call your own ChangeMenu().
#ifdef UNICODE
#define ChangeMenu ChangeMenuW
#else
#define ChangeMenu ChangeMenuA
#endif // !UNICODE
#endif
(It looks very tedious.)
I am working on a project with the library ADOL-C (for automatic differentiation) using gcc. Right now I am trying to recompile the library to use the parallelization features however the make process does not working apparently due to some preprocessor stuff.
I think the problematic line is :
#define ADOLC_OPENMP_THREAD_NUMBER int ADOLC_threadNumber
However I could not find what it means. Does it make a link between two variables? Also ADOLC_threadNumber has not been declared before...
The preprocessor doesn't even know what a variable is. All that #define does is define a short(long?)hand for declaring a variable. I.e., if you type
ADOLC_OPENMP_THREAD_NUMBER;
It becomes
int ADOLC_threadNumber;
It's just a text substitution. Everywhere in code where ADOLC_OPENMP_THREAD_NUMBER appears, it's substituted by int ADOLC_threadNumber.
As far as I see it, the line with the define itself is not problematic, but maybe the subsequent appearance of ADOLC_OPENMP_THREAD_NUMBER. However, to check this, we need to know more about the context.
#define is a directive used often in .h files,
it creates a macro, which is the association of an identifier or parameterized identifier with a token string.
After the macro is defined, the compiler can substitute the token string for each occurrence of the identifier in the source file.
#define may be associated with #ifndef directive to avoid to delare the identifier more than once :
#ifndef ADOLC_OPENMP_THREAD_NUMBER
#define ADOLC_OPENMP_THREAD_NUMBER int ADOLC_threadNumber
#endif
I am building a DLL to wrap a C/C++ library to be called from matlab.
I am using the standard __declspec(dllexport) to export functions. Specifically, I have several .h files with code that essentially looks like:
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _MSC_VER
__declspec(dllexport)
#endif
void FOO();
#ifdef __cplusplus
}
#endif
Then, I have a lib.h file, that just includes all these .h files.
#include "foo.h"
#include "bar.h"
My project configuration is such that it does build a DLL, but the mystery is that BAR() is in the DLL (as verified by dumpbin) but FOO is not.
Any ideas on how this could possibly be the case?
In the example above, the problem was due to the fact that BAR did not have a definition in the source tree of the project.
I'm relatively new to TFS and VS, so let me see if I can explain this in a way that makes sense.
The solution has multiple projects. One project is called MatlabDLL, the main project is called OurLibrary. The Matlab DLL is not importing all of Library, just wraps parts of it for inclusion into Matlab. In many cases, Matlab DLL can easily call directly to the C functions, in other cases, functions have to be rewritten to handle Matlab C/DLL calling semantics.
So, BAR had to have a Matlab specific C wrapper around it to enable it to be called from Matlab. The associated source file bar.cpp was in the MatlabDLL project. (Under the hood, BAR calls a number of functions whose source lives in the OurLibrary project, none of whose source files are in the MatlabDLL project.)
FOO had an implementation that did not require a C specific wrapper, so foo.cpp lived in the OurLibrary part of the source tree, and had no source files in the MatlabDLL project, although it's associated .h file was referenced by MatlabDLL.h.
In the end, VS2010 appears to only build the __declspec(dllexport)'d functions that have associated c files in the project. Adding foo.c to the project fixed the problem.
template <class T>
struct scalar_log_minimum {
public:
typedef T value_type;
typedef T result_type;
static
result_type initial_value(){
return std::log(std::numeric_limits<result_type>::max());
}
static
void update(result_type& t, const value_type& x){
if ( (x>0) && (std::log(x)<t) ) t = std::log(x);
}
};
i got the following error while trying to compile the above:
functional_ext.hpp:55:59: macro "max" requires 2 arguments, but only 1 given
max is not a macro, right? Then what is this error? BTW, I am using visual studio 2005
Also what is 55:59 --- 55 is the line number 59?
I find the many #defines that you encounter once you included windows.h very disturbing (not only max and min, but I also had problems with other generic words like Rectangle if I'm not mistaken). Therefore, I have developed the habit to include windows.h only when absolutely necessary, and never in header files. This reduces the pain to a small number of C++ files that are platform-specific.
Unfortunately some boost libraries (I believe thread and asio) do include windows.h in their headers, and I still run into this kind of silly problems from time to time.
My solution for the remainder of the situations where this causes problems is to #undef the problematic symbols after the inclusion of the header files.
You're including a header file somewhere that #defines max as a macro. The best solution would be to figure out where it's being defined, and inhibit it from being defined if possible. Alternatively, you could just #undef it:
#include <evil_header_which_defines_max.h>
#undef max
As others have noted, including windows.h is probably your problem. Microsoft provides a means to "turn off" parts of windows.h with preprocessor symbols. You can define these symbols as part of your build or directly in code.
Using preprocessor symbols to conditionally skip sections of windows.h may or may not be considered elegant but in the general case it is an easier, more general and more scalable solution than #undef.
Here's how to skip defining min or max as macros:
#define NOMINMAX
#include <windows.h>
Note that many include files will, at some point, include windows.h. In such cases setting up your defines at a more global level may be more convenient.
If you search through windows.h, you can find a bunch of other preprocessor symbols (e.g., NOOPENFILE, NOKANJI, NOKERNEL and many others) that can often be useful.
It's a macro called max that gets into the way as Adam explained. Another solution (more a "hotfix") may be to put parentheses around the function, to prevent it from being seen as a macro invocation:
return std::log((std::numeric_limits<result_type>::max)());