Does anyone know if it is possible to enable any kind of logging on any C++
compliant compiler (Visual Studios, g++ etc) so that I can discover when temporary objects are created?
For example:
Let's say I have a function f(char x) but I call this with f(46)
I will see in the logs -
temporary char created promoting int # function param f(46) (or something like this)
I have read through the VS compiler switch options and it appears that this is not
an option.
I understand that in the new standard there is the concept of an rvalue reference (&&) which could be used to detect most temporaries for the move semantics but this involves adding new code / compliant compiler.
So can this be done? Or is this privileged knowledge of the compiler?
What would be more useful would be inline annotations in the IDE (since I assume you want to optimise by minimising some of these temps?). In practice the easiest way would be to modify GCC or g++ and make them talk to a Visual Studio plugin or something. They could annotate with the register allocation and everything. Wow, that would actually be really helpful.
Barring an effort like that, and I don't know of any, the best way is to just learn to read the assembly. In Visual Studio you can have the compiled assembly appear inline with the source which is super useful.
Related
I would like advice how to proceed in such situation.
Imagine I have large C++ project which works well.
I have suspicion there might be some UB in this code (because in different project written by same author I found UB).
Now, say I need to add new features to this project.
I am afraid because:
if I recompile with new compiler this can increase risk of UB happening if in the code is UB already. (e.g. new compiler might not be OK with UB which the old compiler was fine with).
Is it realistic to eliminate all UB in this large project by eye inspection (before I move to adding new feature)??
If not, then I should at least compile with same version of compiler right? (to decrease chance of problems if there is UB).
Project is done in Visual Studio so I don't know if there are object files, in which case, I could leave object files same and only modify parts in files where I need to add something - thus again minimizing risk of UB.
What is the course of action in such situation? I think this could be pretty common scenario.
I like suggestion that I test the project using new compiler before adding new code, but even then - we know testing might not reveal UB, isn't it?
In order, I would:
Compile with -Wall (/W4 for you Windows folk) and fix errors.
Write tests if there aren't any already.
Use tools like valgrind to detect issues and fix them.
Study synchronization primitives if in use, and use modern paradigms where possible.
Document the code and adhere to a style guide.
I would not attempt to avoid problems by keeping object files around. That's a nightmarish maintenance problem.
Undefined Behavior = Bugs
It's impossible to prove that a project is bug-free. Even the best programmers do create bugs. Even the best code-review cannot eliminate all bugs in a project. No, it's not realistic to eliminate all UB in a project of some size by code inspection or by any other means. Your best option is to review the code and eliminate as many as possible.
Change your perception of UB (bugs): If you encounter a bug during your re-engineering efforts, it's a good thing! You are in the best position to remove one UB.
Don't keep the old compiler just because you are afraid of UB. Recompile the project with the latest and best compiler available. Compilers can also have bugs. Newer compilers will produce better, more robust code. Newer compilers will produce better warnings. Use all warnings possible -Wall.
Eliminate all the warnings that the compiler produces. Every single warning is there for a reason, it highlights a problem. The likelihood of a "false positive" is quite dim nowadays. This is even true for MSVC (I'm not talking about real old compilers like before VC 2005)
Use a static code checker (Cppcheck). It can point you to common problems with the code.
Use a custom rule set for your code checker. It will help you to get the code up to some standard.
If possible, compile the project with another compiler (GCC, Clang) just for the sake of getting the warnings of these compilers.
Don't link against old object files. This will create more problems than what you think it avoids
As others said: First and foremost, try to find the errors, not hide them.
The first and simplest measure is to set the warning level to /W4 (you can try Wall, but due to the large amount of noise this will produce (e.g. from standard headerfiles), it is usually only of help if you know you have an error in a certain part of your code)
Use static analyzers - you can start with the builtin Code Analysis tool and then go for external tools (which are usually much more difficult to set up correctly for a non-trivial project).
Write lots of tests and make sure, you are exercising edge cases - thats where UB usually lurks.
If possible, try to compile the project (or parts of it) under clang and activate the different sanitizers (in particular there is UndefinedBehaviorSanitizer) which will further instrument your code to check for UB (only helpfull if you have tests to exercise that UB though)
Test your code at different optimization levels and combination of flags (in VS, especially _ITERATOR_DEBUG_LEVEL can be helpfull to find out-of-bounds errors)
I'd say any non-trivial code base potentially contains undefined behavior. What is special about that particular Programmer? If he/she is prone to a special kind of UB, then you can focus your efforts on this.
I encountered this issue a dozen, if not a million times already: I compile a c++ program on visual studio and get a dozen, if not a million warnings and/or errors suggesting that I am doing something very dangerous and that there is no way my compiler will let me do that. the warnings/errors tell me that I am using a deprecated function and that I should consider using some other safer function that may or may not do the same thing as this one, but I have no idea what this one does in the first place since I did not write it.
After some research (I do it everytime, I am not a quick learner) I find out I am not the first one facing this particular problem, and I can coerce my compiler to work with this program with the proper macro definition (for the future readers who don't care about my question but want to compile their program, you have to define _CRT_SECURE_NO_DEPRECATE, don't you ever dare following visual studio's advice and using the allegedly safe function).
I have often read in the manual or on this very website, along with the answer, the fact that I should not do that if I don't know precisely what I am doing.
I must confess: I have no idea what I am doing, and I would be very grateful if someone would accept to explain it to me.
So here are my questions:
What are those functions that are unsafe? Why do they exist in the first place?
What is unsafe about them?
Why are they so often found in perfectly honourable libraries?
I have come to the understanding that there is no safe and portable alternative to those functions: why is it so? How about we have some people think about it and try to define a way to do it, and everyone would accept to do it that way, and we would call it standard maybe?
To tackle your questions in order:
They exist in the first place because the standard wrote them in such a way. Standards authors are human so don't think of everything and this left some security weaknesses in the C API. You can find a list of these deprecated functions at http://msdn.microsoft.com/en-us/library/ms235384.aspx.
Many of the functions are unsafe as they allow such things as buffer overruns to occur but other security vulnerabilities may be exposed depending on the function.
Honourable libraries generally try for some cross platform compatibility so I suspect will try to stick to stand C rather than using compiler specific functions and extensions.
The "perfect" standard will probably never exist as in my first point :) Some of the C API problems can be avoided using C++ but that's a big hammer to crack a small nut and brings security vulnerabilities of its own.
When porting my project to linux using gcc, I've come across quite a few errors that are a result of VS trying to be "convenient" such as using standard functions like "memcpy" and the "str*" functions without needing to include the right headers, or the std::exception::exception overload that takes a const char*. Is there anyway to force VS to not do this along with other non-standard behaviors?
In a word, no. MS has "extensions" like const char * for std::exception.
You could try setting up a "sanity" build, on say a continuous integration machine to build with another compiler to check.
Do try having the warning level turned all the way up. This may catch one or two things.
I have to import and work with a C++ Project. However, I canĀ“t get it to run without Microsoft Visual Studio. The Author of the project told me, I have to use a Microsoft Compiler, because only this one can handle particular notations he used (e.g. creating Objects on the fly while passing it to a method). See example.
lights.push_back(Light(Vector(dirx,diry,dirz).normalize(), Color(colr, colg, colb)));
I had to create an vector object before and pass it to the method.
Can anyone tell me which compiler I can use?
I dont have enough bit flow to download 3 gb Visual Studio.
Great but not necessary would be a compiler that I can use on Mac OS.
cheers.
Any C++ compiler can 'create objects on the fly while passing it to a function' (these are often known as temporary objects or rvalues).
What Visual C++ can do that other C++ compilers generally can't is pass those temporary objects to functions through parameters that are non-const references. The C++ standard specifically forbids that behavior, but MSVC allows it (Microsoft calls it an extension).
I'm guessing that that is the behavior the Author of the project is depending on.
If you are working on Mac OS, then the default compiler is (for recent version) Clang (based on LLVM).
And you are lucky in that Clang has a compatibility mode for parsing MSVC code that is normally quite advanced. The current top of the tree version is able to parse near every MFC generated header for example.
You can activate this mode using -fms-extensions.
Is there a way to identify unused attributes/methods in Visual C++ 2008 Professional? If it's not possible by default, recommendations of 3rd-party tools are also much appreciated.
Thanks,
Florian
Edit: nDepend only works for .NET assemblies. I'm looking for something that can be used with native C++ applications.
Try PC-Lint. It's pretty good at finding redundant code.
I haven't tried version 9 yet. Version 8 does take some time to configure.
Try the online interactive demo.
I have not personally used their productivity tools (I use their windows control suit), but it looks like DevExpress has a C++ refactor'er called Refactor! for C++. I didn't immediately spot the features that you are looking for, but maybe they have it?
Coverage Validator can show unused C++ code (but not attributes). It does it dynamically so you have to 'exersize' the app to get the results:
http://successfulsoftware.net/2008/03/10/coverage-validator/
The tricky bit is that many functions in C++ have to exist, even if they are not called.
Boost especially will cause this, but even the regular STL code can do this. And your code has to play along. You might define a copy ctor because std::vector formally requires it. But if you don't instantiate any std::vector member that actually does copy a T, your copy ctor will remain unused.
Even if they don't have to, they often exist for safety. For example, declaring a private copy constructor can prevent an object from unintended copying. Without the private declaration, the compiler would define a public, memberwise copy ctor for you. Now, is this "unused" and do you want to be warned about them?
PC-Lint is very powerful, but hard to lean. Of course that pretty well describes C and C++ doesn't it?
Another tool I think is excellent is Whole Tomato's Visual Assist X which integrates right into the IDE.
There are some big gotchas in C++ when searching for unreferenced code: templates, callbacks, and message handlers may be critical to your project but are never directly called. For example the handler for a thread is not called directly, but is a parameter when you create a new thread. The "On_buttonpress" type messages in MFC or WTL projects will also show up as un-called methods.
Once you find them you can configure PC-Lint to ignore these, but the first time through its a lot of work.
nDepend will do it, along with cleaning your house and taking the dog for a walk. There's a nagware version available for free.
The following code query language statement will get you a list of unused methods
WARN IF Count > 0 IN SELECT TOP 10 METHODS WHERE MethodCa == 0 AND
!IsPublic AND !IsEntryPoint AND !IsExplicitInterfaceImpl AND
!IsClassConstructor AND !IsFinalizer