C++ How to protect oneself from stdio.h macros - c++

I spent a long time trying to figure out why the following wouldn't compile:
enum IPC_RC {OK, EOF, ERROR, NEW };
The error message said only something to the effect that it wasn't expecting to see an open parenthesis. It wasn't until I tried compiling it on a more modern compiler that I learned:
/usr/include/stdio.h:201:13: note: expanded from macro 'EOF'
#define EOF (-1)
So I've finally been burned by a macro! :)
My code doesn't #include <stdio.h> (I don't include anything with a .h suffix), but clearly something I included resulted in the inclusion of <stdio.h>. Is there any way (namespaces?) to protect myself, without tracing down exactly where it was included?

Namespaces will not be a solution because macros ignore them.
So you have two options:
get rid of those macros yourself:
#ifdef EOF
#undef EOF
#endif
use a prefix with your enum values:
enum IPC_RC
{
IPC_OK,
IPC_EOF,
IPC_ERROR,
IPC_NEW
};

I don't know a satisfactory solution to the problem you describe, but I just wanted to share one way to handle the situation. Every now and then you (have to) use some particularly obnoxious header which redefins a good part of the English language. The X11 headers of Python.h come to mind. What I ended up doing - and it worked out very well - is that (usually after I notice the breakage) I wrap the 3rd party header in my own header and deal with the uglyness there.
For instance, in projects which make use of the Ruby interpreter, I usually don't include ruby.h directory but rather include an ourruby.h file which looks something like this:
#ifndef RUBY_OURRUBY_H
#define RUBY_OURRUBY_H
// In Ruby 1.9.1, win32.h includes window.h and then redefines some macros
// which causes warnings. We don't care about those (we cannot fix them).
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable:4005)
#endif
#include <ruby.h>
#ifdef _MSC_VER
# pragma warning(pop)
#endif
// In Ruby 1.8.7.330, win32.h defines various macros which break other code
#ifdef read
# undef read
#endif
#ifdef close
# undef close
#endif
#ifdef unlink
# undef unlink
#endif
// ...
#endif // !defined(RUBY_OURRUBY_H)
That way, I don't have to take care of remembering the fact that some headers are not exactly namespace clean.

Related

Foolproof way to do configuration #define/#ifdef

I'm working with a moderately sized embedded C++ project that has a number of configurations for different target products. There are a good number of macros that get set for various configuration items in the different configurations and I'm trying to make that system as error-proof as possible.
Initially, I was just doing the standard thing:
#define CFG_FOO
#ifdef CFG_FOO
<code here>
#endif
but I'm always afraid I'm going to mistype a macro name in an ifdef and have a hard to find bug, because this evaluates to false without error:
#ifdef CFG_FOOO
So, I changed all the macros to this format, which requires that the macro in question be defined, defining all the ones that I want to evaluate as false to 0:
#define CFG_FOO() (1)
#define CFG_BAR() (0)
#if CFG_FOO()
<code is active>
#endif
#if CFG_BAR()
<code is inactive>
#endif
// Produces error, as desired:
#ifdef CFG_FOOO()
#endif
This was good, except that then if I accidentally enter the following (which I found I do all the time, just out of habit) it is true and the contained code is compiled:
#ifdef CFG_BAR
<this is active>
#endif
So I'm looking for a solution that:
Always generates an error for mistyped CFG_xxx item.
Doesn't allow for unintended consequences if using the wrong directive #if vs. #ifdef (it's fine if there's a error for "incorrect" usage.)
Doesn't require additional libraries/frameworks (like Boost).
Doesn't require an additional tool to process all the code (this is what I'm doing now, scanning for any #ifdef and generating an error, but that's not ideal.)
Actually removes the unneeded code. A runtime solution is probably impractical as the code size needs to be tightly controlled.
NOTE: I'm aware of the -Wundef option for gcc, but I don't believe that really helps, as the accidental #ifdef situation is still present.
My best recommendation is never get yourself into a situation where CFG_FOO is valid, CFG_BAR is valid, but both together is not valid.
We can do better by simply avoiding this problem. Specialized form for a switch ladder. CFG is a bad prefix but I'm assuming it's an artifact of minimalization and you simply will have a better one.
modeswitch.h:
#define CFGMODE_FOO 1
#define CFGMODE_BAR 2
header.h:
#if CFG == CFGMODE_FOO
#elif CFG == CFGMODE_BAR
#else
#error CFG has unsupported value
#endif
program.c
#include "modeswitch.h"
#define CFG CFGMODE_FOO
#include "header.h"
If I read this wrong and you're not using this stuff in .h files than I wonder why you have both C and C++ tags but just inline the stuff and it will still work.
My understanding is there's enough power in ## that there's a way to get rid of the pre-header but it's so hard that it doesn't meet any reasonable definition of foolproof.
Instead of repeatedly do
#if CFG_FOO()
<code is active>
#endif
since C99 or C++11, you might have once (per config)
#if CFG_FOO() // or #ifdef CFG_FOO
# define WITH_FOO(...) __VA_ARGS__
#else
# define WITH_FOO(...) /*Empty*/
#endif
And then
WITH_FOO(
<code is active>
)
Note:
It might probably break auto-indentation.
Not sure it is better than traditional way more prone to typo.
Since you're using the gcc compiler, it has a built-in #pragma for this, that throws a compiler error anytime a variable/phrase is used. This would mostly be used when you want to prevent future programmers from using things like PRINTF statements, but you can also use it in a clunkier way to eliminate the possibility that you mistype your variable names in a common way. ie. you would type something like:
#pragma GCC poison CFG_FOOO CFG_FOOD CFG_FOO0 CFG_FO
Note - I've only ever worked with this in theory, so I'm not certain it will work for you. Slightly more info in this doc:
https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html

How to get rid of insecure functions (sprintf, ...)

I want to get rid of all uses of insecure functions like sprintf and the like in a large C++ project.
I would like to have errors or at least warnings, that show me all occurrences for further reviewing.
I know, that on OpenBSD there is such a warning, but I'm on Linux. If I try to define a macro for sprintf I get errors in the <cstdio> header. So any good ideas, besides patching the system headers?
Edit:
Additional challenge is, that there is a sprintf function in a homegrown C++ string class. So, just grepping for sprintf results in a lot of false positives.
Even though I completely concurr with #Matt that the functions are not bad, and you are quite indiscriminate in your banning, here ways to do so.
Today is patch your headers day:
Copy your headers, then run grep to find those functions you fear.
Add __attribute__ ((deprecated)) to them.
Recompile your project.
Profit???
Not patching headers?
Still, it might be better to go the direct way: Just grep your own project files.
You can even save that search as a script for re-application.
Use the preprocessor (beware, we are changing reserved identifiers, which is bad!):
Add a file "explosive_security.h" like this:
inline static int my_deprecated() __attribute__ ((deprecated)) {return 0;}
#undef strcmp
#define strcmp (my_deprecated(), strcmp)
And include it after all other includes.
That should generate a warning and no error in most contexts, though always an error in some.
Based on the answers of #Deduplicator and #alastair I came up with the following solution, which works for me:
In a header file, that is included by every compile unit with the -include option of gcc (that was already there before), I added these lines:
#ifdef __cplusplus
#include <cstdio>
#else
#include <stdio.h>
#endif
#undef sprintf
extern "C" {
int sprintf(char *, const char*, ...) __attribute__((error("!!!DON'T USE sprintf(), USE snprintf() INSTEAD!!!")));
}
Of course you can replace error with warning. (For some reason deprecated did not produce a warning in my setup, didn't further research, why.)
Thanks to all contributers!
Use a simple #define, not a more complex one. For instance
#undef sprintf
#define sprintf __DO_NOT_CALL_SPRINTF
is much more likely to work without problems than
#undef sprintf
#define sprintf(s,f,...) __DO_NOT_CALL_SPRINTF(s, f, __VA_ARGS__)
If you still have difficulty, make sure you #include all relevant headers before you use the #define; an easy way to do this is to make a project-wide header file (call it "safety.h") and inside that header, do e.g.
#ifdef __cplusplus
#include <cstdio>
#else
#include <stdio.h>
#endif
#undef sprintf
#define sprintf __DO_NOT_CALL_SPRINTF
Of course, all of this may well be more trouble than it's really worth.

Temporary macro to store another macro and then reverting back

I want to have more control over macros such as assertions (and some logging macros that are not directly under my control). So I decided to do something like this, expecting it to work (in case somebody is wondering, the reason it does not work is that the last undef of MY_ASSERT_COPY invalidates MY_ASSERT right before it).
#ifndef ENABLE_FULL_ERROR_ASSERTS
#define MY_ASSERT_COPY MY_ASSERT
#undef MY_ASSERT
#define MY_ASSERT
#endif
// Code for my current class, which happens to be header only
#ifndef ENABLE_FULL_ERROR_ASSERTS
#undef MY_ASSERT
#define MY_ASSERT MY_ASSERT_COPY
#undef MY_ASSERT_COPY
#endif
Now I know a few ways around it, one being to define another macro for assertions just for that file, which I can then turn off without affecting assertions in any other part of the program. I initially thought this was a really elegant solution (before I found out it did not compile) that will allow me to use MY_ASSERT everywhere and then simply turn it off for particular files.
Since the above doesn't work, is there a workaround that will allow me to selectively kill the macro without affecting the surrounding code and without defining another substitute macro like #define MY_ASSERT_FOR_VECTORS MY_ASSERT
Some compilers provide #pragma push_macroand #pragma pop_macro to save and restore macro state.
Limited portability though.
This may not work in all situations, but maybe you could simply undef the macros, define them as you wish and then undef them again.
The next time your code uses some of these macros it should #include the header files where they were initially defined so it will define those macros again.
One safe option would be:
#ifndef ENABLE_FULL_ERROR_ASSERTS
#undef MY_ASSERT
#define MY_ASSERT ....
#endif
// Code for my current class, which happens to be header only
#ifndef ENABLE_FULL_ERROR_ASSERTS
#undef MY_ASSERT
#include "headers.h" //etc
// line above should redefine the macros
#endif

why headerFileName_H

while I am creating a c++ header file, I declare the header file like;
/*--- Pencere.h ---*/
#ifndef PENCERE_H
#define PENCERE_H
I want to learn that why do I need to write underline.
You don't need to use the underline, it's just a convention to separate the header name and extension. You cannot use the literal . since that's not valid in an identifier so you replace it with an underscore which is valid.
The reason you actually do it is as an include guard. The entire contents of the file are something like:
#ifndef PENCERE_H
#define PENCERE_H
// Your stuff goes here.
#endif
so that, if you accidentally include it twice:
#include "pencere.h"
#include "pencere.h"
you won't get everything in it duplicated. The double inclusions are normally more subtle than that - for example, you may include pax.h and diablo.h in your code and pax.h also includes diablo.h for its purposes:
main.c:
#include "pax.h"
#include "diablo.h"
// Other stuff
pax.h:
#ifndef PAX_H
#define PAX_H
#include "diablo.h"
// Other stuff
#endif
diablo.h:
#ifndef DIABLO_H
#define DIABLO_H
typedef int mytype;
#endif
In this case, if the include guards weren't there you would try to compile the line typedef int mytype; twice in your program. Once for main.c -> pax.h -> diablo.h and again for main.c -> diablo.h.
With the include guards, the pre-processor symbol DIABLO_H is defined when main.c includes diablo.h so the #define and typedef are not processed.
This particular mapping of header files to #define names breaks down in the situation where you have dir1/pax.h and dir2/pax.h since they would both use PAX_H. In that case, you can use a scheme like DIR1_PAX_H and DIR2_PAX_H to solve the problem.
The underline is not necessary, that's just a way to produce a string for the include guard that is unlikely to be produced anywhere else and cause hard to detect problems. Even more, you are free to select any symbol for the include guard as long as it will not be defined anywhere else.
It's because you can't #define PENCERE.H
You can define anything you want, but by using a format of using the filename, replacing . with _ means you shouldn't clash #defines that guard importing the same header file twice.
You don't need to write the underline. All you need is a preprocessor symbol which isn't defined anywhere else. If you like (and/or if you have a Pascal background ;-}) you could just as well say
/*--- Pencere.h ---*/
#ifndef THE_PENCERE_HEADER_FILE_WAS_INCLUDED
#define THE_PENCERE_HEADER_FILE_WAS_INCLUDED

How do I avoid name collision with macros defined in Windows header files?

I have some C++ code that includes a method called CreateDirectory(). Previously the code only used STL and Boost, but I recently had to include <windows.h> so I could look-up CSIDL_LOCAL_APPDATA.
Now, this code:
filesystem.CreateDirectory(p->Pathname()); // Actually create it...
No longer compiles:
error C2039: 'CreateDirectoryA' : is not a member of ...
Which corresponds to this macro in winbase.h:
#ifdef UNICODE
#define CreateDirectory CreateDirectoryW
#else
#define CreateDirectory CreateDirectoryA
#endif // !UNICODE
The pre-processor is redefining my method call. Is there any possible way to avoid this naming collision? Or do I have to rename my CreateDirectory() method?
You will be better off if you just rename your CreateDirectory method. If you need to use windows APIs, fighting with Windows.h is a losing battle.
Incidently, if you were consistent in including windows.h, this will still be compiling. (although you might have problems in other places).
You could create a module whose sole purpose is to #include <windows.h> and look up CSIDL_LOCAL_APPDATA wrapped in a function.
int get_CSIDL_LOCAL_APPDATA(void)
{
return CSIDL_LOCAL_APPDATA;
}
btw, Well done for working out what happened!
#undef CreateDirectory
As a developer working on a cross platform codebase, this is a problem. The only way to deal with it is to
ensure that windows.h is - on Windows builds at least - universally included. Then the CreateDirectory macro is defined in every one of your compilation units and is universally substituted with CreateDirectoryW. Precompiled headers are ideal for this
OR, if that is an unpleasant proposition, (and it is for me)
isolate windows.h usage into windows specific utility files. Create files that export the basic required functionality. The header files must use data types that are compatible with, but do NOT depend on the inclusion of windows.h. The cpp implementation file must (obviously) use windows.h.
If your utlility functions need to include project header files with conflicting symbols then the following pattern is a necessity:
#include <windows.h>
#ifdef CreateDirectory
#undef CreateDirectory
#endif
// etc
#include "some_class_with_CreateDirectory_method.h"
// ...
You will need to then explicitly call the non macro version of any windows api functions you have #undef'd - CreateDirectoryA or W etc.
push macro, undef it and pop the macro again:
#pragma push_macro("CreateDirectory")
#undef CreateDirectory
void MyClass::CreateDirectory()
{
// ...
}
#pragma pop_macro("CreateDirectory")
You can take a back up of CreateDirectory, then undefine it, and then define it again when you finish your job with you custom one.
#ifdef CreateDirectory
#define CreateDirectory_Backup CreateDirectory
#undef CreateDirectory
#endif
// ...
// Define and use your own CreateDirectory() here.
// ...
#ifdef CreateDirectory_Backup
#define CreateDirectory CreateDirectory_Backup
#undef CreateDirectory_Backup
#endif
Note that name conflict usually comes from a certain header file being included. Until then stuff like CreateDirectory and GetMessage isn't pulled into visibility and code compiles without a problem.
You can isolate such an inclusion into a wrapper header file and "#undef whatever" at its end. Then, whatever name collision you have will be gone. Unless, of course, you need to use those macros in your own code (yeah, so very likely...)
#pragma push_macro("CreateDirectory")
If nothing works, instead of renaming you could use your own namespace for your functions.