Create custom #warning flags - c++

I'm building a commercial app, and we are using some GPL code to help us along.
How can I add #warning or #error statements so that when the code is built for debug, it warns, but when we build for release it throws errors?
I can do:
#warning this code is released under a CCL licensing scheme, see Source_Code_License.rtf
#warning this code is not LGPL-compliant
#warning this code was copied verbatim from a GP Licensed file
at the beginning of files, but can I do better? Is there a better way of tagging a file if it's included?
I'm using Objective-C++ with gcc or clang.

#ifdef SOME_SYMBOL
#error "foobar"
#else
#warning "foobar"
#endif
NDEBUG has a slightly different purpose (controlling assert) and may be #undef and re-defined selectively (reincluding assert.h to effect the change), so it probably wouldn't be the right symbol. But it is a standard macro and could be used.
Note that #error is standard, but #warning is an extension.

Use #pragma message instead.

Related

Netbeans "__cplusplus" Defined Wrong

In my Ubuntu Netbeans 7.3 installation, I have a C++ project with C++11 marked as the standard in the C++ Compiler Options. When I try to include <chrono> it does not seem to make the std::chrono namespace available. When I open up this file to see what's wrong, I see everything greyed out but his first section:
#ifndef _GLIBCXX_CHRONO
#define _GLIBCXX_CHRONO 1
#pragma GCC system_header
#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else
When I hover over the __cplusplus constant, to see how it was defined, it says it's defined as 199711L. Why is this? I clearly set the project C++ Standard to C++11.
Go to Tools->Options
Select C/C++ menu
Select Code Assistance tab
Select C++ Compiler tab
In Macro Definitions list view, locate __cplusplus and change its value to 201103L
Click OK button

Macro undefined error while building a plugin

I am working on a plugin in which I need to #include a header file (let's say some_file.h) which in turn includes environ.h. Now, when I build my plugin, the build fails with some errors in the environ.h file and some other dependent files. Here's a code sample from environ.h where the error is occurring:
#ifndef PLATFORM
#ifdef WIN_ENV
#define PLATFORM "winpltfm.h"
#elif __OS2__
#define PLATFORM "os2pltfm.h"
#elif defined(unix) || defined(__unix)
#define PLATFORM "UnixPlatform.h"
#else
#error You must define the PLATFORM macro <------- Error-1
#endif
#endif
#include PLATFORM <------- Error-2
The Error-1 is: #error you must define the platform macro and Error-2 is easy to guess: Expected <filename> or "filename".
The strange thing is that some other plugin where some_file.h is included works fine i.e. builds successfully. This made me think that there must be some build settings which might be different.
Can anyone suggest what should be done in such a case to remove the errors from the environ.h header file?
Note: I am working on MAC OS X in Xcode.
I continued my comments to this answer so it's easier to explain...
First, instead of #elif __OS2__ it should be #elif defined(__OS2__) that's why during your test #define __OS2__ didn't work, but #define __OS2__ 1 did.
EDIT: From your comments you noted that environ.h is a standard file, but it seems odd how they are checking for the OS2 define. They are forcing it to be defined to a value rather than just being defined.
Second, as evident from your test, the compiler isn't defining __OS2__ for you, and there might be another header that is, but isn't currently included in the tranlation unit that picks up some_file.h. If you've confirmed that OS2 isn't defined by another header file in your project you can define a macro for the preprocessor by following these steps given by this SO answer:
The build setting you need to change is called 'Preprocessor Macros'
and it can be found in the 'Build Settings' tab of the Project
Settings pane (use the search box to find it). Select each target in
turn in the left-hand side of the Project Settings pane then modify
the Preprocessor Macros setting.
The setting is specified as a space-separated list of preprocessor
macros in the form 'foo' or 'foo=bar'.
Third, it seems your include path to os2pltfm.h is wrong or missing in your compiler settings.
You can include the file following the instructions given in this SO answer:
All you have to do is add the -I flag to your build setting under
"Other C Flags"
So in your target's build setting search for "Other C Flags" and add
-I/path-to-include/

How to use the FTGL C API from C++?

How do I use FTGL's C API from C++ code in Visual Studio 2010?
FTGL uses #ifdef __cplusplus checks to export C and C++ APIs from the same header files.
I tried this:
#ifdef __cplusplus
#undef __cplusplus
#include <FTGL/ftgl.h>
#define __cplusplus
#else
#include <FTGL/ftgl.h>
#endif
But VS2010 isn't having it:
warning C4117: macro name '__cplusplus' is reserved, '#undef' ignored
warning C4117: macro name '__cplusplus' is reserved, '#define' ignored
The macro __cplusplus is a reserved macro, and should be defined automatically by your compiler if you're compiling as C++ code (and not defined otherwise). You shouldn't have to #define it manually, and that's why your compiler throws an error.
How do I use FTGL's C API from C++ code in Visual Studio 2010?
You don't.
The makers of FTGL apparently don't want C++ users to use the C API. So they don't let them.
The __cplusplus macro is a part of the C++ language; it cannot be undefined. Or defined. Or redefined. And since that's what FTGL keys off of, there's no way to trick it into compliance.
The only way to avoid this is to edit FTGL itself.

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

Using Boost.Thread headers with MSVC Language Extensions disabled

I just discovered that when Language Extensions are disabled in MSVC, you get this error if you try to include boost/thread/thread.hpp:
fatal error C1189: #error : "Threading support unavaliable: it has been explicitly disabled with BOOST_DISABLE_THREADS"
It seems that when Boost detects that language extensions are disabled (_MSC_EXTENSIONS isn't defined), they define BOOST_DISABLE_WIN32, to indicate that it is not safe to include windows.h (which won't compile without extensions enabled).
And as a consequence of that #define, BOOST_DISABLE_THREADS is defined, even though Boost.Thread isn't a header-only library, and windows.h is only included in the .cpp files. The headers should in principle be safe to use without language extensions. All the actual win32 calls are isolated in the compiled library (the .dll or .lib)
I can see here that they're aware of the problem, but as it's remained untouched for the last two years, it's probably naive to hope for a quick fix.
It seems like it should be a fairly simple case of modifying some of the #ifdef's and #defines in the various Boost configuration files, but there are a lot of them, and they define and use a lot of macros whose purpose isn't clear to me.
Do anyone know of a simple hack or workaround to allow inclusion of the Boost.Thread headers when language extensions are disabled?
I don't see any simple way to turn off the behavior.
You could wrap the block with your own #ifdef starting at boost\config\suffix.hpp(214):
#ifndef TEMP_HACK_DONT_DISABLE_WIN32_THREADS // XXX TODO FIXME
#if defined(BOOST_DISABLE_WIN32) && defined(_WIN32) \
&& !defined(BOOST_DISABLE_THREADS) && !defined(BOOST_HAS_PTHREADS)
# define BOOST_DISABLE_THREADS
#endif
#endif // ndef TEMP_HACK_DONT_DISABLE_WIN32_THREADS
Not a perfect fix, but it should be temporary until you can get them to fix it upstream. The boost stuff is good, but it's not immutable in its perfection.
Of course, make some kind of tracking item so you don't lose track of your divergence from upstream.