spnda / fastgltf

A modern C++17 glTF 2.0 library focused on speed, correctness, and usability
https://fastgltf.readthedocs.io/v0.8.x/
MIT License
275 stars 42 forks source link

Myriad syntax issues when trying to include parser.hpp #40

Closed NickDriscoll closed 8 months ago

NickDriscoll commented 9 months ago

I added fastgltf 0.6.0 as a dependency to my project by adding the source as a subdirectory in CMake, after which building was fine. However, when I tried to add "#include <fastgltf/parser.hpp>" to a source file, I was treated to a litany of syntax errors coming from util.hpp:

E:\game_projects\ProRender\fastgltf\include\fastgltf\util.hpp(126,31): error C2146: syntax error: missing ')' before identifier 'a' [E:\game_project s\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\util.hpp(126,31): error C2365: 'T': redefinition; previous definition was 'template parameter' [E:\game_projects\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\util.hpp(126,31): error C2061: syntax error: identifier 'a' [E:\game_projects\ProRender\build\P roRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\util.hpp(126,31): error C2059: syntax error: ')' [E:\game_projects\ProRender\build\ProRender\Pr oRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\util.hpp(126,31): error C2146: syntax error: missing ')' before identifier 'b' [E:\game_project s\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\util.hpp(126,31): error C2146: syntax error: missing ';' before identifier 'b' [E:\game_project s\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\util.hpp(126,54): error C2143: syntax error: missing ';' before '{' [E:\game_projects\ProRender \build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\util.hpp(126,54): error C2447: '{': missing function header (old-style formal list?) [E:\game_p rojects\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(725,75): error C2589: '(': illegal token on right side of '::' [E:\game_projects\ProR ender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(725,1): error C2062: type 'unknown-type' unexpected [E:\game_projects\ProRender\build \ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(725,39): error C2080: 'missing_value': the type for 'auto' can only be deduced from a single initializer expression [E:\game_projects\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(725,39): error C2789: 'fastgltf::OptionalFlagValue<size_t,void>::missing_value': an o bject of const-qualified type must be initialized [E:\game_projects\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(725,1): error C2059: syntax error: ')' [E:\game_projects\ProRender\build\ProRender\Pr oRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(742,114): error C2589: '(': illegal token on right side of '::' [E:\game_projects\Pro Render\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(742,1): error C2062: type 'unknown-type' unexpected [E:\game_projects\ProRender\build \ProRender\ProRender.vcxproj] E:\gameprojects\ProRender\fastgltf\include\fastgltf\types.hpp(742,1): error C2144: syntax error: 'unknown-type' should be preceded by '(' [E:\game projects\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(742,1): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [E:\game_projects\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(742,1): fatal error C1903: unable to recover from previous error(s); stopping compil ation [E:\game_projects\ProRender\build\ProRender\ProRender.vcxproj]

I'm targeting C++20 using MSVC as my compiler. Strangely, while VSCode agrees that the hpp file is littered with syntax errors, it disagrees on the details. I have C++20 set everywhere as the standard I'm using, so I just don't know.

spnda commented 9 months ago

Are you on a recent version of VS/MSVC? Im pretty sure it compiles fine for other people, so perhaps it's a configuration issue.

Is that the entire output log? If so it seems like it thinks the concept is a function and then gets confused with the template parameters. That would strongly suggest you're on an old version of the compiler that doesn't properly support C++20. Though I can't test myself right now and that's only a guess.

NickDriscoll commented 9 months ago

I just updated my MSVC and I'm actually seeing more errors as a result. I didn't post the entire output log originally, just the error messages. I'll attach the full log of this run here, and below I'll paste what look like the relevant errors:

"E:\game_projects\ProRender\build\ProRender.sln" (default target) (1) -> "E:\game_projects\ProRender\build\ProRender\ProRender.vcxproj" (default target) (6) -> (ClCompile target) -> E:\game_projects\ProRender\fastgltf\include\fastgltf\util.hpp(126,31): error C2146: syntax error: missing ')' before identifier 'a' [E:\game_project s\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\util.hpp(126,31): error C2365: 'T': redefinition; previous definition was 'template parameter' [E:\game_projects\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\util.hpp(126,31): error C2061: syntax error: identifier 'a' [E:\game_projects\ProRender\build\P roRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\util.hpp(126,31): error C2059: syntax error: ')' [E:\game_projects\ProRender\build\ProRender\Pr oRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\util.hpp(126,31): error C2146: syntax error: missing ')' before identifier 'b' [E:\game_project s\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\util.hpp(126,31): error C2146: syntax error: missing ';' before identifier 'b' [E:\game_project s\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\util.hpp(126,54): error C2143: syntax error: missing ';' before '{' [E:\game_projects\ProRender \build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\util.hpp(126,54): error C2447: '{': missing function header (old-style formal list?) [E:\game_p rojects\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(725,75): error C2589: '(': illegal token on right side of '::' [E:\game_projects\ProR ender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(725,41): error C2062: type 'unknown-type' unexpected [E:\game_projects\ProRender\buil d\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(725,39): error C2080: 'missing_value': the type for 'auto' can only be deduced from a single initializer expression [E:\game_projects\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(725,39): error C2789: 'fastgltf::OptionalFlagValue<size_t,void>::missing_value': an o bject of const-qualified type must be initialized [E:\game_projects\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(725,75): error C2059: syntax error: ')' [E:\game_projects\ProRender\build\ProRender\P roRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(742,114): error C2589: '(': illegal token on right side of '::' [E:\game_projects\Pro Render\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(742,61): error C2062: type 'unknown-type' unexpected [E:\game_projects\ProRender\buil d\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(742,61): error C2144: syntax error: 'unknown-type' should be preceded by '(' [E:\game _projects\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(742,1): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [E:\game_projects\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(742,119): error C2059: syntax error: ')' [E:\game_projects\ProRender\build\ProRender\ ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(747,126): error C2589: '(': illegal token on right side of '::' [E:\game_projects\Pro Render\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(747,67): error C2062: type 'unknown-type' unexpected [E:\game_projects\ProRender\buil d\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(747,67): error C2144: syntax error: 'unknown-type' should be preceded by '(' [E:\game _projects\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(747,1): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [E:\game_projects\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(747,131): error C2059: syntax error: ')' [E:\game_projects\ProRender\build\ProRender\ ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(1109,85): error C2589: '(': illegal token on right side of '::' [E:\game_projects\Pro Render\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(1109,51): error C2062: type 'unknown-type' unexpected [E:\game_projects\ProRender\bui ld\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(1109,85): error C2059: syntax error: ')' [E:\game_projects\ProRender\build\ProRender\ ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(1115,48): error C2131: expression did not evaluate to a constant [E:\game_projects\Pr oRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(1158,41): error C2131: expression did not evaluate to a constant [E:\game_projects\Pr oRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(991,86): error C2794: 'missing_value': is not a member of any direct or indirect base class of 'fastgltf::OptionalFlagValue<fastgltf::Filter,void>' [E:\game_projects\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(1271,6): error C2938: 'fastgltf::Optional' : Failed to specialize alias template [E:\ game_projects\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(1272,6): error C2938: 'fastgltf::Optional' : Failed to specialize alias template [E:\ game_projects\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(991,86): error C2794: 'missing_value': is not a member of any direct or indirect base class of 'fastgltf::OptionalFlagValue<fastgltf::BufferTarget,void>' [E:\game_projects\ProRender\build\ProRender\ProRender.vcxproj] E:\game_projects\ProRender\fastgltf\include\fastgltf\types.hpp(1693,9): error C2938: 'fastgltf::Optional' : Failed to specialize alias template [E:\ game_projects\ProRender\build\ProRender\ProRender.vcxproj]

NickDriscoll commented 9 months ago

I bumped the version to the just-released 0.6.1 to no effect, as well.

spnda commented 9 months ago

I just updated my MSVC and I'm actually seeing more errors as a result.

What version exactly? I just tested compiling the GL example with Visual Studio 17.8.3 through CMake and having everything set to C++20 and it compiles perfectly fine with a single warning about the deprecation of u8path.

It does seem like there might be something messed up with your configuration; perhaps there's some issue with the configuration of the C++ version in your project. I still think it's failing to parse the concept correctly and then gets confused with the template for some reason.

NickDriscoll commented 9 months ago

"msbuild -version" reports 17.8.3.51904 I believe MSVC itself is version 14.38.33130 based on the filepath to cl.exe, but I'm not sure.

NickDriscoll commented 8 months ago

In the interest of putting the compiler version issue to bed, here's a compile command for a source file including fastgltf/parser.hpp:

C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\bin\HostX64\x64\CL.exe /c /IC:\VulkanSDK\1.3.261.1\Include /IE:\cpp_libs\hlslpp\include /IE:\game_projects\ProRender\imgui /IE:\game_projects\ProRender\fastgltf\include /Zi /nologo /W3 /WX- /diagnostics:column /Od /Ob0 /D _MBCS /D WIN32 /D _WINDOWS /D "CMAKE_INTDIR=\"Debug\"" /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /GR /std:c++20 /Fo"ProRender.dir\Debug\" /Fd"ProRender.dir\Debug\vc143.pdb" /external:W0 /Gd /TP /errorReport:queue /external:I "E:/cpp_libs/SDL2-2.28.2/cmake/../include" E:\game_projects\ProRender\ProRender\ProRender.cpp

The /std:c++20 flag is being passed, and my compiler is at the latest version. Some other thing is the problem.

spnda commented 8 months ago

Could you perhaps try and replace the following lines with #define FASTGLTF_CPP_20 0? https://github.com/spnda/fastgltf/blob/0d02611ddfc9e67cfde8158ee8099163ffd29f7a/include/fastgltf/util.hpp#L42-L46

That should disable the use of concepts in fastgltf, and would confirm my suspicion that there's something up with the concepts in util.hpp which are breaking compilation. If that ends up working, you can safely keep those changes locally until I have figured out the root cause and fixed it.

NickDriscoll commented 8 months ago

I forced FASTGLTF_CPP_20 == 0 but I'm still getting the exact same compile errors.

spnda commented 8 months ago

I would strongly suggest you look at the file with some IDE. I think there might be something going on with macros or other previous includes which are messing up the file. I (and others) cannot reproduce this locally at all, so I'm fairly sure it's something with your project which is causing these errors. I'm afraid with the current information I cannot really help you at all.

NickDriscoll commented 8 months ago

Um I am looking at the file(s) with an IDE... Does VSCode not count as an IDE? Its linter is set to C++20, and it also vomits an avalanche of syntax errors. I guess I'll start reading the library source later tonight to figure out what's going on.

spnda commented 8 months ago

I was saying to read the source with an IDE (also VSCode if set up correctly :) ) as they can often show macros being used, as I think something like that is messing this up. Would have a similar effect to clang -E file.cpp, which would show the preprocessed file. Also, might be worth checking if this error happens while compiling fastgltf.cpp, or when compiling one of your source files. This is an important distinction and could help eliminate any issues. Also, if thats the case, you could try including fastgltf first and see what happens.

NickDriscoll commented 8 months ago

So good news first: changing the include order does fix the problem.

I don't understand the cause, but after some experimenting it looks like the problem is triggered by including the file after vk_mem_alloc.h from VMA

But just accepting I need to include vma late solves my specific issue. Thank you.

spnda commented 8 months ago

I just did some work a personal project that uses fastgltf and I found exactly the same issue that you were reporting, and I found it to be exactly what I predicted it to be: image

The VMA header is including Windows.h which contains a macro for min and max, which is of course breaking the max() function from fastgltf. This is why I asked you to look at this through an IDE as it shows these macro replacements as shown in the above image.