-
December 24th, 2021, 06:52 AM
#1
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/
-
December 24th, 2021, 11:04 AM
#2
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
-
December 24th, 2021, 12:06 PM
#3
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)
-
December 26th, 2021, 04:21 AM
#4
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
-
December 26th, 2021, 04:57 AM
#5
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)
-
December 26th, 2021, 06:06 AM
#6
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)
-
December 26th, 2021, 07:15 AM
#7
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)
-
January 1st, 2022, 01:45 PM
#8
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.
-
January 2nd, 2022, 05:03 AM
#9
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)
-
January 2nd, 2022, 11:28 AM
#10
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 ?
-
January 2nd, 2022, 11:56 AM
#11
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
-
January 2nd, 2022, 02:39 PM
#12
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.
-
January 2nd, 2022, 02:40 PM
#13
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 )!!!
-
January 3rd, 2022, 04:34 AM
#14
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)
-
January 6th, 2022, 03:43 AM
#15
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|