Is it possible to test whether a file has been included using preprocessing directives?
I wanted to achieve something like this:
#ifincluded assert.h
#error "Should not include assert.h"
#endif
At the moment, I solve this knowing that assert.h has defined _ASSERT_H. In this case, I can use #ifdef _ASSERT_H. The problem is that this is implementation specific.
Is there a better way to achieve this?
You could simply make use of the fact that assert() itself is a macro, so you could just do an
#ifdef assert
#error "Should not include assert.h"
#endif
This would, of course, also complain in case someone defines their own assert macro, which would, strictly speaking, be a legal thing to do as long as they don't include any standard header…
At the end of the day, I would reconsider whatever it is exactly that you think you're trying to do here. If you're at a point where you have to make sure someone does not include a specific standard header, you're most likely on the wrong path and there's most likely a much better but completely different approach to be found if you just take a step back and rethink from the very beginning. So
Is there a better way to achieve this?
Almost certainly. But it will not have anything to do with detecting and adjusting behavior depending on whether specific parts of the standard library have been included or not…
Related
What is the best way to deal with intrusive #defines in windows headers? They tend to emit errors when I really need to define a symbol with the same name, no matter if it is in a namespace or not. I know some defines can be avoided with WIN32_LEAN_AND_MEAN, but not all. In this particular case, I'm hitting a "DELETE" define in WinNT.h#6478 - and there are tons of pretty generic keywords like this.
My immediate thought is to do an #undef before declaring my constant, but that is a very unelegant solution. I can't easily rename my constants because they are directly translated to text strings and I need those to be exactly what they are now.
Other defines that come to mind are GetFirstChild/GetNextSibling in windowsx.h ... really?
Realistically, I think the cleanest solution would be to provide a wrapper header that would #include <windows.h> and #undef all the macros that are getting in your way. You would then include this wrapper header instead of windows.h.
The obvious solution is not to include <windows.h>. There
should be very, very few modules which need it, and in those,
you just have to avoid the symbols which <windows.h> defines.
Which shouldn't be too difficult, because those will be low
level wrappers which don't need to include anything of your
application.
My solution would be "don't include <windows.h> unless it's absolutely necessary". In general, you want to isolate the system dependencies to a small set of code anyway, so including <windows.h> in files willy-nilly is a bad idea.
When building a growing library of classes/functions, I've commonly seen a sort of "umbrella" header file that #includes all the common header files of a project. For example:
dsp.h
#include "file1.h"
#include "file2.h"
...
#include "filex.h"
Sometimes I might need everything, but other times maybe only a selection of features/options. If #include dsp.h, but don't use anything from file2.h for example, does the compiler know? Is it possible for it to optimize it out in the build?
Otherwise, my solution is to wrap optional code inside preprocessor directives and then define what I need. Perhaps this is a safer, more efficient solution?
Are you talking about code optimization or optimization of build time?
Unnecessary, unused headers will not change the code that is being generated, so there is no question of optimization here.
However, it will increase build time. This is not optimized by build tools. If you are looking to optimize build time, look at the book Large Scale C++ Software Design by John Lakos.
The preprocessor doesn't do any optimization. It doesn't know anything about the semantics of your code and thus cannot tell whether you're using anything from a header file or not. So no, #include statements are not optimized out.
Since the preprocessor is a separate program (and language) from the C++ compiler, there's no way for the preprocessor to know what is used. So the compiler will receive everything that was in the header file.
The include files are are read, and are inserted part of the source code before the compiler really starts generating code.
Yes. As a general rule, things that are not referenced by the program are not put into the final executable. It is ok to think of that as being an optimization. The details will differ depending on the compiler and linker.
All applicants to our company must pass a simple quiz using C as part of early screening process.
It consists of a C source file that must be modified to provide the desired functionality. We clearly state that we will attempt to compile the file as-is, with no changes.
Almost all applicants user "strlen" but half of them do not include "string.h", so it does not compile until I include it.
Are they just lazy or are there compilers that do not require you to include standard library files, such as "string.h"?
GCC will happily compile the following code as is:
main()
{
printf("%u\n",strlen("Hello world"));
}
It will complain about incompatible implicit declaration of built-in function ‘printf’ and strlen(), but it will still produce an executable.
If you compile with -Werror it won't compile.
I'm pretty sure it's non-conformant for a compiler to include headers that aren't asked for. The reason for this is that the C standard says that various names are reserved, if the relevant header is included. I think this implies they aren't reserved if they aren't included, since compilers aren't allowed to reserve names the standard doesn't say are reserved (unless of course they include a non-standard header which happens to be provided by the compiler, and is documented elsewhere to reserve extra names. Which is what happens when you use POSIX).
This doesn't fully answer your question - there do exist non-conformant compilers. As for your applicants, maybe they're just used to including "windows.h", and so have never thought before about what header strlen might be defined in by the C standard. I assume without testing that MSVC does in principle require you to include "string.h". But since "windows.h" does that for you, for the vast majority of practical Windows programs you don't need to know that you have to include "string.h".
They might be lazy, but you can't tell. Standard library implementations (as opposed to compilers, though of course each compiler usually has "its own" stdlib impl.) are allowed to include other headers. For example, #include <stdlib.h> could include every other library described in the standard. (I'm talking in the context of "C/C++", not strictly C.)
As a result, programmers get accustomed to such things, even if not strictly guaranteed, and it's easy to forget whether some function comes from a general catch-all like stdlib.h or something else—many people forget that memcpy is from string.h too.
If they do not include any headers, I would count them as wrong. If you don't allow them to test it with a particular implementation, however, it's hard to say they're wrong. And if you don't provide them with man pages (which represent the resources they'll need to know how to use on the job), then you're wrong.
At that point, you can certainly say the don't follow the exact letter of the standard; but do you want coders that get things done and know how to fix problems when they see them, or coders that worry about minutiea that won't matter?
If you provide a C file to start working with, make it have all the headers that could be needed from the beginning and ask the applicants to remove the unused ones.
The most common engineering experience is to add (or delete) a few lines of code to/from an application with thousands of lines already working correctly. It would be extremely rare in such a case to need another header file when adding a call to printf() or strlen().
It would be interesting to look over the shoulder of experienced engineers—not just graduated from school, but with extensive experience in the trenches—to see if they simply add strlen() and try compiling, or if they check to see if stdlib.h or string.h is already included before compiling. I bet the overwhelming majority do the former.
C implementations usually still allow implicit function declarations.
Anyway, I wouldn't consider all the boilerplate a required part of an interview, unless you specifically ask for it (e.g. "please don't omit anything you'd normally have in a source file").
(And with Visual Assist's "add ... include" I know less and less where they comde from ;))
Most compilers provide some kind of option to force headers inclusion.
Eg. the GCC compiler has the -include option which is the equivalent of #include preprocessor directive.
TCC will also happily compile a file such as the accepted answer's example:
int main()
{
printf("%u\n", strlen("hello world"));
}
without any warnings (unless you pass -Wall); as an added bonus, you can just call tcc -run file.c to execute file.c without compiling to an output file first.
In C89 (the most commonly applied standard), a function that is not declared will be assumed to return an int and have unknown arguments, and will compile (probably with warnings). If it does not, teh compiler is not compliant. If on the other hand you compiled the code as C++ it will fail, andf must do so if the C++ compiler is compliant.
Why not simply specify in the question that all necessary headers must be included (and perhaps irrelevant ones omitted).
Alternatively, sit the candidates at a machine with a compiler and have them check their own code, and state that the code must compile at the maximum warning level, without warnings.
I'm doing C/C++ for 20 years (even taught classes) and I guess there's a 50% probability that I'd forget the include too (99% of the time when I code, the include is already there somewhere). I know this isn't exactly answering your question, but if someone knows strlen() they will know within seconds what to do with that specific compiler error, so from a job qualification standpoint the slip is practically irrelevant.
Rather than putting emphasis on stuff like that, checking for the subtleties that require real understanding of the language should be far more relevant, i.e. buffer overruns, strncpy not appending a final \0 when hitting the limits, asking someone to make a safe (truncating) copy to a buffer of limited length, etc. Especially in C/C++ programming, the errors that do not generate a compiler error are the ones which will cause you/your company the real trouble.
I have inherited C/C++ code base, and in a number of .cpp files the #include directives are wrapped in #ifndef's with the headers internal single include #define.
for example
#ifndef _INC_WINDOWS
#include <windows.h>
#endif
and windows.h looks like
#ifndef _INC_WINDOWS
#define _INC_WINDOWS
...header file stuff....
#endif // _INC_WINDOWS
I assume this was done to speed up the compile/preprocess of the code.
I think it's ugly and a premature optimisation, but as the project has a 5 minute build time from clean, I don't want to makes things worse.
So does the practice add any value or speed things up lots? Is it OK to clean them up?
Update: compiler is MSVC (VS2005) and platform is Win32/WinCE
It's worth knowing that some implementations have #pragma once and/or a header-include-guard detection optimisation, and that in both cases the preprocessor will automatically skip opening, reading, or processing a header file which it has included before.
So on those compilers, including MSVC and GCC, this "optimisation" is pointless, and it should be the header files responsibility to handle multiple inclusion. However, it's possible that this is an optimisation for compilers where #include is very inefficient. Is the code pathologically portable, and <windows.h> refers not to the well-known Win32 header file, but to some user-defined header file of the same name?
It's also possible that the header files don't have multiple-include guards, and that this check is actually essential. In which case I'd suggest changing the headers. The whole point of headers is as a substitute for copy-and-pasting code about the place: it shouldn't take three lines to include a header.
Edit:
Since you say you only care about MSVC, I would either:
do a mass edit, time the build just to make sure the previous programmer doesn't know something I don't. Maybe add #pragma once if it helps. Use precompiled headers if all this really is slowing things down.
Ignore it, but don't use the guards for new files or for new #includes added to old files.
Depending on whether I had more important things to worry about. This is a classic Friday-afternoon job, I wouldn't spend potentially-productive time on it ;-)
If a file is included, then that whole file has to be read, and even the overhead of opening/closing the file might be significant. By putting the guarding directives around the include statement, it never has to be opened. As always with these questions, the correct answer is: try taking out the ifndef/endif guards around the include directives and get your stopwatch...
Hard to come up with a proper title for this problem. Anyway...
I'm currently working on a GUI for my games in SDL. I've finished the software drawing and was on my way to start on the OpenGL part of it when a weird error came up. I included the "SDL/SDL_opengl.h" header and compile. It throws "error C2039: 'DrawTextW' : is not a member of 'GameLib::FontHandler'", which is a simple enough error, but I don't have anything called DrawTextW, only FontHandler::DrawText. I search for DrawTextW and find it in a #define call in the header "WinUser.h"!
//WinUser.h
#define DrawText DrawTextW
Apparently it replaces my DrawText with DrawTextW! How can I stop it from spilling over into my code like that?
It's a minor thing changing my own function's name, but naming conflicts like this seem pretty dangerous and I would really like to know how to avoid them all together.
Cheers!
You have a couple of options, all of which suck.
Add #undef DrawText in your own code
Don't include windows.h. If another library includes it for you, don't include that directly. Instead, include it in a separate .cpp file, which can then expose your own wrapper functions in its header.
Rename your own DrawText.
When possible, I usually go for the middle option. windows.h behaves badly in countless other ways (for example, it doesn't actually compile unless you enable Microsoft's proprietary C++ extensions), so I simply avoid it like the plague. It doesn't get included in my files if I can help it. Instead, I write a separate .cpp file to contain it and expose the functionality I need.
Also, feel free to submit it as a bug and/or feedback on connect.microsoft.com. Windows.h is a criminally badly designed header, and if people draw Microsoft's attention to it, there's a (slim) chance that they might one day fix it.
The good news is that windows.h is the only header that behaves this badly. Other headers generally try to prefix their macros with some library-specific name to avoid name collisions, they try to avoid creating macros for common names, and they try avoid using more macros than necessary.
It's an unfortunate side effect of #includeing <windows.h>. Assuming you're not actually using Windows' DrawText() anywhere in your program, it's perfectly safe to #undef it immediately after:
// wherever you #include <windows.h>, or any other windows header
#include <windows.h>
#undef DrawText
There is no general way of avoiding this problem - once you #include a header file using the preprocessor it can redefine any name it likes, and there is nothing you can do about it. You can #undef the name, but that assumes you know the name was #defined in the first place.
Just #undef the symbols you don't want. But Make sure that you include windows.h and do this before you include SDL:
#include <windows.h>
#undef DrawText
#include <SDL/SDL_opengl.h>