-
Notifications
You must be signed in to change notification settings - Fork 193
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
vsg/utils/Builder.h isn't self-sufficient #1188
Comments
Work around vsg-dev/VulkanSceneGraph#1188 Export a class that wasn't exported properly
I have just had a look at vsg::Builder and I don't even see a default constructor, let alone a copy operator or copy constructor. I don't think there is particular value in copy constructor or assignment operator. It would be better users just created it on the heap and then shared that instance. |
I have added a default constructor to see if it affects your build and need to include Options.h d599ee2. This change is checked into VSG master. Could you try it out to see if you still need the include of Options.h? |
It's the implicitly generated copy assignment operator that causes the problem. That commit neither provides an alternative copy assignment operator nor explicitly deletes the implicit one, so the implicit one will still get generated, and still need to call I investigated further. First I tried building VSG with Next, I tried explicitly defaulting the copy assignment operator in That change was basically // Builder.h
Builder();
Builder(const Builder& rhs);
Builder& operator=(const Builder&);
protected:
virtual ~Builder();
// Builder.cpp
Builder::Builder() = default;
Builder::Builder(const Builder& rhs) = default;
Builder& Builder::operator=(const Builder&) = default;
Builder::~Builder() = default; Something weird was that it was different files complaining about different functions. I was using the default constructor and the destructor in one of these, but that one wasn't the only one complaining about the destructor, and none of the files should have been copying anything as they were just using a reference to a single instance. If every file complained about everything, or files only complained about the functions they used, it'd make more sense, but what I'm seeing makes me suspicious a compiler bug might be involved. As it only became a problem when I started consuming VSG in a DLL, I took a look at the documentation for The last thing I tried was simply adding a #include <vsg/utils/Builder.h>
with the idea that if it builds, the header's self-sufficient, and if it doesn't, then it isn't. When I build VSG as a static library, this file is fine. However, when I build it as a dynamic library, it emits the following:
and that's even with the explicitly defaulted functions for I suspect there are quite a few other places where headers only have forward declarations, and while the explicitly declared functions are all fine, the implicit functions aren't, but it's not caused symptoms because no one's tried using those headers on their own. This can be detected with a self-sufficient header check in CI or by manually doing what I did, and then if the implicit functions are supposed to be there, they can be fixed by including the necessary headers or making them explicit and having the implementation in a file with the header included, and if they're not supposed to exist, then they can be explicitly deleted. So after spending a couple of hours looking into this I've come full circle back to my original theory that it's just some headers in the VSG not being self-sufficient, and it not being noticed as it only affects compilation units that don't have extra includes that hide the problem and might need to export a definition. As an aside, this shouldn't be a weird Windows problem - GCC isn't used with |
Forward declaration is typically used to avoid circular references in the headers or to keep the include count down. The need to include <vsg/Options.h> is something that has been present with many of the VSG's .cpp's. The Windows' DLL build is what highlights the problem and I have to go in and add the vsg/Options.h include. One option might be to delete the copy and assignment operators, that way there isn't any need to implement them, and as they wouldn't typically be needed this shouldn't be an issue. There is the vsg::Object::clone() method though, which might need a null implementation if it's an issue. It would be an interesting test to try attribute ((visibility ("default"))) if only to use it as an early warnings with the Windows DLL build. I am curious if there would be any memory and performance delta, I suspect little difference. |
For Windows, it's only a potential problem for symbols explicitly marked The reason things haven't been on fire all along is that nothing's compiling the affected headers without also including the headers they implicitly depend on, until a user of VSG tries including a header and hits this. You need to compile headers on their own if you want to proactively detect this kind of problem. I can take a look at adding a self-sufficient header check to CI if you think that would be worthwhile. |
I tried an experiment on my Kubuntu 22.04 systems with g++ 11.4.0 and a modified include/vsg/core/Export.h with: # define VSG_DECLSPEC __attribute__ ((visibility ("default"))) But the library and vsgviewer application sizes are identical for with/without this change, and this applies to static and shared library builds. However, it's not entirely clear to me what changes you are expecting to be needed, I've just taken my best guess based on how I've interpreted what you mean. This is the problem having to guess rather than have an actual commit with all the required changes in place. |
To help resolve the immediate issue I have put in explicit deletion of the copy constructor and assignment operation: e0cc165 Could you try this out with vsgPhysX in the various build combinations you've been testing? |
It's that, plus adding MinGW flavours of GCC don't work the same as native Unix ones with this feature, so I'd have to drop what I was doing and reboot into Linux to switch to this tangent. I only brought it up because I realised I'd mentioned a lot of Windows-specific things and wanted to make it clear that it's the least likely platform to run into this problem rather than the only place it can happen.
It stops it complaining about the copy constructor and assignment operator, but the destructor still depends on |
When including
vsg/utils/Builder.h
in a file that doesn't also includevsg/io/Options.h
, (at least when consuming static VSG when building a DLL with MSVC 2022) it will generate an error as the compiler can't generate the implicit assignment operator forvsg::Builder
because it's only got a forward declaration forvsg::Options
, which isn't enough forvsg::ref_ptr<vsg::Options>::operator=
as it's got to callref
andunref
, soBuilder::options
breaks.I've not hit this error when building a static library with the same file and compiler, and my theory for that is that the compiler knows anyone calling it who's consuming a static library has to have the header that it can be implicitly generated from, so doesn't generate it if it's not called, whereas as I've got a class that inherits from
vsg::Builder
which isdeclspec(dllexport)
when it's built as a DLL, it's mandatory that the compiler generates the implicit assignment operator.The fix would be to include
Options.h
inBuilder.h
if it's meant to be copyable, ordelete
the assignment operators if it's not.The text was updated successfully, but these errors were encountered: