Inline member function

Started by
3 comments, last by TheUnbeliever 15 years, 5 months ago
I don't know what I'm doing wrong here; I had the same issue recently, but can't remember what I did to fix it. I didn't get anywhere with reducing it to a minimal example, so I'll just show exactly what I have. material.h
#ifndef MATERIAL_H
#define MATERIAL_H

#include "Colour.h"

namespace Graphics
{
	class LightTransportParameters
	{
		float diffuse_;
		float specular_;

		void normalizeAndSetReflection(float diffuse, float specular);

	public:
		float transparency;

		LightTransportParameters(float diffuse, float specular, float transparency)
			: transparency(transparency)
		{ normalizeAndSetReflection(diffuse, specular); }

		float diffuse() { return diffuse_; }
		float specular() { return specular_; }
	};

	struct Material
	{
		LightTransportParameters lightTransportParameters;
		float refractiveIndex;

		Colour colour;

		Material(LightTransportParameters lightTransportParameters, float refractiveIndex, Colour colour)
			: lightTransportParameters(lightTransportParameters), refractiveIndex(refractiveIndex), colour(colour)
		{}
	};
}

#endif
material.cpp
#include "Floating.h"
#include "Material.h"

inline void Graphics::LightTransportParameters::normalizeAndSetReflection(float diffuse, float specular)
{
	if (Utility::floatEqual(diffuse + specular, 1.0f))
		return;

	float k = 1 / (diffuse + specular);
	diffuse *= k;
	specular *= k;

	diffuse_ = diffuse;
	specular_ = specular;
}
main.cpp
#include <iostream>
#include "Sphere.h"

int main()
{
	using namespace Graphics;
	using Maths::Vector3;

	Sphere s(Vector3(0, 0, 0), 1.0f, Material(LightTransportParameters(0.5f, 0.5f, 0.0f), 1.0f, Colour(1.0f, 0, 0)));
}
Error:
main.obj : error LNK2019: unresolved external symbol "private: void __thiscall Graphics::LightTransportParameters::normalizeAndSetReflection(float,float)" (?normalizeAndSetReflection@LightTransportParameters@Graphics@@AAEXMM@Z) referenced in function "public: __thiscall Graphics::LightTransportParameters::LightTransportParameters(float,float,float)" (??0LightTransportParameters@Graphics@@QAE@MMM@Z)
Obviously the problem is with the declaration of the inline member function, but I'm clearly missing something obvious!
[TheUnbeliever]
Advertisement
An easy and obvious solution - just remove the inline keyword! The compiler will probably inline it anyway if it's beneficial...
Construct (Free open-source game creator)
I think the problem is that the function is defined as "inline", but not declared as "inline" in the header.

Regardless of that "normalizeAndSetReflection" can never be inlined (except maybe inside of material.obj), because its definition is not in the header file.

In order to have it inlined everywhere, you have to move the definition into the header file.
Quote:Original post by AshleysBrain
An easy and obvious solution - just remove the inline keyword! The compiler will probably inline it anyway if it's beneficial...


inline methods must be visible to each translation unit that uses it. By placing your inline method in the .cpp the material translation unit is the only unit that has it visible. In your case you want to move your inline definition to the header file.

Also, I wouldn't really trust the compiler to inline methods. For across translation unit inline analysis you need to enable whole program optimizations which many compilers don't support and the ones that do don't do it very well. Aditionally, even for methods that are declared inline (or a force inline equivelent) don't always inline even when it is a good idea to inline. For example, GCC is very terrible at inling methods while Intel is very good.
Graphics Programmer - Ready At Dawn Studios
Thank you.
[TheUnbeliever]

This topic is closed to new replies.

Advertisement