Whole Tomato Software Forums
Whole Tomato Software Forums
Main Site | Profile | Register | Active Topics | Members | Search | FAQ
User name:
Password:
Save Password
Forgot your password?

 All Forums
 Visual Assist
 Technical Support
 Macros or templates are not properly evaluated
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic  

Krakken
Ketchup Master

Australia
63 Posts

Posted - May 22 2008 :  8:00:08 PM  Show Profile  Reply with Quote
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  Show Profile  Reply with Quote
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
Go to Top of Page

Krakken
Ketchup Master

Australia
63 Posts

Posted - May 22 2008 :  8:43:20 PM  Show Profile  Reply with Quote
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.
Go to Top of Page

Krakken
Ketchup Master

Australia
63 Posts

Posted - May 22 2008 :  8:48:32 PM  Show Profile  Reply with Quote
Plus, as I mentioned before, the macro is evaluated if Get() is defined within CInterfaceManager.
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
18940 Posts

Posted - May 23 2008 :  3:52:53 PM  Show Profile  Reply with Quote
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
Go to Top of Page

Krakken
Ketchup Master

Australia
63 Posts

Posted - May 25 2008 :  7:51:11 PM  Show Profile  Reply with Quote
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?
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
18940 Posts

Posted - May 26 2008 :  11:53:34 AM  Show Profile  Reply with Quote
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
Go to Top of Page

Krakken
Ketchup Master

Australia
63 Posts

Posted - May 27 2008 :  12:09:12 AM  Show Profile  Reply with Quote
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.
Go to Top of Page

Krakken
Ketchup Master

Australia
63 Posts

Posted - May 27 2008 :  01:41:51 AM  Show Profile  Reply with Quote
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
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
18940 Posts

Posted - May 27 2008 :  09:27:21 AM  Show Profile  Reply with Quote
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
Go to Top of Page

Krakken
Ketchup Master

Australia
63 Posts

Posted - May 27 2008 :  8:01:32 PM  Show Profile  Reply with Quote
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. :)
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
© 2023 Whole Tomato Software, LLC Go To Top Of Page
Snitz Forums 2000