Why does std::make_unique work in Visual Studio but not g++ on linux?

Sep 21, 2020 at 8:56pm
I've got a very simple piece of code that runs prefectly on Window's visual studio but doesn't on Linux (g++).

I get the following error on Linux:

1
2
3
4
5
/usr/bin/ld: ../builds/Debug-x86_64/engine/libengine.a(app.o): in function `std::_MakeUniq<Engine::Profiler>::__single_object std::make_unique<Engine::Profiler>()':
/usr/include/c++/9/bits/unique_ptr.h:857: undefined reference to `Engine::Profiler::Profiler()'

/usr/bin/ld: ../builds/Debug-x86_64/engine/libengine.a(app.o): in function `std::default_delete<Engine::Profiler>::operator()(Engine::Profiler*) const':
/usr/include/c++/9/bits/unique_ptr.h:81: undefined reference to `Engine::Profiler::~Profiler()'


Again it works on Windows, but not sure what I'm doing wrong with G++. By the way, I'm using C++17 and make_unique works with another class I got on Linux, but not this Profiler class in particular.

I'll share the code below. Thanks for reading, hope this makes sense.

1
2
3
4
5
6
//app.h
private:
std::unique_ptr<Profiler> updateProfiler;

//app.cpp
updateProfiler = std::make_unique<Profiler>(); // This doesn't work. 


And the Profiler class looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//profiler.h
#pragma once
#include <string>
namespace Engine {
	class Profiler {
	public:

		//Profiler(std::string profilerName = "Unnamed Profiler");
		Profiler();
		~Profiler();

		void Start();
		void Stop();
		double GetTotalTime(double divisor);
		double GetTotalCalculatedTime();

	private:
		std::string name;
		unsigned int checks = 0;
		double totalTime = 0.0;
		double startTime = 0.0;
		double totalCalcTime = 0.0;
	};
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// profiler.cpp
#include "enginepch.h"
#include "profiler.h"
#include <engine/time/time.h>
#include <engine/core/app.h>

namespace Engine {

	//Profiler::Profiler(std::string profilerName) {
	Profiler::Profiler() {

		//name = profilerName;
	}

	Profiler::~Profiler() {

	}

	void Profiler::Start() {
		auto& time = App::Get().GetTime();
		startTime = time.GetCurrentTime();
	}

	void Profiler::Stop() {
		if (startTime != 0) {
			auto& time = App::Get().GetTime();
			checks += 1;
			totalTime += (time.GetCurrentTime() - startTime);
			startTime = 0;
		}
	}

	double Profiler::GetTotalCalculatedTime() {
		return totalCalcTime;
	}

	double Profiler::GetTotalTime(double divisor) {
		divisor = (divisor == 0) ? checks : divisor;
		double result = (totalTime == 0 && divisor == 0.0) ? 0.0 : (1000.0 * totalTime) / ((double)divisor);

		checks = 0;
		totalTime = 0.0;
		totalCalcTime = result;
		return result;
	}
}
Last edited on Sep 21, 2020 at 8:57pm
Sep 21, 2020 at 9:06pm
any chance its just the order of your includes? Visual studio, in my experience, sometimes handles includes in a more friendly way that it strictly should, breaking things if you move off the platform.
Last edited on Sep 21, 2020 at 9:07pm
Sep 21, 2020 at 9:08pm
Hey Jonnin! Thanks for the quick reply. You mean in the profiler class? I could try switching them around, but is it possible it works on Visual Studio and not linux?
Sep 21, 2020 at 9:34pm
@jonnin You pointed me to the right direction! It wasn't the order but a missing header in my make file. Thank you! This solved :D
Topic archived. No new replies allowed.