Get current compilation unit name within #include - c++

My current goal is to create one (or as few as possible) line of code that will switch the remainder of the active compilation unit to an unoptimized, debug configuration. My first instincts were either:
FORCE_DEBUG;
// code below here will be forced to be unoptimized and in a debug environment
or
#include "ForceDebug.h"
// code below here will be forced to be unoptimized and in a debug environment
would be ideal. In my workspace, to convert to an unoptimized debug configuration requires I change the pragma optimize level, but also #undef some macros and #define other macros.
The FORCE_DEBUG macro doesn't work because it would need to execute preprocessor directives #undef and #define which I understand are not evaluatable within a macro.
Instead I have a working version of #include "ForceDebug.h". But I want to message the developer that they have disabled optimization on a given compilation unit (so they don't check it in, or if they do check it in that it can be caught and fixed). Ideally this message includes the filename of whichever file #includes "ForceDebug.h" or the current compilation unit.
Here's an approx ForceDebug.h
#pragma once
#pragma message("DISABLING OPTIMIZATION IN" COMPILATION_UNIT_FILE)
#undef _RELEASE
#define _DEBUG
#ifdef _MSC_VER
# pragma optimize("", off)
#else
# pragma GCC optimize("O0")
#endif
So a call site would look something like Foo.cpp:
// this messages "ForceDebug.h", I want to message "Foo.cpp"
//#define COMPILATION_UNIT_FILE __FILE__
// double macro also messages "ForceDebug.h"
//#define COMPILATION_UNIT_FILE COMPILATION_UNIT_FILE2(__FILE__)
//#define COMPILATION_UNIT_FILE2(x) x
// this works but requires doing it manually, which I'm trying to avoid
#define COMPILATION_UNIT_FILE "Foo.cpp"
#include "ForceDebug.h"
// code below here will be forced to be unoptimized, debug environment
I can't use __FILE__ because that messages about ForceDebug.h, when I want it to report about Foo.cpp.
If I could evaluate __FILE__ inside Foo.cpp and pass the evaluated version into ForceDebug.h that would be acceptable, but I tried recursive macro calls and it still reported ForceDebug.h
Is there any way to get it to pass "Foo.cpp" into the include or to derive that value by some other means for either clang or Visual Studio?

I was not able to find a way to emit the current compilation unit name from an included file.
However, your proposed syntax requires the user of "ForceDebug.h" to add another directive to expose its compilation unit name to the header file. Instead, you can turn it around and allow simple inclusion that defines a macro that allows for the message to be emitted.
While, generally speaking, macros cannot be used to generate pre-processor directives, there is a syntax for pragmas for the compilers you illustrated. MSVC and GCC each have their own syntax, but conditional compilation can make the syntax appear uniform.
In your source file:
#include "ForceDebug.h"
FORCE_DEBUG;
//... rest of source
In "ForceDebug.h":
#pragma once
#ifdef _MSC_VER
#define DO_PRAGMA(X) __pragma(X)
#define NO_OPT optimize("", off)
#else
#define DO_PRAGMA2(X) _Pragma(#X)
#define DO_PRAGMA(X) DO_PRAGMA2(X)
#define NO_OPT GCC optimize("O0")
#endif
#define FORCE_DEBUG \
DO_PRAGMA(message("DISABLING OPTIMIZATION IN " __FILE__)) \
DO_PRAGMA(NO_OPT) \
struct __force_debug
#undef _RELEASE
#define _DEBUG

You could use the __FILE__ predefined macro like below:
#pragma message("DISABLING OPTIMIZATION IN " __FILE__)
Live Demo
Edit:
Since you want to report about the .cpp file I would go the other way around. That is, I would change ForceDebug.h to:
#pragma once
#undef _RELEASE
#define _DEBUG
#define OPT_OFF
^^^^^^^^^^^^^^^
#ifdef _MSC_VER
# pragma optimize("", off)
#else
# pragma GCC optimize("O0")
#endif
And then I would put the potensial message in my .cpp file:
#include "foo.h"
...
#ifdef OPT_OFF
#pragma message("DISABLING OPTIMIZATION IN " __FILE__)
#endif

Related

Include precompiled header in ifdef

I have a cross-platform project and thing is on Windows I want to use precompiled headers(its really vital in this case) and Linux I dont want it. So I would like to have something like this:
#ifdef _WIN32
#include "precompiled.h"
#endif //#ifdef WIN32
When I build on Windows I get this annoying error, claiming:
PCH warning: header stop cannot be in a macro or #if block. An intellisense pch was not generated
Is there any workaround to fix this issue?
Thanks on advance.
I already have this problem and for me one of these two options worked for me.
1) Maybe if you add #pragma once at the start of the file (even before the #ifndef _WIN32 header guard).
2) Or you can add on your header files this skecth:
#ifndef MYHEADER_H
#define MYHEADER_H
... contents of myheader.h
#endif /* MYHEADER_H */
This will guarantee your header will be compiled just once and this warning will disapear (at least for me).
Hope it works!

Remove #pragma once warnings

I am using #pragma once in my .cpps and .hpps and because of that I get a warning for each file that uses it. I have not found any option to disable this kind of warning, only the thing of #ifndef MY_FILE_H #define MY_FILE_H /*...*/ #endif.
So would you recommend me to replace each #pragma once with ifndefs?
in header:
#define MYFILE_H
// all the header
and in the other files:
#ifndef MYFILE_H
#include "myfile.hpp"
#endif
// the rest of the file
What do you think, is it better to use it like this? Or there is an option to disable the #pragma once warnings in GCC, that I do not know?
The common approach is to place the guard in the .h file only:
#ifndef MYFILE_H
#define MYFILE_H
// all your myfile.hpp here
#endif
or
#pragma once
// all your myfile.hpp here
The rest of files (other .cpp) should do nothing regarding the guards. You should not get warnings by doing this.
Indeed the #ifndef guard can always be used, but just to remove the warning while compiling the source which uses #pragma once I would recommend to use the -woption while compiling.
e.g. gcc -w -o <output file> <input file(s)>

How to disable asserts without changing command line?

I have C++ code with asserts. When I compile the code with g++ -D NDEBUG option no assert commands are executed. But when I include NDEBUG on the code #define NDEBUG and compile it with no -D NDEBUG option, assert command are executed. How to disable asserts without changing command line?
You have to define NDEBUG before including the header that defines assert. Try
#define NDEBUG
#include <assert.h>
at the top of the source file you want to disable assertions in.
By defining NDEBUG. In practice, you would never compile with
-D NDEBUG in the command line; you should define your own
debug command, and then when the profiler shows you cannot
afford the checks in a specific function, wrap the function in
something like:
// Non-critical code...
#ifdef MYDEBUGOFF
#define NDEBUG
#endif
#include <assert.h>
// Critical function
#undef NDEBUG
#include <assert.h>
// More non-critical code.
You can include <assert.h> as often as you like; each time it
redefines the assert macro according to whether NDEBUG is
defined at that moment. So you can tune to your heart's
content; just #define NDEBUG or #undef NDEBUG each time
before you include the header.

Preprocessor in visual studio 2010-c++ project

In .cpp file I use a macro mmData1.I searched in the project and see that this macro is defined in several files.(I.e. there are several .h files which have the line #define mmData1)
I want to know if there is a capability in VS10 to check from which file the preprocessor takes the macro value
If Intellisense does not know then there is no direct way. However, there are indirect ways. Say your macro name is SOME_MACRO
After each instance of #define SOME_MACRO put #error Defined here, then right click the source file and choose Compile. If compiler returns an error remove the directive that raises it and compile again. The last instance of this error will tail the definition visible in the source.
Make each directive defining SOME_MACRO define it as something else and then, in the source file, add these lines after all includes:
#define STRINGIZE(x) STRINGIZE2(x)
#define STRINGIZE2(x) #x
#pragma message("SOME_MACRO is expanded as: " STRINGIZE(SOME_MACRO))
Compile the source file; you should see the value in the build log.
Less intrusive way: put those lines after each #define SOME_MACRO
#pragma push_macro("STRINGIZE")
#pragma push_macro("STRINGIZE2")
#define STRINGIZE(x) STRINGIZE2(x)
#define STRINGIZE2(x) #x
#pragma message("Defining at " __FILE__ ":" STRINGIZE(__LINE__))
#pragma pop_macro("STRINGIZE")
#pragma pop_macro("STRINGIZE2")
Or, if you don't need the line number:
#pragma message("Defining at " __FILE__)
Compile the file. Looking at build log you should be able to tell the order of SOME_MACRO definitions.
The best way to see exactly what the preprocessor is doing is to inspect its output directly. Intellisense is helpful but often does not match what the compiler understands.
A simple trick I always use is to redefine the macro at the line you want to check. When you compile the code, the preprocessor will complain and tell you where the previous definition was.
Example:
test.cpp contains:
#include "test.h"
int main()
{
#define SOMEMACRO 1
return 0;
}
test.h contains:
#define SOMEMACRO 2
int foo();
when compiling test.cpp, IĀ get this error message:
test.cpp:5:0: warning: "SOMEMACRO" redefined [enabled by default]
In file included from test.cpp:1:0:
test.h:1:0: note: this is the location of the previous definition
I tested on GCC, but Visual Studio does the same thing.

Safer conditional compilation?

In an MSVC C++ program I have a part of code which I want to enable or disable depending on a preprocessor definition
// 1.h
#ifdef MYOPTION
//...
#endif
But I find that it is quite dangerous when it is used in a .h file included in more than one compilation unit, as I can easily get inconsistent headers (I don't want to define MYOPTION globally as it would require a complete recompilation each time I change it):
// 1.cpp
#define MYOPTION
#include "1.h"
// 2.cpp
#include "1.h"
Of course, it is much more complicated than this simplified example due to the chained header inclusion.
Is there a way to avoid such inconsistency, e.g. have a compile-time error without too much effort?
I thought of doing #define MYOPTION 0 or 1, but then I would have to write something like
#if MYOPTION == 1
//...
#elif !defined(MYOPTION)
#error ...
#endif
which looks too complicated... Maybe there is a better option?
How about something like this: have 1.h define a dummy section in the obj with different options. This way, if MYOPTION is ever used inconsistently, the linker will issue a warning.
1.h:
#ifdef MYOPTION
#pragma section("MYOPTION_GUARD",write)
#else
#pragma section("MYOPTION_GUARD",read)
#endif
namespace { __declspec(allocate("MYOPTION_GUARD")) int MYOPTION_guard; }
Compiling with MYOPTION defined in a.cpp but not in b.cpp yields this linker warning (using VC 2008):
b.obj : warning LNK4078: multiple 'MYOPTION_GUARD' sections found with different attributes (40300040)
A consistent definition yields no linker warnings at all.
I think you've listed most solution yourself, basically. I would use the last solution, but perhaps in a slightly different form:
#ifndef MYOPTION
#error ...
#endif
...
#if MYOPTION == 1
//...
#endif
Because often this #if MYOPTION == 1 will appear more than once in each file. It's also clearer that MYOPTION is a requisite for that file.
You say it "looks too complicated", but I'm afraid there's probably no solution that's less "complicated" than this.
Assuming that you actually need to use the defines, better is to define them via the compiler command line than #define in your source files. Then your configure script/makefile/build process sets the define once and you're guaranteed that it will agree properly across all source files.
Perhaps what you want is to create a separate configuration.
You can go to Build -> Configuration Manager and create a new configuration (separate from DEBUG, RELEASE). Creating a new configuration will allow you to define preprocessor symbols specific to that configuration.
For example, with a new configuration titled "MyOption 1" you could add the preprocessor definition MYOPTION = 1. The same thing goes with MYOPTION = 2, 3, ...
Each configuration has to be built separately.
DEBUG and RELEASE are examples of separate configurations; DEBUG defines _DEBUG and RELEASE defines NDEBUG