4
votes

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?

2
The current file's name is in __FILE__. - greyfade
Oops, I know about __FILE__ but it doesn't transfer from Foo.cpp to ForceDebug.h correctly, it reports "ForceDebug.h" and not "Foo.cpp" - Roger Hanna
I've modified the question to reflect that I know about __FILE__ but that doesn't get me to report Foo.cpp - Roger Hanna
#define COMPILATION_UNIT_FILE __FILE__ in foo.cpp [or whatever] should do the trick. But no, there is no way to do this within the header. - Mats Petersson
@MatsPetersson So then usage of that macro inside a header gives the headers name… as the asker described. - Columbo

2 Answers

1
votes

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
0
votes

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