Skip to content
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

"Rule of 5" copy/assign/move declarations #601

Merged
merged 10 commits into from
Nov 14, 2019

Conversation

cary-ilm
Copy link
Member

@cary-ilm cary-ilm commented Oct 25, 2019

  • Added =delete constructor/operator=/move to all internal classes (declared inside a .cpp)
  • Added =delete constructor/operator=/move to all external classes (in .h files) for which the operation is not trivial (i.e. class has dynamically-allocated fields), and is currently not needed.
  • Added =default constructor/operator=/move to TypedAttribute class, since that behavior is reasonable.
  • added if(this!=&other) in operator=
  • restructured IMF_STD_ATTRIBUTE

Signed-off-by: Cary Phillips <cary@ilm.com>
Signed-off-by: Cary Phillips <cary@ilm.com>
- Added =delete copy constructors and assignment operators
- Added =default destructors
- check for &other==this in assignment operator

Signed-off-by: Cary Phillips <cary@ilm.com>
- copy constructors and assignment operators declared = delete
- use of ## is macro definition

Signed-off-by: Cary Phillips <cary@ilm.com>
- copy constructor and assignment operator declared = delete
- compare this==&other in assignment operator

Signed-off-by: Cary Phillips <cary@ilm.com>
- removed const from operator= =delete
- added move-assign/move-constructor = delete

Signed-off-by: Cary Phillips <cary@ilm.com>
@xlietz
Copy link
Contributor

xlietz commented Oct 25, 2019

You probably saw that this is generating an undefined move constructor in the Windows build when linking testMultiPartSharedAttributes.obj. I suspect this is related to MSVC compiler generating a move constructor while gcc/clang are doing some optimization akin to copy elision. Possibly related to line 146 in testMultiPartSharedAttributes.cpp where header is an xvalue in the call to headers.push_back(header) but I haven't traced it to where the TypedAttr move constructor would actually be invoked. Just a guess as I haven't had time to test it!

2019-10-25T22:00:12.5717991Z testMultiPartSharedAttributes.obj : error LNK2019: unresolved external symbol "public: __thiscall Imf_2_4::TypedAttribute::TypedAttribute(class Imf_2_4::TypedAttribute const &&)"
(??0?$TypedAttribute@H@Imf_2_4@@QAE@$$QBV01@@z) referenced in function "private: class Imf_2_4::TypedAttribute * __thiscall std::vector<class Imf_2_4::TypedAttribute,class std::allocator<class Imf_2_4::TypedAttribute > >::_Umove(class Imf_2_4::TypedAttribute *,class Imf_2_4::TypedAttribute *,class Imf_2_4::TypedAttribute *)" (?_Umove@?$vector@V?$TypedAttribute@H@Imf_2_4@@v?$allocator@V?$TypedAttribute@H@Imf_2_4@@@std@@@std@@AAEPAV?$TypedAttribute@H@Imf_2_4@@PAV34@00@Z) [D:\a\1\s_build\OpenEXR\IlmImfTest\IlmImfTest.vcxproj]
2019-10-25T22:00:12.5718387Z D:\a\1\s_build\bin\Release\IlmImfTest.exe : fatal error LNK1120: 1 unresolved externals [D:\a\1\s_build\OpenEXR\

@cary-ilm
Copy link
Member Author

I guess in this case there's no reason to not provide the move constructor as well. These changes are taking the conservative approach - if the function isn't declared, eliminated it, as long as there's no legitimate need for it, but this presumably points to a need for it. It's worth investigating a little more, but I'll just add the move constructor.

@xlietz
Copy link
Contributor

xlietz commented Oct 26, 2019

These copy/move deletions break ABI compatibility. And possibly API compatibility when both are deleted. Just to verify, we are ok with that? Any lib user who has been invoking these copy/move constructors intentionally or unintentionally, will not be able to compile, Perhaps not a bad thing, they can add the constructor if there is legitimate need?

@lgritz
Copy link
Contributor

lgritz commented Oct 26, 2019

They are all things that shouldn't be copied or moved, so I'm ok with it.

But the potential break break in ABI compatibility means it should not be backported to 2.4.x for sure (I'm ok with ABI breaks for minor releases such as 2.4 -> 2.5; IIRC, semver only talks about API, not ABI, so I think it's not a break of semver rules for 2.5).

The potential break in API compatibility means it's probably a 3.0 feature if you want to follow strict sementic versioning.

TypedAttribute assumes that the T class supports copy/move/assign
operations, so it should, too.

Also, the move/moveassign operators for OStream/IStream incorrectly
declared their arguments as const.

Signed-off-by: Cary Phillips <cary@ilm.com>
@cary-ilm cary-ilm changed the title SonarCloud-inspired bug fixes "Rule of 5" copy/assign/move declarations Nov 3, 2019
@cary-ilm
Copy link
Member Author

cary-ilm commented Nov 3, 2019

Changed the name of the PR and edited the description, since the majority of the fixes involve copy/move/assign operations.

Copy link
Contributor

@meshula meshula left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checks out :)

@cary-ilm cary-ilm merged commit 861aad1 into AcademySoftwareFoundation:master Nov 14, 2019
@cary-ilm cary-ilm added this to the v2.5.0 milestone Apr 26, 2020
@cary-ilm cary-ilm deleted the sonar-fixes branch May 18, 2021 03:20
cary-ilm added a commit to cary-ilm/openexr that referenced this pull request Nov 19, 2024
When we implemented the "rule of 5" (PR AcademySoftwareFoundation#601) in 2019, I added code to
testAttributes.cpp to validate the behavior, specifically related to
the TypedAttribute class, but in retrospect, this code isn't reliable,
so I propose eliminating the test altogether.

The test counts invocations of the various constructors, destructors,
and move/assignment operators, expecting them to be consistent, but
compilers can optionally optimize some of these operations away,
producing inconsistent results.

In particular, a Debug build on Windows produces different results
from a Release build. Our CI has not historically tested a Windows
Debug build, which explains why we never caught this. The exact
behavior may have also changed with C++17. All the more reason to
avoid such picky tests.

This does not change the library code, only the tests.

Signed-off-by: Cary Phillips <cary@ilm.com>
cary-ilm added a commit that referenced this pull request Nov 20, 2024
When we implemented the "rule of 5" (PR #601) in 2019, I added code to
testAttributes.cpp to validate the behavior, specifically related to
the TypedAttribute class, but in retrospect, this code isn't reliable,
so I propose eliminating the test altogether.

The test counts invocations of the various constructors, destructors,
and move/assignment operators, expecting them to be consistent, but
compilers can optionally optimize some of these operations away,
producing inconsistent results.

In particular, a Debug build on Windows produces different results
from a Release build. Our CI has not historically tested a Windows
Debug build, which explains why we never caught this. The exact
behavior may have also changed with C++17. All the more reason to
avoid such picky tests.

This does not change the library code, only the tests.

Signed-off-by: Cary Phillips <cary@ilm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants