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
 Find references misses some matches when #if used
 New Topic  Reply to Topic
 Printer Friendly
Author  Topic Next Topic  

DWS
New Member

7 Posts

Posted - Sep 18 2024 :  11:39:37 AM  Show Profile  Reply with Quote
Hello, I have attached (via Google Drive) a ZIP of a simple Visual Studio 2022 solution which demonstrates my problem.

https://drive.google.com/file/d/14iZvkWimN1HXUTesCLbOHL-aGj4sHPfZ/view?usp=drive_link

The source files are:

  • structs.h - Defines two struct types, InactiveStruct_t and ActiveStruct_t. Importantly, both structs contain a field that has the same name, fieldWithSameName. Also, InactiveStruct_t is defined within an #if (0) preprocessor block.

  • testClass.h - The test class has two functions and a data member named activeStruct, of type ActiveStruct_t.

  • function1.cpp contains TestClass::Function1(), which assigns "activeStruct.fieldWithSameName" to zero.

  • function2.cpp contains TestClass::Function2(), which has the same body as Function1(). Importantly, function2.cpp also contains an #if (0) preprocessor block, which declares a variable named "activeStruct" which -- if it was not being excluded from compilation -- would "hide" the assignment to TestClass::activeStruct in Function2().

To demonstrate the problem, perform a Find References on ".fieldWithSameName" in the two functions. You should see the following:
  • In TestClass::Function1(), find references returns the assignment to activeStruct.fieldWithSameName in Function1. It also returns the field named "fieldWithSameName" in ActiveStruct_tag. This is correct.

  • In TestClass::Function2(), find references returns the assignment to activeStruct.fieldWithSameName in Function2 (correct). But it also returns the field named "fieldWithSameName" in InactiveStruct_tag. This is incorrect.

feline
Whole Tomato Software

United Kingdom
18938 Posts

Posted - Sep 19 2024 :  07:45:04 AM  Show Profile  Reply with Quote
Do you want VA to ignore the code in the #if (0) block?

By design, VA parses inactive code, since if you are working under Windows, you are still going to want help working on code wrapped in a #ifdef LINUX block. So currently VA is doing what we expect and want.

If you really want VA to ignore this code, you can change:

#if (0)
InactiveStruct_t activeStruct;
#endif

into:
#if (0)
_asm {
InactiveStruct_t activeStruct;
}
#endif


since VA's parser ignores anything inside the _asm block, and since the compiler is already ignoring this code, editing the code further doesn't effect things.

zen is the art of being at one with the two'ness
Go to Top of Page

DWS
New Member

7 Posts

Posted - Sep 19 2024 :  11:11:56 AM  Show Profile  Reply with Quote
You're right; I don't want VA to ignore the code in the #if (0) block (although that is how I phrased my initial post -- my fault).

What I really want is for VA to account for the possibility that activeStruct in Function2 could be either an InactiveStruct_t (as if the preprocessor code were included) or an ActiveStruct_t (when the preprocessor code is excluded).

So in Function2(), I would want find references to return all references to both:
  • InactiveStruct_t::fieldWithSameName
  • ActiveStruct_t::fieldWithSameName

As it is today, it only returns references to InactiveStruct_t::fieldWithSameName.


I thought that maybe changing the #if to the following would make it return references to both structs:
#if (0)
InactiveStruct_t activeStruct;
#else
ActiveStruct_t activeStruct;
#endif

But unfortunately, it seems to just make VA assume that activeStruct in Function2 is of type ActiveStruct_t, rather than InactiveStruct_t -- it doesn't return references to both InactiveStruct_t::fieldWithSameName and ActiveStruct_t::fieldWithSameName.

Thanks for your continued help! -- Dave
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
18938 Posts

Posted - Sep 19 2024 :  1:11:20 PM  Show Profile  Reply with Quote
Unfortunately VA simply isn't designed to do this. If there are two possible definitions of the symbol, one will get picked and used.

Do you have a lot of situations like this, or only a few?

I am wondering if marking these types with Hashtags would work. If you mark the symbols with the same hashtag, you can jump between the instances of the hashtag with Alt-G on any of them.

https://www.wholetomato.com/documentation/navigation/va-hashtags

zen is the art of being at one with the two'ness
Go to Top of Page

DWS
New Member

7 Posts

Posted - Sep 19 2024 :  2:31:07 PM  Show Profile  Reply with Quote
Thank you for your answer -- I was afraid that might be the case, but it's understandable.

Our C++ code is highly shared between multiple build configurations, and therefore the situation where we are using one or more #if conditions to selectively choose between different structures that have at least some overlap in the names of their fields is not uncommon for us (although I know in the grand scheme of things that people don't do this kind of thing all that often). We're not using #if(0) like in this simple example, but rather #if(CONFIG_ONE) #elif(CONFIG_TWO), etc.

I'll have to give some thought to whether there is any way to refactor parts of our software so that this is done less frequently, but still somehow without requiring us to duplicate pieces of our code. The problem is that right now we can't always trust that our Find References results are complete (although at least now I understand why that is). And of course, Find References is one of the ways that we use VA the most.

I guess I might as well ask one final follow-up question: You said that if there are two possible definitions of a symbol, VA will ultimately pick one of them to use. Is there anything creative that we could do to influence the decision that VA makes in this regard? Maybe another way of asking the question is, is there anything that we can do inside of a preprocessor block that will have some effect on how VA parses the code? If so, we might be able to find some clever way to use it to work around our problem. Thanks!
Go to Top of Page
   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