Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

World::each causes Internal compiler error if class has an implementation file #5

Closed
jkunstwald opened this issue Mar 2, 2018 · 16 comments
Labels

Comments

@jkunstwald
Copy link

This header file compiles and works perfectly:

#pragma once

#include "ECS.h"

struct TestComp {
	int x;
	int y;
};

class TestClass {
public:
	TestClass() {}
	virtual ~TestClass() = default;

	void update(ECS::World* world, float dt) {
		using namespace ECS;
		world->each<TestComp>([&](Entity* ent, ComponentHandle<TestComp> testComp) {
			testComp->x += 1;
		});

	}
};

however, as soon as an implementation file is present, for example TestClass.cpp, even if it just contains

#include "TestClass.h"

Visual Studio shows an internal compiler error (C1001) at the last line of the implementation file. This error remains whatever i do, using inline, moving the implementation to the .cpp file and so on.

Im running the latest Visual Studio enterprise 2017, v. 15.5.7

@redxdev
Copy link
Owner

redxdev commented Mar 2, 2018

I am unable to reproduce said issue in VS2017. C1001 indicates an internal compiler error, can you post the full error message? It may have to do with what optimization settings you are using. Alternatively, zip the entire project and post it here (or email it to me at sam at xbloom dot io).

An implementation file being present is likely to be a red herring, by the way. Header files are not compiled unless included by an implementation file (unless you change the default settings).

@redxdev
Copy link
Owner

redxdev commented Mar 2, 2018

Side-note: Unless you have some requirements I do not know about, I suggest making TestClass a subclass of EntitySystem (see here) and registering it via world->registerSystem() - otherwise you will have to manage calling update manually rather than just calling world->tick(deltaTime).

@jkunstwald
Copy link
Author

jkunstwald commented Mar 2, 2018

This is an empty project containing just ECS.h and a test class demonstrating the issue, for me this project fails to compile, take a look:
ECSTest.zip

There is nothing more to the error message than just "Internal compiler error". From Stackoverflow, it seems like this error is not "supposed to appear" and should be reported to Microsoft as a bug in the VC++ compiler. It might just be one but i was wondering if you ever encountered this or if it recently popped up.

Side-note: Unless you have some requirements I do not know about, I suggest making TestClass a subclass of EntitySystem (see here)- otherwise you will have to manage calling update manually rather than just calling world->tick(deltaTime).

Usually im using your classes how they're supposed to be used :) Was just trying to make the example as short as possible

@redxdev
Copy link
Owner

redxdev commented Mar 2, 2018

I'm still unable to reproduce the issue, even using your project files. It's possible I'm running a different version of the compiler (VS 15.4.1, not sure the exact compiler version) but unfortunately I can't upgrade on this machine. It's also possible that you have some setting set somewhere that changes things just enough as to trigger this error since it sounds like you might have actually hit a bug in the compiler. The best I can find is that there are some newer optimizations that might be breaking something in the compiler. Try rewriting things to be slightly different (but in effect make them do the same thing). Change the type of variables (i.e. use float or uint16_t instead of int) and see what happens, try adding code before/after the call to world->each, etc. Optimizations are fickle and if that is indeed what is causing the compiler bug then changing almost anything should change the result you get.

Maybe try the other overload for each() - use a range-based for loop instead of a lambda and see if it works. Also try using the different overloads of all() which operate similarly to each() and see if those cause the bug as well.

@jkunstwald
Copy link
Author

Huh, then this might have been just introduced in one of the last couple of updates. I have tried changing things quite a bit, this issue originally popped up in a much bigger class, the method looks something like this:

void RenderingCore::render(ECS::World* world)
{
	m_display->clear();
	m_pbrShader->use();
	m_pbrShader->updateCamera(*m_camera);

	using namespace ECS;
	world->each<Transform, Model>([&](Entity* ent, ComponentHandle<Transform> transform, ComponentHandle<Model> model) {
		m_pbrShader->setTransform(transform.get());
		model->draw();
	});

	m_cubemap->render(*m_camera);
	m_display->update();
}

where Transform and Model are both relatively large classes themselves, so there's quite a bit of variation to variable types and code before / after the call to World::each. I've also tried two different optimization levels, once off (/Od) and once on Release default (/O2). I suppose we'll just have to wait for the next VS update which hopefully fixes this issue.

@redxdev
Copy link
Owner

redxdev commented Mar 2, 2018 via email

@jkunstwald
Copy link
Author

we might have a bug report for the MSVC team

I'll wait for your reproduction first, i find it more likely that my machine / VS install is somehow broken than this actually being a VC++ bug.

@redxdev
Copy link
Owner

redxdev commented Mar 2, 2018 via email

@jkunstwald
Copy link
Author

I just tested the demo project on a different machine, also with VS 15.5.7, and i get the same error.

@redxdev
Copy link
Owner

redxdev commented Mar 2, 2018

Looks like it isn't just you. VS 15.5.7 gives me the same issue. I guess it's a bug in the compiler introduced in 15.5.

@redxdev redxdev added the bug label Mar 2, 2018
@redxdev
Copy link
Owner

redxdev commented Mar 2, 2018

Looks like adding the /P flag to the C++ compiler options lets it compile successfully. Might be good as a temporary workaround.

/P can be added manually or by going to C/C++ options -> Preprocessor -> turn on Preprocess to a File.

@jkunstwald
Copy link
Author

adding the /P flag lets it compile successfully

This instead gives me a linker error LNK1104 "Can't open main.obj". That is for the test project, in my real project its a seemingly unrelated other .obj. But good to know its not just me. Is it reasonable to submit a bug report to Microsoft?

@redxdev
Copy link
Owner

redxdev commented Mar 2, 2018 via email

@jkunstwald
Copy link
Author

Here's the bug report:
https://developercommunity.visualstudio.com/content/problem/206634/internal-compiler-error-in-vs-1557.html

@jkunstwald
Copy link
Author

The bug report has been answered, and i can confirm that it works in the 15.6 preview!

@redxdev
Copy link
Owner

redxdev commented Mar 8, 2018

Great!

@redxdev redxdev closed this as completed Mar 8, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants