Author |
Topic |
|
Krakken
Ketchup Master
Australia
63 Posts |
Posted - May 22 2008 : 8:00:08 PM
|
I have the following example code to demonstrate this issue. I am using version 1639 but it occurs on the stable build also.
#define InterfaceManager CInterfaceManager::Get()
template <typename t_Class>
class CSingletonT
{
public:
static inline t_Class& Get()
{
static t_Class s_Instance;
return s_Instance;
}
};
class CInterfaceManager : public CSingletonT<CInterfaceManager>
{
public:
void DoSomething()
{
m_iIndex = 5;
}
protected:
int m_iIndex;
};
If you try to access the above code using the macro:
InterfaceManager
The members of CInterfaceManager are not listed. When used without the singleton template (ie. the Get() is implemented within the CInterfaceManager class), it works fine so I believe it is a template problem.
I'm finding this when using templates and macros together in other areas too.
|
|
rhummer
Tomato Guru
USA
527 Posts |
Posted - May 22 2008 : 8:19:39 PM
|
It's not a template issue, its just that VA X doesn't evaluate macros. So what you are trying to use InterfaceManager for you will get no help from VA X for.
Support has their answer to this here: http://forum.wholetomato.com/forum/topic.asp?TOPIC_ID=4253
Feline: maybe you want to make an FAQ entry from this, I've seen this popup up here from time to time, and I always have to search to digg-up this post every time. :)
|
Tools Engineer - Raven Software VS2005 SP2/VS2008 SP1 - VAX <LATEST> - Win 7 x64
|
Edited by - rhummer on May 22 2008 8:27:36 PM |
|
|
Krakken
Ketchup Master
Australia
63 Posts |
Posted - May 22 2008 : 8:43:20 PM
|
Thank you for your reply.
Is there a good reason VAX doesn't evaluate macros? The post you referred me to doesn't satisfy my concern. |
|
|
Krakken
Ketchup Master
Australia
63 Posts |
Posted - May 22 2008 : 8:48:32 PM
|
Plus, as I mentioned before, the macro is evaluated if Get() is defined within CInterfaceManager. |
|
|
feline
Whole Tomato Software
United Kingdom
19021 Posts |
Posted - May 23 2008 : 3:52:53 PM
|
rhummer a good point, I have just created a new FAQ entry:
http://docs.wholetomato.com?W311
Krakken as explained in the new FAQ entry there is a work around here. You have to edit VA's "StdAfx.h" file as explained in this FAQ entry:
http://docs.wholetomato.com?W302
and add the entry:
#define InterfaceManager CInterfaceManager::Get()
at the bottom. This file is used to help VA's parser with difficult code, and can be used to work around odd effects. After modifying this file you need to rebuild the VA symbol database for the changes to take effect:
VA Options -> Performance -> General -> Rebuild symbol databases
I have just tested this here and it worked correctly for me. Note that this does effectively hard code a single definition of the macro across all solutions. |
zen is the art of being at one with the two'ness |
|
|
Krakken
Ketchup Master
Australia
63 Posts |
Posted - May 25 2008 : 7:51:11 PM
|
Thanks feline, I'll use that fix for now.
Are there any plans to introduce evaluation when referencing macros? I'm assuming there is a reason behind not doing it right now? |
|
|
feline
Whole Tomato Software
United Kingdom
19021 Posts |
Posted - May 26 2008 : 11:53:34 AM
|
macro's are a tricky subject. There are quite a few system types like INT and LONG where people do not want the macro evaluated more deeply, since the macro type is what they want, and are working with.
What you are doing here, the problems really start when you start doing something like:
#ifdef PROJECT_ONE #define InterfaceManager CInterfaceManager::Get() #else #define InterfaceManager CCreateInterface::GetThisItem() #endif
It is fairly easy to think up situations that VA is not going to be able to handle correctly, since it is not actually compiling the code. Add in users who work on multiple OS's, perhaps Windows and Linux, and the situation can get really quite nasty. |
zen is the art of being at one with the two'ness |
|
|
Krakken
Ketchup Master
Australia
63 Posts |
Posted - May 27 2008 : 12:09:12 AM
|
I agree, that does complicate the situation for VA. In response to INT and LONG, surely so long as you didn't use a '.' or '->' to dereference an object, it shouldn't suggest anything anyway.
I have a suggestion for the current StdAfx.h system though I don't know how feasible it might be. Maybe if we had a project-level file VA could search for and parse as it would the "StdAfx.h" file when the project is loaded. For example: "__VA_AFX.h" or something. That way it would allow more flexibility when dealing with issues like this. |
|
|
Krakken
Ketchup Master
Australia
63 Posts |
Posted - May 27 2008 : 01:41:51 AM
|
I also still don't fully understand what you mean when you say "Visual Assist X does not evaluate as you reference symbols".
Take this for example:
#define LIST_FOREACH(TYPE, ITER, LIST) \ for (TYPE::iterator ITER = LIST.begin(); ITER != LIST.end(); ITER++)
typedef std::list<int> t_IntegerList;
int _tmain(int argc, _TCHAR* argv[])
{
t_IntegerList lIntegers;
LIST_FOREACH(t_IntegerList, pInteger, lIntegers)
{
printf("%d\\n", *pInteger);
}
return 0;
}
A few months ago, VA did not know how to display "pInteger" in this example. It would have no colour coding and intellisense was unavailable to the variable. Recently, VA has started to pick this up.
There's also that if CInterfaceManager::Get() is defined as without using the singleton template:
class CInterfaceManager //: public CSingletonT<CInterfaceManager>
{
public:
static inline CInterfaceManager& Get()
{
static CInterfaceManager s_Instance;
return s_Instance;
}
void DoSomething()
{
m_iIndex = 5;
}
protected:
int m_iIndex;
};
"InterfaceManager" lists the members without any problems.
Here is an image demonstrating this:
|
Edited by - Krakken on May 27 2008 02:01:21 AM |
|
|
feline
Whole Tomato Software
United Kingdom
19021 Posts |
Posted - May 27 2008 : 09:27:21 AM
|
VA's stdafx.h file first. This file is designed to be used while parsing the library code, stable include directories, etc. Given this "low level" nature doing this on a project by project, or solution by solution basis is not going to work very well.
Plus all sorts of interesting problems are going to start once you consider source code that is used by more than one solution, where two different stdafx.h files apply, and make the code look different. This sounds like a support nightmare in the making.
Normally I do not suggest that people edit VA's stdafx.h file, but it is useful to do so in certain specific conditions.
The comment "Visual Assist X does not evaluate as you reference symbols" is a quote from the forum thread:
http://forum.wholetomato.com/forum/topic.asp?TOPIC_ID=4253
I am not 100% sure what to make of it, but it sort of makes sense to me. There is a lot of difference between referencing and declaring a symbol. Trying to determine the type of a symbol by its usage is going to run into all sorts of edge cases, and is a lot less reliable than trying to determine its type based on its declaration. Just compare C++ (a strongly typed language) to a scripting language, where variables do not even have to be declared before being used.
Your "pInteger" example, macro's are a fact of life in C++ so we try to work with them, and work to improve our handling of them. However it is still true that it is easy to find macro's that confuse VA's parser, and they are a common cause of support enquiries.
I see what you mean about CInterfaceManager::Get() now. Here two "separate" issues are at work. VA's support for templates is not perfect. It is a lot better than it used to be, but remember what the compiler does when compiling template code. It actually generates the complete code for each instanciated (not sure that is the correct word, or how to spell it ) template type.
VA does not have the same luxuries as a compiler, so our parser has to work a bit differently. So when mixing templates (can cause problems) with macros that declare an "unclear" type (you need to evaluate the template to work out the type) I am not surprised that VA gets confused. |
zen is the art of being at one with the two'ness |
|
|
Krakken
Ketchup Master
Australia
63 Posts |
Posted - May 27 2008 : 8:01:32 PM
|
Thanks for your reply feline. :)
I've just gone ahead and replaced templated versions of Get() with per-instance implementations of Get(). It's working well with VA now and I can use my macros without editing the "evil" StdAfx.h.
I did notice something though, I don't know what I did but I managed to get the templated Get() working at one point. It even listed Get() as being a member of a base class correctly so I must have jogged something to make it parse the template. I tried it in other projects and I can't seem to reproduce it.
It looks like VA is getting closer to being able to manage this sort of situation so I'll sit tight and wait to see what happens over a few more major builds. :) |
|
|
|
Topic |
|