C++ Error C4700 "use of uninitialized local var", reference to reference.

In Visual Studio I get the error C4700 “use of uninitialized local variable” when I attempt to use a local reference variable.

To optimize my mesh editor (memory usage), I decided to use a managing class “Mesh Editor” to hold an array of Points and also forms like edges and corners the moment they are required. Those forms store only references to the points, no copies. The mesh editor ensures that when a point gets deleted any shape referencing a point gets deleted as well.

All getter methods return a reference to either a reference or the actual data as stored on the Mesh Editor.
The error appears when I do this, referencing a reference member as explained above:

void FMeshEditor::DoSomething() {
	for (FDCorner& CX : MeshEditor.GetCorners()) {
		FDPoint& PointCB = CX.GetCornerPoint();
		float A = PointCB.X;
// "uninitialized local variable 'PointCB ' used"
	}
}

It is unclear why this happens, because the reference properties are all initialized.

struct FDEdge {
	
	FDPoint& P1;

	FDPoint& P2;

	FDPoint* GetConnectingPoint(const FDEdge& InEdge) const {
		if (P1 == InEdge.P1 || P1 == InEdge.P2) {
			return &P1;
		}
		if (P2 == InEdge.P1 || P2 == InEdge.P2) {
			return &P2;
		}
		return nullptr;
	}

	FDEdge(FDPoint& InP1, FDPoint& InP2)
		: P1 (InP1)
		, P2 (InP2)
	{}
};
struct FDCorner {

private:

	// Edge which should make a corner with EdgeB.
	FDEdge& EdgeA;

	// Edge which should make a corner with EdgeA.
	FDEdge& EdgeB;
	
	FDPoint& CornerPoint;

	FDPoint& OuterPoint1;

	FDPoint& OuterPoint2;

public:

	// Setup

	FDCorner(FDEdge& InEdgeA, FDEdge& InEdgeB)
		: EdgeA (InEdgeA) 
		, EdgeB (InEdgeB) 
		, CornerPoint (GetEdgeA().GetConnectingPoint(GetEdgeB()) 
? *GetEdgeA().GetConnectingPoint(GetEdgeB()) 
: GetEdgeA().P1) 
		, OuterPoint1 (GetEdgeA().P1 == GetCornerPoint() 
? GetEdgeA().P2 
: GetEdgeA().P1) 
		, OuterPoint2 (GetEdgeB().P1 == GetCornerPoint() 
? GetEdgeB().P2 
: GetEdgeB().P1) 
	{
		// We need to check that we actually set a connected corner point.
		check(GetEdgeA().GetConnectingPoint(GetEdgeB()) != nullptr);
	}

	FDEdge& GetEdgeA() const {
		return EdgeA;
	}

	FDEdge& GetEdgeB() const {
		return EdgeB;
	}

	FDPoint& GetCornerPoint() const {
		CornerPoint;
	}

	FDPoint& GetOuterPoint1() const {
		return OuterPoint1;
	}

	FDPoint& GetOuterPoint2() const {
		return OuterPoint2;
	}
};

I am not getting any error when my local variable is not a reference, or when I use a reference directly from a Get method. I assume then there might be something weird happening with the assignment operator, but it is not clear. No further info / error message.

What is the definition of the FDPoint? Did you overload the copy operator yourself? I see the == must have been overloaded. These ternary operators in the member initializer list are interesting. Obviously I dont actually see GetCornerPoint defined in your post.

I simplified some of the shown code because there’s a lot. I use ternary operators to check if a point exists on two edges (to check if there is a corner), otherwise a dummy value is assigned. It is not beautiful but since I work with references it has to be assigned to something.

As long as I can get away with this reference system I might be able to keep the memory usage extremely low, which is good and actually required if there will be many points. There is room for improvement :').

I did not overload the copy / move / assignment operator. equality operators are overloaded to check poinst against their Id instead of position. Any Get function returns named property as a non const reference from a non const Get.

I feel like there is something strange going on with the = operator. Microsoft docs state that any class with a reference member will have its default = operator deleted. It’s the first time I run into that actually. I don’t get any errors about that right now but it does give me the C4700 error when I attempt to store properties contained by such reference in a local reference var.

struct FDPoint {
	
	float X;

	float Y;

	// The Id is used for equality checks, not the X / Y of the point.
	int32 Id;

	// Initialize
	FDPoint() 
		: X (0.f)
		, Y (0.f)
		, Id (-1)
	{}
	FDPoint(float InX, float InY, int32 InId)
		: X (InX)
		, Y (InY)
		, Id (InId)
	{}
	FDPoint(FVector2D InPosition, int32 InId)
		: X (InPosition.X)
		, Y (InPosition.Y)
		, Id (InId)
	{}

	friend inline uint32 GetTypeHash(const FDPoint& InPoint) {
		return GetTypeHash(InPoint.Id);
	}

	// Operators
	bool operator==(const FDPoint& InOther) const {
		return (
			Id == InOther.Id
		);
	}
	bool operator!=(const FDPoint& InOther) const {
		return !operator==(InOther);
	}

};
  • Updated first post to show Get methods on corner. Currently they are const methods but it doesn’t change the outcome.

Alright , I figured something out. Whenever I try to access the reference, say:
FDPoint& CornerPoint;
from:
FDPoint& GetCornerPoint () { return CornerPoint; }

I run into memory problems. which is strange, because the actual point CornerPoint refers to lives in an array in the Mesh Editor. It’s just invalid at any time during and after construction. In the corner’s constructor you see it retrieves the corner point ref from the edges. The edges and their referenced points are valid.

1 Like

New to me, but it seems that structs can not simply have reference members unless you write custom operators for them to handle copying and moving. I’m not going to mess with that right now. Pointers were not a useful alternative in my current system. I will rewrite it and see if I can get rid of the classes I had made (tris, corners etc) by using only points and a new utility library.

1 Like