CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15
  1. #1
    Join Date
    May 2015
    Posts
    500

    New file inclusion problem on legacy code

    Hello,

    I added a new class in the c++ header file and included in existing file. And it works ok, as expected .

    I also have #pragma once in the new header file.

    Now I want to include in another c++ legacy header file. But now I get unknown type for the new class, in the first inclusion..


    I tried using the forward declaration. I also tried to remove #include from the first .h and no help..

    I am not sure about the legacy code is quite big and might have some circular inclusion.


    Please help me with this ?

    thanks
    Pdk

    Btw, Merry Christmas and Happy new year..Was on break and now back again and thanks a lot for the wonderful forum/

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: New file inclusion problem on legacy code

    Sometimes the order of #includes and also the order of declarations does matter.
    However, without seeing your code it's hard to guess.
    Victor Nijegorodov

  3. #3
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: New file inclusion problem on legacy code

    I am not sure about the legacy code is quite big and might have some circular inclusion.
    Well that is fairly easy to determine by finding out the include dependencies for each .cpp/.h file uses. Once you have that, then you can ascertain if there any circular dependencies and which .h files require which others first.

    Note that if you forward declare a class/struct, usage of that class until it is defined is restricted to pointer usage.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  4. #4
    Join Date
    May 2015
    Posts
    500

    Re: New file inclusion problem on legacy code

    Thanks a lot Victor and kaud.

    Actually, that function i was adding was not used as of now (so commented out) and moved on. But now facing similar issue.

    I never had this kind of file inclusion issues (as the .h guards ), might have helped in my earlier works.


    I had added a new file:
    Code:
    #pragma once
    
    #include "VectorGUIDList.h"
    #include "Simulator.h"
    #include "MIFile.h"
    #include "MIGeometry.h"
    #include "MISubGeometry.h"
    
    class CSimulator;
    
    // TODO_PRIYA_FWA: Does this needs to have CSimObject, so as to get the GetObSize
    class FWApoint : public TweakableObject
    {
    public:
    
    	FWApoint()
    	{
    	}
    
    	FWApoint(CString sPointName) : m_name(sPointName)	//TODOPRIYA Set up other members
    	{
    	}
    
    	FWApoint(CString sPointName, size_t nPixelIndex, int nSimIndex, double dAntEasting_m, double dAntNorthing_m, double dAntHeight_m)
    		:m_name(sPointName),
    		m_pixelIndex(nPixelIndex),
    		m_indexWrtSim(nSimIndex),
    		m_dAntEasting_m(dAntEasting_m),
    		m_dAntNorthing_m(dAntNorthing_m),
    		m_dAntHeight_m(dAntHeight_m)
    	{
    
    		// Set the pixel index based on the above
    	}
    
    	~FWApoint()
    	{
    	}
    
    	const CString& GetName() const
    	{
    		return m_name;
    	}
    	virtual bool PopulateTweakList(TweakList& tl)
    	{
    
    		tl.Add(new TweakListObj_SimpleType<CString>("FWA point Name", &m_name, TWEAKUNIT_String));
    		tl.Add(new TweakListObj_SimpleType<size_t>("Pixel index", &m_pixelIndex, TWEAKUNIT_Number));
    		tl.Add(new TweakListObj_SimpleType<int>("FWA index wrt sim", &m_indexWrtSim, TWEAKUNIT_Number));
    		tl.Add(new TweakListObj_SimpleType<double>("Antenna Easting", &m_dAntEasting_m, TWEAKUNIT_Number));
    		tl.Add(new TweakListObj_SimpleType<double>("Antenna Northing", &m_dAntNorthing_m, TWEAKUNIT_Number));
    		tl.Add(new TweakListObj_SimpleType<double>("Antenna Height", &m_dAntHeight_m, TWEAKUNIT_Number));
    
    		return true;
    	}
    	
    		const size_t& GetPixelIndex() const
    		{
    			return m_pixelIndex;
    		}
    
    		void SetPixelIndex( size_t nIndex)
    		{
    			m_pixelIndex =nIndex;
    		}
    	
    	void SetupFWAIndex(int  nFwaCounter)
    	{
    		m_indexWrtSim = nFwaCounter;
    	}
    
    	void Serialize(CSimPersist& persist)
    	{
    
    		if(persist.IsStoring())
    		{
    
    		persist.Archive(m_name);
    				persist.Archive(m_pixelIndex);
    						persist.Archive(m_indexWrtSim);
    		persist.Archive(m_dAntEasting_m);
    		persist.Archive(m_dAntNorthing_m);
    		persist.Archive(m_dAntHeight_m);
    		}
    		else
    		{
    		persist.Archive(m_name);
    						persist.Archive(m_pixelIndex);
    		persist.Archive(m_indexWrtSim);
    
    		persist.Archive(m_dAntEasting_m);
    		persist.Archive(m_dAntNorthing_m);
    		persist.Archive(m_dAntHeight_m);
    
    		}
    
    	}
    private:
    	CString m_name;      // The name of the FWA point
    	size_t  m_pixelIndex =0; // The pixel index that stores the pathloss info for this point
    	int m_indexWrtSim = -1;
    	// The following 3 things should be used to set above m_pixelIndex somehow
    	double m_dAntEasting_m = 0;
    	double m_dAntNorthing_m = 0;
    	double m_dAntHeight_m = 0;
    };
    
    class CFWAInfo : public TweakableObject
    {
    public:
    	CFWAInfo()
    	{
    		ClearGUIDs();
    		ClearPoints();
    	}
    
    	void ClearGUIDs()
    	{
    		//m_GUIDList.m_nVectorCount = 0;
    		m_GUIDList.GetList().clear();
    	}
    	void AddGUIId(const std::string& szGuid)
    	{
    		m_GUIDList.GetList().push_back(szGuid);
    	}
    	const std::string& GetGUIId(int index)
    	{
    		auto /*std::list<std::string>::iterator */itr = m_GUIDList.begin();
    		std::advance(itr, index);
    		auto str = *itr;
    
    		return *itr;
    	}
    	void ClearPoints()
    	{
    		m_FWApoints.clear();
    	}
    
    	virtual bool PopulateTweakList(TweakList& tl)
    	{
    		// TODO_PRIYA: As of now some issue in GUIDs display.
    		//tl.Add(new TweakListObj_Object<VectorGUIDList>("GUID List",			&(m_GUIDList)));
    		//for(auto guid : m_GUIDList.GetList())
    		//{
    		//	CString nGUID = guid.c_str(); 
    			//tl.Add(new TweakListObj_SimpleType<CString>	("GUID",					&nGUID,				TWEAKUNIT_String));
    		//}
    
    		for (auto& fwp : m_FWApoints)
    		{
    			tl.Add(new TweakListObj_Object<FWApoint>("FWP ", &(fwp)));
    		}
    		return true;
    	}
    
    	void PopulatePoints(CSimulator * psim)
    	{
    		ClearPoints();
    
    		// Go through the m_GUIDList and use it to populate m_FWApoints
    		for (auto& sGuid : m_GUIDList)
    		{
    			MIVector* pMIVector = MITopManager::Instance()->FindVectorInSystemAndUserManagers(sGuid.c_str());
    
    			MIFile* pMIFile = NULL;
    			pMIVector->ResetFileReading();
    			while (pMIFile = pMIVector->GetNextFile())
    			{
    				pMIFile->SetLoadingType(LoadingType::MI_BOTH);
    				MIFeature* pMIFeature = NULL;
    
    				for (pMIFeature = pMIFile->GetFirstFeature(); pMIFeature != NULL; pMIFeature = pMIFile->GetNextFeature())
    				{
    					MIGeometry* pMIGeometry = NULL;
    					pMIFeature->ResetGeometryReading();
    					while (pMIGeometry = pMIFeature->GetNextGeometry())
    					{
    						// for each point
    						if (pMIGeometry->GetType() == GeometryType::MI_POINT)
    						{
    							int nSubGeometry = 0;
    							pMIGeometry->ResetSubGeometryReading();
    							MISubGeometry* pMISubGeometry = NULL;
    							MISubGeometry* pMISub = pMIGeometry->GetFirstSubGeometry();
    							if (!pMISub)
    								continue;
    							MIPoint* poPoint = pMISub->GetFirstPoint();
    							if (!poPoint)
    								continue;
    							double easting = poPoint->GetXDouble();
    							double northing = poPoint->GetYDouble();
    							size_t	nPixelIndex = psim->GetPixelIndex(easting, northing);
    							std::string sName = std::string("fwa_point_") + std::to_string(nPixelIndex);
    
    							FWApoint pt(sName.c_str(), nPixelIndex, -1, easting, northing, 0);
    
    							m_FWApoints.push_back(pt);
    						}
    					}
    				}
    			}
    		}
    	}
    
    	void Serialize(CSimPersist& persist)
    	{
    		/*
    				int nSize = m_FWApoints.size();
    
    				for (int i = 0; i < nSize; i++)
    				{
    					m_FWApoints[i].Serialize(persist);
    				}
    		 */
    
    		size_t numEntries = m_FWApoints.size();
    		persist.Archive(numEntries);
    
    		if (persist.IsStoring())
    		{
    			for (auto& vecObj : m_FWApoints)
    			{
    				vecObj.Serialize(persist);
    			}
    		}
    		else
    		{
    			m_FWApoints.clear();
    
    			FWApoint pt;
    			for (size_t i = 0; i < numEntries; i++)
    			{
    				pt.Serialize(persist);
    
    				m_FWApoints.push_back(pt);
    
    			}
    		}
    	}
    
    	// TODO_PRIYA_FWA: Can a terminal type have multiple point vectors ? !!!
    
    		void SetupFWAIndex( int  fwaCounter)
    	{
    	  m_FWApoints[0].SetupFWAIndex(fwaCounter);
    	}
    
    	FWApoint GetFirstFWAPoint()
    	{
    	  return m_FWApoints[0];
    	}
    
    	~CFWAInfo()
    	{
    		ClearGUIDs();
    		ClearPoints();
    	}
    private:
    	VectorGUIDList				m_GUIDList;     // GUIDs for FWA point-vector on a terminal type
    	std::vector<FWApoint>		m_FWApoints;
    
    };
    The simulator.h is legacy file, which i included.

    Now getting error that:

    C:\Development\lat_22_2\enterprise\Source\Planning\3gAsset\Sim\FWAInfo.h(192,1): error C2027: use of undefined type 'CSimulator'
    C:\Development\lat_22_2\enterprise\Source\Planning\3gAsset\Sim\FWAInfo.h(9): note: see declaration of 'CSimulator'


    Not sure how to resolve this.

    Is there anyway, to find the inclusion order in visual c++ ?

    thanks a lot
    pdk

  5. #5
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: New file inclusion problem on legacy code

    Is there anyway, to find the inclusion order in visual c++ ?
    Yeah - use a pen and paper and work through the includes!

    Seriously, you need to work through the includes/code, find each of the different defined types (classes/structs etc), note their name and then find where these types are defined. Note that a declaration (eg class Simulation is not a definition. Once you have this list, then you know which includes are needed for each include/code and then you have to work out the order. Depending upon the number of defined types and the number of possible includes, this can be a simple or difficult task.

    A debugger can be useful here if it can show all the variables and their types.

    This can be a slog, but I don't know of another way. If any one does know of any free automated way of doing this, I'd love to know.
    Last edited by 2kaud; December 26th, 2021 at 04:59 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  6. #6
    Join Date
    May 2015
    Posts
    500

    Re: New file inclusion problem on legacy code

    Thanks a lot kaud. Btw, I created the FWA.cpp and moved most of functions there. Now this issue is resolved.

    But it would be helpful, if we have any tools to show the inclusion order .. (when the large legacy code base and multiple inclusions)

  7. #7
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: New file inclusion problem on legacy code

    Yes I know - but I don't know of any. We have a tool which shows the #include hierarchy - but not what each include defines.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  8. #8
    Join Date
    May 2015
    Posts
    500

    Re: New file inclusion problem on legacy code

    Hi Kaud,

    Sorry i didnot have time to look further into this issue. Just to simplify the issue

    I have added a new file called FWAInfo.h which has two classes: FWAPoint and CFWAInfo

    Now in the legacy c++ class called simulator:
    Code:
    class CSimulator : public TweakableObject
    {
    public:
    	CSimTerminalTypeArray		m_terminalTypeList;		// List of terminal types.
    	SimulationInfo				m_simInfo;
    	
    };
    CSimTerminalTypeArray and SimulationInfo classes need the new class

    Code:
    --------------------------------------------------------------------------
    #include "FWAInfo.h"
    typedef CSimArray<CSimTerminalType, ObjectHelper<CSimTerminalType> > CSimTerminalTypeArray;
    
    class CSimTerminalType : public TweakableObject, public CSimObject
    {
    
    
    	CFWAInfo					m_FWAinfo;
    }
    
    --------------------------------------------------------------------------
    #include "FWAInfo.h"
    class SimulationInfo : public TweakableObject, public CSimObject
    {
    	// TODO_PRIYA_FWA: On inclusion of FWAInfo.h, i get circular dependency issue
    //	FWApoint*	GetFWApoint(int fwaIndexWrtSim);
    }
    So issue is I cannot include the new file, in the SimulationInfo class. I get compile error for the first CSimTerminalType class/




    Just to give an simple eg. lets we define new class D . In the legacy class B and C, it is used. B and C are used in class A.

    In
    class A{

    B b;
    C c;
    }

    In both Class B and C, D is used

    Class B
    {
    D d;
    }

    class C
    {
    D d;

    }

    when i include Class D header in class C, header, i get compile error for classB

    Please help me with this issue
    Last edited by pdk5; January 1st, 2022 at 01:57 PM.

  9. #9
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: New file inclusion problem on legacy code

    // TODO_PRIYA_FWA: On inclusion of FWAInfo.h, i get circular dependency issue
    Well FWAInfo.h must have an include which then includes FWAInfo.h somewhere or another already included file - causing the circular dependency. You''ll need to find what in FWAInfo,h is causing the circular dependency and re-factor the includes to eliminate it. I know this can be a pain as I've been through it - but it's just a case of slogging through the include files and finding out the issue.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  10. #10
    Join Date
    May 2015
    Posts
    500

    Re: New file inclusion problem on legacy code

    Thanks a lot kaud. I think most probably this issue is now resolved . I had included "simulator.h" in the FWAInfo.h. As I had moved all function definitions, into the .cpp, I could remove that .h. (and just forward declared)

    Now Btw, i have another issue:
    I have a function like this :

    Code:
    FWApoint * SimulationInfo::GetFWApoint(int fwaIndexWrtSim)
    {
    	// Search through FWA points on terminal types till get one with correct index.
    	// else return nullptr
     	CSimulator* pSim = GetSim();
    	const size_t numTermTypes = (size_t)GetNumTerminalTypes();
    	int fwaCounter(0);
    	for (size_t i = 0; i < numTermTypes ; i++)
    	{
    		CSimTerminalType& termType = pSim->m_terminalTypeList.GetAt(i);
    
    		if(termType.IsFWA())
    		{
    			if(fwaIndexWrtSim == fwaCounter)
    			{
    				
    				//m_dummyTerminal.SetAtPixel(pTermType->GetFWAInfo().GetFirstFWAPoint().GetPixelIndex(), pTermType);
    				return &termType.GetFWAInfo()->GetFirstFWAPoint();	
    			}
    		}
    	}
    	return nullptr;
    }
    But I know, itswrong to return pointer to local variable and I get the error
    warning C4172: returning address of local variable or temporary

    Ive not used the smart pointers for long.
    Could you kindly give inputs, on this ?

  11. #11
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: New file inclusion problem on legacy code

    What prevents you to return the CSimulator instance rather than the pointer to a temporary created object?
    Victor Nijegorodov

  12. #12
    Join Date
    May 2015
    Posts
    500

    Re: New file inclusion problem on legacy code

    @Victor thanks a lot for the response.
    Yes, i.e what was discussed during design. It makes it easier, to check if it is valid, by checking if its null_ptr !
    Also makes it consistent with the existing code
    Last edited by pdk5; January 2nd, 2022 at 02:41 PM.

  13. #13
    Join Date
    May 2015
    Posts
    500

    Re: New file inclusion problem on legacy code

    May be otherway is pass it function param as reference and return a bool (to tell if its valid )!!!

  14. #14
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: New file inclusion problem on legacy code

    Have you considered using std:: optional? There is also a nullopt value. https://en.cppreference.com/w/cpp/utility/optional

    If not that, then perhaps return say a std:: pair - one element value, one element bool

    Your suggestion to return bool and pass param as ref is also a valid established method.

    But what would you return for parm if not valid? One common value used is the default initialisation value for the type. If this default init value is considered not to be valid, then you can just return this default value and check for it in the caller.

    Another way would be to use exceptions - if not valid then an exception is thrown. If an invalid value can be 'norm' as opposed to a true exception then I consider this way last - as exceptions have an overhead if called. But in this case the caller needs to know this and coded to handle exceptions.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  15. #15
    Join Date
    May 2015
    Posts
    500

    Re: New file inclusion problem on legacy code

    Thankyou very much kaud. As per your advice i have used optional now
    (sorry for the delay response,)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured