0

I have a few functions under a namespace. They are only defined in a single file(include/math/math.h), but for some reason, I am getting errors about those functions already being defined. Please note header guards are in place.

I've already gone through practically all of the code in the solution multiple times over and I couldn't find anything, but it could just be me being in a rush, I suppose. Couldn't find anything after multiple attempts.

include/math/math.h

#ifndef STORMENGINE_MATH_MATH_H
#define STORMENGINE_MATH_MATH_H

namespace Math
{
    // Fast inverse square root algorithm.
    // All credits go to Greg Walsh.
    // Original algorithm is available online
    // on multiple websites, including with
    // a full explanation on the English
    // Wikipedia project by WikiMedia.
    float FastInverseSquareRoot(float flNum)
    {
        long i;
        float x2, y;
        const float threehalfs = 1.5f;

        x2 = flNum * 0.5f;
        y = flNum;
        i = *(long*)& y;
        i = 0x5f3759df - (i >> 1);
        y = *(float*)& i;
        y = y * (threehalfs - (x2 * y * y));

        return y;
    }

    // Fast inverse square root algorithm.
    // All credits go to Greg Walsh.
    // Original algorithm is available online
    // on multiple websites, including with
    // a full explanation on the English
    // Wikipedia project by WikiMedia.
    float InverseSquareRoot(float flNum, int nCount = 1)
    {
        long i;
        float x2, y;
        const float threehalfs = 1.5f;

        x2 = flNum * 0.5f;
        y = flNum;
        i = *(long*)& y;
        i = 0x5f3759df - (i >> 1);
        y = *(float*)& i;

        for (int j = 0; j < nCount; ++j)
        {
            y = y * (threehalfs - (x2 * y * y));
        }

        return y;
    }

    // Fast inverse square root algorithm.
    // All credits go to Greg Walsh.
    // Original algorithm is available online
    // on multiple websites, including with
    // a full explanation on the English
    // Wikipedia project by WikiMedia.
    float FastSquareRoot(float flNum)
    {
        long i;
        float x2, y;
        const float threehalfs = 1.5f;

        x2 = flNum * 0.5f;
        y = flNum;
        i = *(long*)& y;
        i = 0x5f3759df - (i >> 1);
        y = *(float*)& i;
        y = y * (threehalfs - (x2 * y * y));

        return (1.f / y);
    }

    // Fast inverse square root algorithm.
    // All credits go to Greg Walsh.
    // Original algorithm is available online
    // on multiple websites, including with
    // a full explanation on the English
    // Wikipedia project by WikiMedia.
    float SquareRoot(float flNum, int nCount = 1)
    {
        long i;
        float x2, y;
        const float threehalfs = 1.5f;

        x2 = flNum * 0.5f;
        y = flNum;
        i = *(long*)& y;
        i = 0x5f3759df - (i >> 1);
        y = *(float*)& i;

        for (int j = 0; j < nCount; ++j)
        {
            y = y * (threehalfs - (x2 * y * y));
        }

        return (1.f / y);
    }
};

#endif // STORMENGINE_MATH_MATH_H

vector2.h segments of usage


    FORCEINLINE float Length() const
    {
        return Math::SquareRoot(x * x + y * y, 6);
    }

    FORCEINLINE float LengthFast() const
    {
        return Math::FastSquareRoot(x * x + y * y);
    }

    FORCEINLINE float LengthSqr() const
    {
        return (x * x + y * y);
    }

// ----- Multiple irrelevant things inbetween -----

    FORCEINLINE static float Length(const Vector2& vec)
    {
        return Math::SquareRoot(vec.x * vec.x + vec.y * vec.y, 6);
    }

    FORCEINLINE static float LengthFast(const Vector2& vec)
    {
        return Math::FastSquareRoot(vec.x * vec.x + vec.y * vec.y);
    }

    FORCEINLINE static float LengthSqr(const Vector2& vec)
    {
        return (vec.x * vec.x + vec.y * vec.y);
    }

vector3.h segments of usage

    FORCEINLINE float Length() const
    {
        return Math::SquareRoot(x * x + y * y + z * z, 6);
    }

    FORCEINLINE float LengthFast() const
    {
        return Math::FastSquareRoot(x * x + y * y + z * z);
    }

    FORCEINLINE float LengthSqr() const
    {
        return (x * x + y * y + z * z);
    }

// ----- Multiple irrelevant things inbetween -----

    FORCEINLINE static float Length(const Vector3& vec)
    {
        return Math::SquareRoot(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z, 6);
    }

    FORCEINLINE static float LengthFast(const Vector3& vec)
    {
        return Math::FastSquareRoot(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);
    }

    FORCEINLINE static float LengthSqr(const Vector3& vec)
    {
        return (vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);
    }

vector4.h segments of usage

    FORCEINLINE float Length() const
    {
        return Math::SquareRoot(x * x + y * y + z * z + w * w, 6);
    }

    FORCEINLINE float LengthFast() const
    {
        return Math::FastSquareRoot(x * x + y * y + z * z + w * w);
    }

    FORCEINLINE float LengthSqr() const
    {
        return (x * x + y * y + z * z + w * w);
    }

// ----- Multiple irrelevant things inbetween -----

    FORCEINLINE static float Length(const Vector4& vec)
    {
        return Math::SquareRoot(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z + vec.w * vec.w, 6);
    }

    FORCEINLINE static float LengthFast(const Vector4& vec)
    {
        return Math::FastSquareRoot(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z + vec.w * vec.w);
    }

    FORCEINLINE static float LengthSqr(const Vector4& vec)
    {
        return (vec.x * vec.x + vec.y * vec.y + vec.z * vec.z + vec.w * vec.w);
    }

There shouldn't be any errors for as much as I am aware, but instead, I am getting these:

1>vector2.obj : error LNK2005: "float __cdecl Math::FastInverseSquareRoot(float)" (?FastInverseSquareRoot@Math@@YAMM@Z) already defined in vector4.obj
1>vector2.obj : error LNK2005: "float __cdecl Math::FastSquareRoot(float)" (?FastSquareRoot@Math@@YAMM@Z) already defined in vector4.obj
1>vector2.obj : error LNK2005: "float __cdecl Math::InverseSquareRoot(float,int)" (?InverseSquareRoot@Math@@YAMMH@Z) already defined in vector4.obj
1>vector2.obj : error LNK2005: "float __cdecl Math::SquareRoot(float,int)" (?SquareRoot@Math@@YAMMH@Z) already defined in vector4.obj
1>vector3.obj : error LNK2005: "float __cdecl Math::FastInverseSquareRoot(float)" (?FastInverseSquareRoot@Math@@YAMM@Z) already defined in vector4.obj
1>vector3.obj : error LNK2005: "float __cdecl Math::FastSquareRoot(float)" (?FastSquareRoot@Math@@YAMM@Z) already defined in vector4.obj
1>vector3.obj : error LNK2005: "float __cdecl Math::InverseSquareRoot(float,int)" (?InverseSquareRoot@Math@@YAMMH@Z) already defined in vector4.obj
1>vector3.obj : error LNK2005: "float __cdecl Math::SquareRoot(float,int)" (?SquareRoot@Math@@YAMMH@Z) already defined in vector4.obj
SleepyMode
  • 120
  • 11
  • 2
    My advice is don't define functions in your headers. – drescherjm Jul 05 '19 at 20:16
  • 5
    Every translation unit that includes this header will define its own version of all these functions, resulting in your link failures. Remember, an `#include` of something is as if your `.cpp` contains this included text, verbatim. So you now have the same function defined in a bazillion `.cpp`s, so your linker LOLs at you. – Sam Varshavchik Jul 05 '19 at 20:16

0 Answers0