Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Why am I getting "C stack overflow"?

I'm creating my own Vector3 class just for fun, but I am having problems with it.

Here is my code

local Vector3 = {};
local mt = {
	__index = Vector3,
	__metatable = "This metatable is locked",
	__newindex = function(t, k, v)
		rawset(t, k, nil);
		error(k .. " is not a valid member of Vector3", 2);
	end,
	__mul = function(op1, op2)
		if (rawequal(type(op1), "table") and rawequal(type(op2), "table")) then
			return Vector3.new(op1.X*op2.X, op1.Y*op2.Y, op1.Z*op2.Z);
		end
		
		if (rawequal(type(op2), "number")) then
			return Vector3.new(op1.X*op2, op1.Y*op2, op1.Z*op2);
		end
	end,
	__tostring = function(t)
		return t.X .. ", " .. t.Y .. ", " .. t.Z;
	end,
	__unm = function(t)
		return Vector3.new(-t.X, -t.Y, -t.Z);
	end,
	__div = function(op1, op2)
		if (rawequal(type(op1), "table") and rawequal(type(op2), "table")) then
			return Vector3.new(op1.X/op2.X, op1.Y/op2.Y, op1.Z/op2.Z);
		end
		
		if (rawequal(type(op2), "number")) then
			return Vector3.new(op1.X/op2, op1.Y/op2, op1.Z/op2);
		end
	end,
	__add = function(op1, op2)
		return Vector3.new(op1.X + op2.X, op1.Y + op2.Y, op1.Z + op2.Z);
	end,
	__sub = function(op1, op2)
		return Vector3.new(op1.X - op2.X, op1.Y - op2.Y, op1.Z + op2.Z);
	end
};

function Vector3.new(x, y, z)
	local self = {};
	self.X = x or 0;
	self.Y = y or 0;
	self.Z = z or 0;
	self.Magnitude = math.sqrt(x^2 + y^2 + z^2);
	setmetatable(self, mt);
	self.Unit = self/self.Magnitude;
	return self;
end

local myVector3 = Vector3.new(10, 20, 30);

print(
	myVector3,
	-myVector3,
	myVector3*2,
	myVector3/2,
	myVector3 + Vector3.new(1, 1, 1),
	myVector3 - Vector3.new(1, 1, 1),
	myVector3*Vector3.new(2, 2, 2),
	myVector3/Vector3.new(2, 2, 2)
);

(I get this error on line 48, which is in the Vector3.new constructor, which is self.Unit = self/self.Magnitude;

From what I understand, this "C stack overflow" would only occur if you invoked the metamethod within the function. Here is an example of what I mean:

local t = {};
setmetatable(t, {__index = function(t, k)
	return t[k];
end};

t[k] invokes __index again, thus calling that function again, and again: it is a circle.

I am not dividing my table within the __div function? If I am, can someone show me where? Or can other things cause this "C stack overflow" as well that I am doing?

Everything else seems to work just fine.

5 comments

0

woah

0

bruh u can probably download urself into a pc if ur that good at coding.

0

yeah

0

i cant even read this lol

0

do not read my old code bro

2 answers

You'll need to do:

function mt:__index(index)
  if index:lower() == 'unit' then
     return self/self.Magnitude
  end
end

I found the issue:

It was in __div

__div = function(op1, op2)
	if (rawequal(type(op1), "table") and rawequal(type(op2), "table")) then
		return Vector3.new(op1.X/op2.X, op1.Y/op2.Y, op1.Z/op2.Z);
	end

	if (rawequal(type(op2), "number")) then
		return Vector3.new(op1.X/op2, op1.Y/op2, op1.Z/op2);
	end
end

I was calling Vector3.new within its definition, thus causing a stack overflow.

I also have a solution:

self.Unit = {
	X = self.X/self.Magnitude,
	Y = self.Y/self.Magnitude,
	Z = self.Z/self.Magnitude
};
 
setmetatable(self, mt);
setmetatable(self.Unit, mt);

pasting code in this is a huge pain eryn pls fix

This discussion is preserved as it was. New answers, comments, and votes are closed.