How can I get the compiler tell me what file #define a value? - c++

My code is linking against several other libraries that are also developed at my company, one of these libraries is redefining several values from errno.h, I would like to be able to fix this, however I am having trouble finding the exact file that is redefining these values, I am want to know if there is a way to make the compiler tell me when a file has defined a particular value.

You can probably do it by adding -include errno.h to the command line that builds the library in question. Here's a quick example. I have a C program called "file.c":
#define ESRCH 8
That's it - then I compile with:
cc -c -include errno.h file.c
And presto, a compiler warning:
file.c:1:1: warning: "ESRCH" redefined
In file included from /usr/include/errno.h:23,
from <command-line>:0:
/usr/include/sys/errno.h:84:1: warning: this is the location of the previous definition
That will tell you where your bad definitions are.

Have you tried searching with grep?

If you don't want to search through all your headers for the particular #define, you could use
#undef YOUR_MANIFEST_CONSTANT
after each #include in your source module and then start removing them from the bottom up and see where your definitions come from.
Also, your compiler may tell you that a #define has been redefined. Turn all your warnings on.

With GCC I did something similar with:
g++ input.cc -dD -E > cpp.out
-dD tells cpp to print all defines where they were defined. And in the cpp output there are also markers for the include file names and the line numbers.

It is possible that some environments, I'm thinking IDE's here, have configuration options tied into the "project settings" rather than using a configuration header. If you work with a lot of other developers in a place where this behavior is NOT frowned on then you might also check your tool settings.
Most compilers will tell you where the problem is, you have to look and think about what the diagnostic notification is telling you.
Short of that, grep/findstr on *nix/Windows is your friend.
If that yields nothing then check for tool settings in your build system.

Some IDE's will jump to the correct location if you right click on the usage and select 'go to definition'.
Another option if you're really stuck is a command line option on the compiler. Most compilers have an option to output the assembler they generate when compiling C++ code.
You can view this assembler (which has comments letting you know the relative line number in the C++ source file). You don't have to understand the assembler but you can see what value was used and what files and definitions were included when the compiler ran. Check your compiler's documentation for the exact option to use

Related

How to find the library path that clang uses [duplicate]

How can I tell where g++ was able to find an include file? Basically if I
#include <foo.h>
g++ will scan the search path, using any include options to add or alter the path. But, at the end of days, is there a way I can tell the absolute path of foo.h that g++ chose to compile? Especially relevant if there is more than one foo.h in the myriad of search paths.
Short of a way of accomplishing that... is there a way to get g++ to tell me what its final search path is after including defaults and all include options?
g++ -H ...
will also print the full path of include files in a format which shows which header includes which
This will give make dependencies which list absolute paths of include files:
gcc -M showtime.c
If you don't want the system includes (i.e. #include <something.h>) then use:
gcc -MM showtime.c
Sure use
g++ -E -dI ... (whatever the original command arguments were)
If your build process is very complicated...
constexpr static auto iWillBreak =
#include "where/the/heck/is/this/file.h"
This will (almost certainly) cause a compilation error near the top of the file in question. That should show you a compiler error with the path the compiler sees.
Obviously this is worse than the other answers, but sometimes this kind of hack is useful.
If you use -MM or one of the related options (-M, etc), you get just the list of headers that are included without having all the other preprocessor output (which you seem to get with the suggested g++ -E -dI solution).
For MSVC you can use the /showInclude option, which will display the files that are included.
(This was stated in a comment of Michael Burr on this answer but I wanted to make it more visible and therefore added it as a separate answer.)
Usability note: The compiler will emit this information to the standard error output which seems to be suppressed by default when using the windows command prompt. Use 2>&1 to redirect stderr to stdout to see it nonetheless.

How can I ensure no code uses an API?

I want to ban use of iostreams in a code base I have (for various reasons). Is there a way I can inspect symbol files or force the compiler to emit an error when that API is used?
A simple approach is provide a dummy iostream implementation that does nothing but throw a compile-time error.
The following example assumes a GCC toolchain - I imagine the process is similar with other compilers.
First, create your dummy iostream file:
#error 'Use of iostream is prohibited'
Some dummy application code to demonstrate:
#include <iostream>
int main (int argc, char** argv) {
std::cout << "foo!";
return 0;
}
Compile as follows (assuming the dummy iostream and main.cpp are in the working directory):
g++ -I. main.cpp
Compilation fails with the following errors:
In file included from main.cpp:2:0:
./iostream:1:2: error: #error 'Use of iostream is prohibited'
main.cpp: In function 'int main(int, char**)':
main.cpp:4:2: error: 'cout' is not a member of 'std'
Added bonus: symbols usually declared in that file (e.g. cout here) are undefined, and so get flagged in the compiler output as well. As such, you also get pointers to exactly where you're using your prohibited API.
UPDATE: Instructions for Visual C++ 2012.
As #RaymondChen points out in the comments below, a solution tailored to Visual C++ is likely more useful to the OP. As such, the following outlines the process I went through to achieve the same as the above under Visual C++ 2012.
First, create a new console project, using the above C++ code. Also create the dummy iostream header I described above, and place it in a directory somewhere easy to find (I put mine in the main project source directory).
Now, in the Solution Explorer, right click on the project node and select "Properties" from the drop-down list. In the dialog that appears, select "VC++ Directories" from the tree on the left. Prepend the directory containing the dummy iostream file into the list of include directories that appears on the right, separated from the other directories with a semicolon:
Here, my project was called TestApp1, and I just prepended its main directory to the $(IncludePath) that was already there. Note that it is important to prepend rather than append - the order of the directories in the list determines the search order, so if $(IncludePath) appears before your custom directory, the system header will be used in preference to your dummy header - not what you want.
Click OK, and rebuild the project.
For me, doing so resulted in the following errors in the VC++ console (edited slightly for brevity):
error C1189: #error : 'Use of iostream is prohibited'
IntelliSense: #error directive: 'Use of iostream is prohibited'
IntelliSense: namespace "std" has no member "cout"
Note that IntelliSense also picks up the (now) illegal use of cout - it is highlighted with an error mark in the editor.
This is a nasty hack, but it should work.
The C standard (and consequently the C++ standard as well) allows preprocessor tokens in #include directives. This is also known as "computed includes".
Thus, adding something like -Diostream to CFLAGS inside your makefile (or to compiler options in your IDE's project settings) should reliably break the build if someone tries to use iostream.
Of course, with an empty macro, the error message will not be very informative, but you could instead use something like -Diostream=DUDE_DONT_USE_IOSTREAM, which will show an error like: DUDE_DONT_USE_IOSTREAM: file not found.
It's also something that you can turn off again without much hassle if you change your mind later. Just remove the build option.
Your idea to inspect symbol files is feasible and very realistic. virtual ~ios_base(); is a single method that all streams will inherit, and which can't easily be inlined since it's virtual and non-trivial. Its presence in an object file is therefore a very strong indication of IOstream use.
In addition to compiler-assist method mentioned by Mac you can use generic search functions. For example (I assume zsh shell - for bash doesn't have ** and on Windows you need to find how to do it with Powershell):
# Find all mentioning on `iostream` `cin` in all files ending in cc in all subdirectories of current directory
grep iostream **/*.c
grep cin **/*.cc
If you don't want to/can't use command line you can use your favourite editor and search for unwanted symbols.
I usually combine both methods:
Compilation, especially of large project with large number of templates, is slow while searching is fast so you're more productive with search
On the other hand search operates is not exact and might miss something. So I'd use header tricks to verify solution done in previous step
As final verification you can search for symbols after compilation. It is especially useful if you compile with no optimization. You can use objdump or similar (depending on platform) and watch for imported symbol (this works if you don't say link statically to something using iostreams).
No, not at all. For a very limited subset, you could provide your own definitions, causing the linker to error at the duplicates. This would be very undefined behaviour though. And a good portion is templates that aren't susceptible to this. Without doing drastic things like deleting the iostream header, or using a compiler like Clang and modifying the source code, there's really nothing you can do.

Why is Xcode 4.2 applying C files build rule script for .cpp files?

I have an Xcode 4.2 project which includes a target that cross-compiles for windows. I use custom build rules for C source files and C++ source files in that target, invoking i386-pc-mingw32-g++ via a custom script. For some reason, Xcode runs the custom script I have specified as being for C source files, even when compiling files with a .cpp extension. Why might this be? How can I get Xcode 4.2 to run the "C++ source files" script for my .cpp files?
I also have .c files in this project, and am hoping to use -std=c++11 flag when compiling c++ files to enable some c++11 features. If I compile the .c files with this flag, I end up with weird scoping issues on constants included from math.h that I have yet to really try and understand - I am hoping I can just get Xcode to run the correct script for my .cpp files.
Any ideas?
Update: I've been able to get Xcode to run the correct scripts. To do this, I had to change the Process drop-down menu selections from "C source files" and "C++ source files" both to "Source files with names matching:" and then manually enter *.c and *.cpp in the provided text field. Now I have to figure out why I'm getting an M_PI was not declared in this scope error message where I wasn't before - maybe a different version of math.h is being used with the -std=c++11 flag which either doesn't include the M_PI constant or provides it under a different namespace?
Update: Continuing to work on this - it appears the M_PI value I was using from math.h is actually a macro which is only #define'd if __STRICT_ANSI__ has not been defined. Apparently switching to c++11 by using the -std=c++11 compiler flag has caused this __STRICT_ANSI__ macro to be defined, and thus the M_PI macro I was previously using isn't there. I suppose it's better to just define my own pi constants than to mess with the declaration of this __STRICT_ANSI__ macro, but I'll probably dig into that a bit just to clarify why it is being declared now that I'm using the c++11 flag.
Update: I found this post How can I make C++0x and __STRICT_ANSI__ get along?, which just suggests undefining the 'STRICT_ANSI' macro right after the '-std=c++11' flag (or rather, the equivalent '-std=c++0x' flag. While this seems sketchy, no one has posted encountering any problems because of it and it appears to work just fine for me as well in this case. Gcc documentation on this macro is located here: http://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html, with the following relevant statement:
The macro STRICT_ANSI is predefined when the -ansi option is used. Some header files may notice this macro and refrain from declaring certain functions or defining certain macros that the ISO standard doesn't call for; this is to avoid interfering with any programs that might use these names for other things.
Still not sure why the '-std=c++11' flag causes this to be defined when it isn't by default (which would be '-std=c++98', apparently).
If you want C++11 support without ANSI mode, use -std=gnu++11 instead of std=c++11.

How to tell where a header file is included from?

How can I tell where g++ was able to find an include file? Basically if I
#include <foo.h>
g++ will scan the search path, using any include options to add or alter the path. But, at the end of days, is there a way I can tell the absolute path of foo.h that g++ chose to compile? Especially relevant if there is more than one foo.h in the myriad of search paths.
Short of a way of accomplishing that... is there a way to get g++ to tell me what its final search path is after including defaults and all include options?
g++ -H ...
will also print the full path of include files in a format which shows which header includes which
This will give make dependencies which list absolute paths of include files:
gcc -M showtime.c
If you don't want the system includes (i.e. #include <something.h>) then use:
gcc -MM showtime.c
Sure use
g++ -E -dI ... (whatever the original command arguments were)
If your build process is very complicated...
constexpr static auto iWillBreak =
#include "where/the/heck/is/this/file.h"
This will (almost certainly) cause a compilation error near the top of the file in question. That should show you a compiler error with the path the compiler sees.
Obviously this is worse than the other answers, but sometimes this kind of hack is useful.
If you use -MM or one of the related options (-M, etc), you get just the list of headers that are included without having all the other preprocessor output (which you seem to get with the suggested g++ -E -dI solution).
For MSVC you can use the /showInclude option, which will display the files that are included.
(This was stated in a comment of Michael Burr on this answer but I wanted to make it more visible and therefore added it as a separate answer.)
Usability note: The compiler will emit this information to the standard error output which seems to be suppressed by default when using the windows command prompt. Use 2>&1 to redirect stderr to stdout to see it nonetheless.

Is there a good general method for debugging C++ macros?

In general, I occasionally have a chain of nested macros with a few preprocessor conditional elements in their definitions. These can be painful to debug since it's hard to directly see the actual code being executed.
A while ago I vaguely remember finding a compiler (gcc) flag to expand them, but I had trouble getting this to work in practice.
gcc -E will output the preprocessed source to stdout.
For MSVC users, you can right-click on the file/project, view the settings and change the file properties to output preprocessed source (which typically in the obj directory).
This might not be applicable in your situation, but macros really do hamper debugging and often are overused and avoidable.
Can you replace them with inline functions or otherwise get rid of them all together?
You should probably start moving away form Macros and start using inline and templates.
Macros are an old tool, the right tool sometimes. As a last resort remember printf is your friend (and actually printf isn't that bad a friend when your doing multithreaded stuff)
Debug the dissasembly with the symbols loaded.
gcc -save-temps
will write out a .i (or .ii file for C++) which is the output of the C preprocessor, before it gets handed to the compiler. This can often be enlightening.
GCC and compatible compilers use the -E option to output the preprocessed source to standard out.
gcc -E foo.cpp
Sun Studio also supports this flag:
CC -E foo.cpp
But even better is -xdumpmacros. You can find more information in Suns' docs.