False positive Error 503 for call to template function - c++

I have some code that PC-Lint is giving me Error 503: Boolean argument to relational on. It is a call to a template function which is defined like this:
template <typename ITypeToUse>
void ShowWindowEx(
HWND hWnd,
int nCmdShow,
ITypeToUse *pControl);
The call itself looks like this:
ShowWindowEx<IActualType>(this->GetWndHandle(), SW_SHOW, m_spControl);
Appearantly, the part ShowWindowEx<IActualType>(...) is interpreted as Identifier1 < Identifier2 > Expression... PC-Lint seems not to be aware that ShowWindowEx is a template function which requires a type in angled brackets and tries its best to interpret it as a boolean expression.
I am aware that I can simply tell lint to ignore this error for this line (though in reality it's about 30 lines), but I'd like to prevent this from happening again. Also, as far as I know, PC-Lint should be capable of handling template function calls, any idea why this is not the case here?
The declaration is inside a class in a header and the call is in another member function of that class, which is declared right before ShowWindowEx is. The implementation of both member functions happens in the .cpp file in the same order, so the call to ShowWindowEx happens before its implementation. Is it possible PC-Lint just ignored the header?
EDIT:
I now changed the function prototype to:
template <typename IPointerToUse>
void ShowWindowEx(
HWND hWnd,
int nCmdShow,
IPointerToUse pControl);
So the template will take care of the type being a pointer. Thanks DeadMG for the suggestion. Question still stands, as I see no reason the above should not have worked, but it works this way as well.

503 normally is a C warning, not C++. Can it be that your C++ file containing the template function call is considered a C file by Lint, maybe by using *.C (capital letter) on a Windows machine? or using a non-standard extension?
I've seen this happen when using Samba to Lint a Unix C++ program on a Windows PC Lint installation.
If this is still an issue, look at the output lines indicating the module names like --- Module: ..., and look at the file type between parentheses. If switched off, you may need to use -vm (default).
If this is the case, I would expect many more warnings around the call, but interpreting the template <...> as two comparison operators would legitimately provoke this warning.
Other than that, the line you presented - without context - does not give any reason why 503 could be applicable here.

Perhaps the reason is that there is already a definition of ShowWindowEx (one that is no template definition) in the Windows headers.
Perhaps you should try to rename your function.

Related

Removal of unused or redundant code [duplicate]

This question already has answers here:
Listing Unused Symbols
(2 answers)
Closed 7 years ago.
How do I detect function definitions which are never getting called and delete them from the file and then save it?
Suppose I have only 1 CPP file as of now, which has a main() function and many other function definitions (function definition can also be inside main() ). If I were to write a program to parse this CPP file and check whether a function is getting called or not and delete if it is not getting called then what is(are) the way(s) to do it?
There are few ways that come to mind:
I would find out line numbers of beginning and end of main(). I can do it by maintaining a stack of opening and closing braces { and }.
Anything after main would be function definition. Then I can parse for function definitions. To do this I can parse it the following way:
< string >< open paren >< comma separated string(s) for arguments >< closing paren >
Once I have all the names of such functions as described in (2), I can make a map with its names as key and value as a bool, indicating whether a function is getting called once or not.
Finally parse the file once again to check for any calls for functions with their name as in this map. The function call can be from within main or from some other function. The value for the key (i.e. the function name) could be flagged according to whether a function is getting called or not.
I feel I have complicated my logic and it could be done in a smarter way. With the above logic it would be hard to find all the corner cases (there would be many). Also, there could be function pointers to make parsing logic difficult. If that's not enough, the function pointers could be typedefed too.
How do I go about designing my program? Are a map (to maintain filenames) and stack (to maintain braces) the right data structures or is there anything else more suitable to deal with it?
Note: I am not looking for any tool to do this. Nor do I want to use any library (if it exists to make things easy).
I think you should not try to build a C++ parser from scratch, becuse of other said in comments that is really hard. IMHO, you'd better start from CLang libraries, than can do the low-level parsing for you and work directly with the abstract syntax tree.
You could even use crange as an example of how to use them to produce a cross reference table.
Alternatively, you could directly use GNU global, because its gtags command directly generates definition and reference databases that you have to analyse.
IMHO those two ways would be simpler than creating a C++ parser from scratch.
The simplest approach for doing it yourself I can think of is:
Write a minimal parser that can identify functions. It just needs to detect the start and ending line of a function.
Programmatically comment out the first function, save to a temp file.
Try to compile the file by invoking the complier.
Check if there are compile errors, if yes, the function is called, if not, it is unused.
Continue with the next function.
This is a comment, rather than an answer, but I post it here because it's too long for a comment space.
There are lots of issues you should consider. First of all, you should not assume that main() is a first function in a source file.
Even if it is, there should be some functions header declarations before the main() so that the compiler can recognize their invocation in main.
Next, function's opening and closing brace needn't be in separate lines, they also needn't be the only characters in their lines. Generally, almost whole C++ code can be put in a single line!
Furthermore, functions can differ with parameters' types while having the same name (overloading), so you can't recognize which function is called if you don't parse the whole code down to the parameters' types. And even more: you will have to perform type lists matching with standard convertions/casts, possibly considering inline constructors calls. Of course you should not forget default parameters. Google for resolving overloaded function call, for example see an outline here
Additionally, there may be chains of unused functions. For example if a() calls b() and b() calls c() and d(), but a() itself is not called, then the whole four is unused, even though there exist 'calls' to b(), c() and d().
There is also a possibility that functions are called through a pointer, in which case you may be unable to find a call. Example:
int (*testfun)(int) = whattotest ? TestFun1 : TestFun2; // no call
int testResult = testfun(paramToTest); // unknown function called
Finally the code can be pretty obfuscated with #defineā€“s.
Conclusion: you'll probably have to write your own C++ compiler (except the machine code generator) to achieve your goal.
This is a very rough idea and I doubt it's very efficient but maybe it can help you get started. First traverse the file once, picking out any function names (I'm not entirely sure how you would do this). But once you have those names, traverse the file again, looking for the function name anywhere in the file, inside main and other functions too. If you find more than 1 instance it means that the function is being called and should be kept.

Please help me find the actual error in this jungle of compiler errors

I can't for the life of me figure out what the compiler wants from me.
Can anyone experienced with compiler messages help me decipher what it wants, please?
I can't even provide code bits because I've no idea whats going on.
I'm using g++-4.7 with -std=c++11
http://pastebin.com/AxYMd6L8
It seems it complains about SimpleMapSquare and something about it being an allocator?
It's nothing like that. SimpleMapSquare is defined as:
#pragma once
namespace BlackDragonEngine
{
struct SimpleMapSquare
{
int TileID;
};
}
I wrote about 400+ lines of templated code yesterday and just tried to include the header for it in my main app and boom this happens...
I don't even know where to start...please help.
EDIT:
A search for "vector<" in my project returns this: http://i.imgur.com/g8L1l.png
I expanded the revelant files (the ones I created yesterday)
The reason I wrote so much code without testing is because I'm converting my engine from C# to C++, so the logical side is already right and I can't test incomplete code.
EDIT 2:
Here are all usages of "SimpleMapSquare" http://i.imgur.com/zedkh.png
EDIT3:
Thanks to Konrad I was able to pinpoint the exact line and find the error... ignore the searches above as I forgot to include *.inl files (where the template code implementation is located)
You are using the following class somewhere:
class std::vector<sf::Vector2<int>, BlackDragonEngine::SimpleMapSquare>
The second type argument of std::vector is the allocator type!
Looks like SimpleMapSquare shold contain definition of types value_type, pointer and reference.
It is like the STL is treating SimpleMapSquare as an iterator, allocator or other traits requiring classes.
Did you pass it as a wrong parameter somewhere ?

Default template parameters?

I am currently trying to make an old project in C++ work with more recent tools: the project has been developped on Windows XP with VC71 and I am now trying to make it run on Windows 7 with VC100.
I didn't get any "big" problem yet but however I am having a last compilation issue which led me to some code - pretty obscure to me -.
Here is a sample of the macro (simplified) I am having trouble with:
#define IMPORT_STD_PAIR( _keyClass_ ,_objectClass_) \
extern template struct std::pair< _keyClass_,_objectClass_ >; \
...
The error is:
C2955: 'std::allocator' : use of class template requires template argument list.
I don't really get what it is supposed to do (the 2nd line), specify default parameters to a templated class ?
Thank you for your help.
Edit:
#Mark B: Thank you for you answer. You made me realize what was going on: Nothing.
In fact, it is my fault cause I am not familiar at all with developping on Windows. The code was originally:
#define IMPORT_STD_MAP( _import_directive_, _keyClass_ ,_objectClass_) \
extern template struct _import_directive_ std::pair<_keyClass_,_objectClass_>;
I neglected _import_directive_ cause it was almost "empty" in every case but one. So when it is empty, it simply creates an instance with no name which is not really relevant; but when this macro takes the value __declspec ( dllimport ) it makes much more sense :)
Thanks for helping me realizing that, I thought it was something more exotic, and thank you for the debugging advice which has been useful.
It looks like ListRemake is a templated class and you're trying to instantiate an instance as
ListRemake myList;
You need to specify the template arguments for ListRemake
ListRemake<int, long> myList;
It looks like it's attempting to instantiate a specific instantiation of std::pair. Without more context I can't see why this would be attempted, but you might try just making the macro define to nothing and see if the code compiles, links, and appears to work. They may have changed template compiling in 10.0.

(C++ and gcc) error: expected constructor, destructor, or type conversion before 'inline'

I have a header file with some inline template methods. I added a class declaration to it (just a couple of static methods...it's more of a namespace than a class), and I started getting this compilation error, in a file that uses that new class.
There are several other files that include the same .h file that still compile without complaint.
Googling for the error gives me a bunch of links to mailing lists about bugs on projects that have a similar error message (the only difference seeming to be what the constructor, destructor, or type conversion is supposed to precede).
I'm about ready to start stripping everything else away until I have a bare-bones minimal sample so I can ask the question intelligently, but I figured I'd take a stab at asking it the stupid way first:
Can anyone give me a basic clue about what this error message actually means so I might be able to begin to track it down/google it?
Just for the sake of completeness, the first example of where I'm seeing this looks more or less like
namespace Utilities
{
template <typename T> GLfloat inline NormalizeHorizontally(T x)
{
GLfloat scaledUp = x*2.0;
GLfloat result = scaledUp / Global::Geometry::ExpectedResolutionX;
return result;
}
}
It means that you put the "inline" keyword in the wrong place. It needs to go before the method's return type, e.g.
template <typename T> inline GLfloat NormalizeHorizontally(T x)
Simple as that.
The reason that you got this message on one compilation unit and not others may be because it is a templated function that was not being instantiated from those other compilation units.
Generally, if you get an "expected blah blah before foobar" error, this is a parsing error and it often indicates a simple syntax mistake such as a missing semicolon, missing brace, or misordered keywords. The problem is usually somewhere around the portion mentioned, but could actually be a while back, so sometimes you have to hunt for it.

VS2008 internal compiler error

I'm consistently running into an internal compiler error while attempting to switch from MSVC6 to MSVC 2008. After much work commenting out different parts of the program, I've traced the error to two lines of code in two different CPP files. Both of these CPP files compile successfully, yet somehow have an effect on whether or not the error manifests in other files.
Both of those lines involve instantianting several complex, nested templates. They also appear to be the only places in the app that use an abstract class as one of the template parameters. That said, I'm far from certain that the issue involves either abstract classes or templates, it's just the most obvious thing I've noticed. I can't even be sure that these lines are significant at all. Here's what they look like, though:
m_phDSAttributes = new SObjDict<RWCString, SIDataSource>(&RWCString::hash);
So we've got SObjDict, a templatized dictionary class, SIDataSource, an abstract interface, and the parameter is a pointer to a static member function of RWCString.
I've been playing around with the code some, and I can occasionally get the error to move from one CPP file to another (for instance, I changed a bunch of template declarations from using class to typename), but I can't find any rhyme or reason to it.
I'm at a loss as to how to debug this issue further. The exact error output by the compiler (with the name of my source file changed) is below. There is no mention of it anywhere on the internet. I'm pretty desperate for any advice on how to proceed. I don't expect someone to say "oh, you just need to do XYZ", but a pointer on how to debug this sort of issue would be greatly appreciated.
1>d:\Dev\webapi.cpp : fatal error C1001: An internal error has occurred in the compiler.
1>(compiler file 'f:\dd\vctools\compiler\utc\src\p2\p2symtab.c', line 5905)
The trick seems to be disabling precompiled headers. I have no idea why that solves the problem, and it's very unfortunate since my build time for the affected project has gone from less than 30 secs to nearly 5 minutes, but at least I can progress forward.
It's a reasonable bet to assume that p2symtab.c is (part of) the symbol table code. This would immediately explain how the upgrade caused it; this code has been rewritten. (Remember the 255 character length warnings of VC6?)
In this case, there is no new entry in the symbol table, so it's likely a lookup in the symbol table failing spectactularly. It would be interesting to see if the context in which th name lookup happens affects the result. For instance, what happens if you change the code to
typedef SObjDict<RWCString, SIDataSource> SObjDict_RWCString_SIDataSource;
m_phDSAttributes = new SObjDict_RWCString_SIDataSource(&RWCString::hash);
This will force another symbol table entry to be created, for SObjDict_RWCString_SIDataSource. This entry is sort of a symbolic link to the template instantiation. The new name can (and must) be looked up on its own.
Start breaking it down into smaller parts. My first guess is the pointer to the static function is going to be the problem. Can you make a dummy non-template class with the same parameter in the constructor? Does it compile if you don't use an abstract class in the template?
Looks like I'm sending you in the wrong direction, the following compiles fine in 2008:
class thing {
public:
static void hash( short sht ) {
}
void hash( long lng ) {
}
};
class thing2 {
public:
thing2( void (short ) ){}
};
int _tmain(int argc, _TCHAR* argv[])
{
thing2* t = new thing2( &thing::hash );
delete t;
return 0;
}
The principle remains though, remove/replace complex elements until you have code that compiles and you'll know what is causing the problem.
fatal error C1001: An internal error has occurred in the compiler.
1>(compiler file 'f:\dd\vctools\compiler\utc\src\p2\p2symtab.c
i also observed the same error when i try to build my vs 2005 code to vs 2008. but it happen till i have not installed Service pack of VS 2008...
have you installed Service pack... i think this will resolved your issue....
This typically happens with template instantiation. Unfortunately it could be caused by many things, but 99% of the time your code is subtly invoking undefined behavior.