PixarAnimationStudios / OpenSubdiv

An Open-Source subdivision surface library.
graphics.pixar.com/opensubdiv
Other
2.9k stars 561 forks source link

error: arithmetic on a pointer to an incomplete type 'OpenSubdiv::v3_5_0::Far::PatchTable::PatchArray' #1288

Closed thomthom closed 1 year ago

thomthom commented 1 year ago

I have been building OSD for my project on MSVC and Apple Clang for years. Recently I've run into a few issues with Apple Clang that prompted me to try to use LLVM Clang instead.

I'm running into a strange error:

[build] FAILED: ThirdParty/OpenSubdiv/opensubdiv/far/CMakeFiles/far_obj.dir/patchTable.cpp.o 
[build] /usr/local/opt/llvm/bin/clang++ -DOPENSUBDIV_VERSION_STRING=\"3.5.0\" -I/Users/thomas/SourceTree/subd/ThirdParty/OpenSubdiv/opensubdiv -g -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk -mmacosx-version-min=10.9   -Wall -Wextra -Wno-invalid-offsetof -Wno-strict-aliasing -Wno-overloaded-virtual -fPIC -Wno-error -Wno-deprecated-copy -Wno-format-pedantic -Wno-gnu-zero-variadic-macro-arguments -Wno-unused-function -Wno-unused-parameter -std=c++20 -MD -MT ThirdParty/OpenSubdiv/opensubdiv/far/CMakeFiles/far_obj.dir/patchTable.cpp.o -MF ThirdParty/OpenSubdiv/opensubdiv/far/CMakeFiles/far_obj.dir/patchTable.cpp.o.d -o ThirdParty/OpenSubdiv/opensubdiv/far/CMakeFiles/far_obj.dir/patchTable.cpp.o -c /Users/thomas/SourceTree/subd/ThirdParty/OpenSubdiv/opensubdiv/far/patchTable.cpp
[build] In file included from /Users/thomas/SourceTree/subd/ThirdParty/OpenSubdiv/opensubdiv/far/patchTable.cpp:25:
[build] In file included from /Users/thomas/SourceTree/subd/ThirdParty/OpenSubdiv/opensubdiv/far/../far/patchTable.h:30:
[build] In file included from /Users/thomas/SourceTree/subd/ThirdParty/OpenSubdiv/opensubdiv/far/../far/patchDescriptor.h:30:
[build] In file included from /Users/thomas/SourceTree/subd/ThirdParty/OpenSubdiv/opensubdiv/far/../far/types.h:30:
[build] In file included from /Users/thomas/SourceTree/subd/ThirdParty/OpenSubdiv/opensubdiv/far/../vtr/types.h:31:
[build] /usr/local/opt/llvm/bin/../include/c++/v1/vector:540:52: error: arithmetic on a pointer to an incomplete type 'OpenSubdiv::v3_5_0::Far::PatchTable::PatchArray'
[build]         {return static_cast<size_type>(__end_cap() - this->__begin_);}
[build]                                        ~~~~~~~~~~~ ^
[build] /usr/local/opt/llvm/bin/../include/c++/v1/vector:760:56: note: in instantiation of member function 'std::vector<OpenSubdiv::v3_5_0::Far::PatchTable::PatchArray>::capacity' requested here
[build]       __annotate_contiguous_container(data(), data() + capacity(),
[build]                                                        ^
[build] /usr/local/opt/llvm/bin/../include/c++/v1/vector:431:7: note: in instantiation of member function 'std::vector<OpenSubdiv::v3_5_0::Far::PatchTable::PatchArray>::__annotate_delete' requested here
[build]       __annotate_delete();
[build]       ^
[build] /Users/thomas/SourceTree/subd/ThirdParty/OpenSubdiv/opensubdiv/far/patchTable.cpp:37:13: note: in instantiation of member function 'std::vector<OpenSubdiv::v3_5_0::Far::PatchTable::PatchArray>::~vector' requested here
[build] PatchTable::PatchTable(int maxvalence) :
[build]             ^
[build] /Users/thomas/SourceTree/subd/ThirdParty/OpenSubdiv/opensubdiv/far/../far/patchTable.h:549:12: note: forward declaration of 'OpenSubdiv::v3_5_0::Far::PatchTable::PatchArray'
[build]     struct PatchArray;
[build]            ^
[build] In file included from /Users/thomas/SourceTree/subd/ThirdParty/OpenSubdiv/opensubdiv/far/patchTable.cpp:25:

(...)

build] /Users/thomas/SourceTree/subd/ThirdParty/OpenSubdiv/opensubdiv/far/../far/patchTable.h:577:12: note: forward declaration of 'OpenSubdiv::v3_5_0::Far::PatchTable::FVarPatchChannel'
[build]     struct FVarPatchChannel;
[build]            ^
[build] fatal error: too many errors emitted, stopping now [-ferror-limit=]
[build] 20 errors generated.

I don't have a minimal repo yet. I build OSD with CPU support only, so I don't have all the libs setup to build everything. In testing with Examples and OpenGL on I was not able to reproduce.

I'm wondering if anyone has encountered something similar before and could provide some pointers on why this fails with this particular compiler, but works in others. Or some suggestions to what I might try to narrow this down?

thomthom commented 1 year ago

I just tested this on a Clang build (14.0.5 GNU CLI from VS 2022 installation) on Windows and I'm getting similar error there about incomplete type for PatchArray.

thomthom commented 1 year ago

I've replicated a minimal example of what PatchTable and PatchTable::PatchArray does;

// foo.h
#pragma once

#include <vector>

class Foo
{
private:
  struct Bar;
  typedef std::vector<Bar> BarVector;

  BarVector bars_;
};
// foo.cpp
#include "foo.h"

struct Foo::Bar
{
  int biz;
  int baz;
};

I get very similar error:

[build] In file included from C:/Users/Thomas/SourceTree/cmake-playground/main.cpp:1:
[build] In file included from C:/Users/Thomas/SourceTree/cmake-playground/foo.h:3:
[build] In file included from C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\vector:11:
[build] In file included from C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\xmemory:14:
[build] In file included from C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\new:11:
[build] In file included from C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\exception:12:
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\type_traits:780:50: error: incomplete type 'Foo::Bar' used in type trait expression
[build] struct is_trivially_destructible : bool_constant<__is_trivially_destructible(_Ty)> {
[build]                                                  ^
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\type_traits:59:53: note: in instantiation of template class 'std::is_trivially_destructible<Foo::Bar>' requested here
[build] struct conjunction<_First, _Rest...> : _Conjunction<_First::value, _First, _Rest...>::type {
[build]                                                     ^
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\type_traits:64:44: note: in instantiation of template class 'std::conjunction<std::is_trivially_destructible<Foo::Bar>, std::disjunction<std::_Is_default_allocator<std::allocator<Foo::Bar>>, std::_Has_no_alloc_destroy<std::allocator<Foo::Bar>, Foo::Bar *>>>' requested here
[build] _INLINE_VAR constexpr bool conjunction_v = conjunction<_Traits...>::value;
[build]                                            ^
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\xmemory:947:20: note: in instantiation of variable template specialization 'std::conjunction_v<std::is_trivially_destructible<Foo::Bar>, std::disjunction<std::_Is_default_allocator<std::allocator<Foo::Bar>>, std::_Has_no_alloc_destroy<std::allocator<Foo::Bar>, Foo::Bar *>>>' requested here
[build]     if constexpr (!conjunction_v<is_trivially_destructible<_Ty>, _Uses_default_destroy<_Alloc, _Ty*>>) {
[build]                    ^
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\vector:1907:13: note: in instantiation of function template specialization 'std::_Destroy_range<std::allocator<Foo::Bar>>' requested here
[build]             _Destroy_range(_Myfirst, _Mylast, _Al);
[build]             ^
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\vector:807:9: note: in instantiation of member function 'std::vector<Foo::Bar>::_Tidy' requested here
[build]         _Tidy();
[build]         ^
[build] C:/Users/Thomas/SourceTree/cmake-playground/foo.h:5:7: note: in instantiation of member function 'std::vector<Foo::Bar>::~vector' requested here
[build] class Foo
[build]       ^
[build] C:/Users/Thomas/SourceTree/cmake-playground/main.cpp:5:7: note: in implicit default constructor for 'Foo' first required here
[build]   Foo foo;
[build]       ^
[build] C:/Users/Thomas/SourceTree/cmake-playground/foo.h:8:10: note: forward declaration of 'Foo::Bar'
[build]   struct Bar;
[build]          ^
[build] In file included from C:/Users/Thomas/SourceTree/cmake-playground/main.cpp:1:
[build] In file included from C:/Users/Thomas/SourceTree/cmake-playground/foo.h:3:
[build] In file included from C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\vector:11:
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\xmemory:947:20: error: constexpr if condition is not a constant expression
[build]     if constexpr (!conjunction_v<is_trivially_destructible<_Ty>, _Uses_default_destroy<_Alloc, _Ty*>>) {
[build]                   ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\vector:1907:13: note: in instantiation of function template specialization 'std::_Destroy_range<std::allocator<Foo::Bar>>' requested here
[build]             _Destroy_range(_Myfirst, _Mylast, _Al);
[build]             ^
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\vector:807:9: note: in instantiation of member function 'std::vector<Foo::Bar>::_Tidy' requested here
[build]         _Tidy();
[build]         ^
[build] C:/Users/Thomas/SourceTree/cmake-playground/foo.h:5:7: note: in instantiation of member function 'std::vector<Foo::Bar>::~vector' requested here
[build] class Foo
[build]       ^
[build] C:/Users/Thomas/SourceTree/cmake-playground/main.cpp:5:7: note: in implicit default constructor for 'Foo' first required here
[build]   Foo foo;
[build]       ^
[build] In file included from C:/Users/Thomas/SourceTree/cmake-playground/main.cpp:1:
[build] In file included from C:/Users/Thomas/SourceTree/cmake-playground/foo.h:3:
[build] In file included from C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\vector:11:
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\xmemory:948:33: error: arithmetic on a pointer to an incomplete type 'std::_Default_allocator_traits<std::allocator<Foo::Bar>>::value_type' (aka 'Foo::Bar')
[build]         for (; _First != _Last; ++_First) {
[build]                                 ^ ~~~~~~
[build] C:/Users/Thomas/SourceTree/cmake-playground/foo.h:8:10: note: forward declaration of 'Foo::Bar'
[build]   struct Bar;
[build]          ^
[build] In file included from C:/Users/Thomas/SourceTree/cmake-playground/main.cpp:1:
[build] In file included from C:/Users/Thomas/SourceTree/cmake-playground/foo.h:3:
[build] In file included from C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\vector:11:
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\xmemory:69:56: error: invalid application of 'alignof' to an incomplete type 'Foo::Bar'
[build] _INLINE_VAR constexpr size_t _New_alignof = (_STD max)(alignof(_Ty),
[build]                                                        ^~~~~~~~~~~~
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\xmemory:832:21: note: in instantiation of variable template specialization 'std::_New_alignof<Foo::Bar>' requested here
[build]         _Deallocate<_New_alignof<_Ty>>(_Ptr, sizeof(_Ty) * _Count);
[build]                     ^
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\vector:1909:17: note: in instantiation of member function 'std::allocator<Foo::Bar>::deallocate' requested here
[build]             _Al.deallocate(_Myfirst, static_cast<size_type>(_Myend - _Myfirst));
[build]                 ^
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\vector:807:9: note: in instantiation of member function 'std::vector<Foo::Bar>::_Tidy' requested here
[build]         _Tidy();
[build]         ^
[build] C:/Users/Thomas/SourceTree/cmake-playground/foo.h:5:7: note: in instantiation of member function 'std::vector<Foo::Bar>::~vector' requested here
[build] class Foo
[build]       ^
[build] C:/Users/Thomas/SourceTree/cmake-playground/main.cpp:5:7: note: in implicit default constructor for 'Foo' first required here
[build]   Foo foo;
[build]       ^
[build] C:/Users/Thomas/SourceTree/cmake-playground/foo.h:8:10: note: forward declaration of 'Foo::Bar'
[build]   struct Bar;
[build]          ^
[build] In file included from C:/Users/Thomas/SourceTree/cmake-playground/main.cpp:1:
[build] In file included from C:/Users/Thomas/SourceTree/cmake-playground/foo.h:3:
[build] In file included from C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\vector:11:
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\xmemory:832:46: error: invalid application of 'sizeof' to an incomplete type 'Foo::Bar'
[build]         _Deallocate<_New_alignof<_Ty>>(_Ptr, sizeof(_Ty) * _Count);
[build]                                              ^~~~~~~~~~~
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\vector:1909:17: note: in instantiation of member function 'std::allocator<Foo::Bar>::deallocate' requested here
[build]             _Al.deallocate(_Myfirst, static_cast<size_type>(_Myend - _Myfirst));
[build]                 ^
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\vector:807:9: note: in instantiation of member function 'std::vector<Foo::Bar>::_Tidy' requested here
[build]         _Tidy();
[build]         ^
[build] C:/Users/Thomas/SourceTree/cmake-playground/foo.h:5:7: note: in instantiation of member function 'std::vector<Foo::Bar>::~vector' requested here
[build] class Foo
[build]       ^
[build] C:/Users/Thomas/SourceTree/cmake-playground/main.cpp:5:7: note: in implicit default constructor for 'Foo' first required here
[build]   Foo foo;
[build]       ^
[build] C:/Users/Thomas/SourceTree/cmake-playground/foo.h:8:10: note: forward declaration of 'Foo::Bar'
[build]   struct Bar;
[build]          ^
[build] In file included from C:/Users/Thomas/SourceTree/cmake-playground/main.cpp:1:
[build] In file included from C:/Users/Thomas/SourceTree/cmake-playground/foo.h:3:
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\vector:1909:68: error: arithmetic on a pointer to an incomplete type 'std::_Default_allocator_traits<std::allocator<Foo::Bar>>::value_type' (aka 'Foo::Bar')
[build]             _Al.deallocate(_Myfirst, static_cast<size_type>(_Myend - _Myfirst));
[build]                                                             ~~~~~~ ^
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\vector:807:9: note: in instantiation of member function 'std::vector<Foo::Bar>::_Tidy' requested here
[build]         _Tidy();
[build]         ^
[build] C:/Users/Thomas/SourceTree/cmake-playground/foo.h:5:7: note: in instantiation of member function 'std::vector<Foo::Bar>::~vector' requested here
[build] class Foo
[build]       ^
[build] C:/Users/Thomas/SourceTree/cmake-playground/main.cpp:5:7: note: in implicit default constructor for 'Foo' first required here
[build]   Foo foo;
[build]       ^
[build] C:/Users/Thomas/SourceTree/cmake-playground/foo.h:8:10: note: forward declaration of 'Foo::Bar'
[build]   struct Bar;
[build]          ^
[build] 6 errors generated.

However, in this case I also get errors while compiling with MSVC, so I don't know why I'm not seeing the same behaviour with OSD in that regard.

MSVC:

[build]   foo.cpp
[build]   main.cpp
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\vector(1909,1): error C2036: 'Foo::Bar *': unknown size [C:\Users\Thomas\SourceTree\cmake-playground\build\example.vcxproj]
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\vector(1897): message : while compiling class template member function 'void std::vector<Foo::Bar,std::allocator<Foo::Bar>>::_Tidy(void) noexcept' [C:\Users\Thomas\SourceTree\cmake-playground\build\example.vcxproj]
[build] C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.33.31629\include\vector(807): message : see reference to function template instantiation 'void std::vector<Foo::Bar,std::allocator<Foo::Bar>>::_Tidy(void) noexcept' being compiled [C:\Users\Thomas\SourceTree\cmake-playground\build\example.vcxproj]
[build] C:\Users\Thomas\SourceTree\cmake-playground\foo.h(11): message : see reference to class template instantiation 'std::vector<Foo::Bar,std::allocator<Foo::Bar>>' being compiled 

In either case, the compiler isn't liking the forward declaration of the struct that is used in the template initialization of the vector. Errors seem to original from const expressions.

I didn't think you could forward declare the types used in members for types like vector. So now, instead of wondering why this fails with Clang only in OSD, I'm wondering why it works at all in any compiler.

https://stackoverflow.com/questions/37346/why-cant-a-forward-declaration-be-used-for-a-stdvector

thomthom commented 1 year ago

When I replaced the forward declarations for struct PatchArray; and struct FVarPatchChannel; with their definitions then everything builds fine in my project. From what I understand the forward declaration of types that is used in vector is not allowed.

If I can manage to reproduce this with a build of only OSD itself I can make a PR that corrects this.

davidgyu commented 1 year ago

Thanks @thomthom! This seems like the same underlying issue as PR #1275

thomthom commented 1 year ago

Ah, yes! Exactly. That PR looks to be fixing what I'm running into. hmm... this relates to C++20..? 🤔

thomthom commented 1 year ago

This issue can be considered a dup of #1275. (I'll certainly be fixed by that PR)

davidgyu commented 1 year ago

Filed as internal issue #OSD-400

davidgyu commented 1 year ago

Fixed by merging #1275