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

clang notices that constexpr can't be used on a mutating function #1242

Merged
merged 3 commits into from
Mar 21, 2022

Conversation

meshula
Copy link
Collaborator

@meshula meshula commented Mar 18, 2022

This PR fixes an issue raised by the version of Clang bundled with XCode 13.x, see below. Clang correctly notices that constexpr can't be used on a mutating function.

Users/nporcino/build/local/include/opentime/rationalTime.h:160:20: error: cannot assign to non-static data member within const member function 'operator+='
            _value = other._value + value_rescaled_to(other._rate);
            ~~~~~~ ^
/Users/nporcino/build/local/include/opentime/rationalTime.h:156:35: note: member function 'opentime::v1_0::RationalTime::operator+=' is declared const here
    constexpr RationalTime const& operator+=(RationalTime other) noexcept
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/nporcino/build/local/include/opentime/rationalTime.h:161:20: error: cannot assign to non-static data member within const member function 'operator+='
            _rate  = other._rate;
            ~~~~~  ^
/Users/nporcino/build/local/include/opentime/rationalTime.h:156:35: note: member function 'opentime::v1_0::RationalTime::operator+=' is declared const here
    constexpr RationalTime const& operator+=(RationalTime other) noexcept
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/nporcino/build/local/include/opentime/rationalTime.h:165:20: error: cannot assign to non-static data member within const member function 'operator+='
            _value += other.value_rescaled_to(_rate);
            ~~~~~~ ^
/Users/nporcino/build/local/include/opentime/rationalTime.h:156:35: note: member function 'opentime::v1_0::RationalTime::operator+=' is declared const here
    constexpr RationalTime const& operator+=(RationalTime other) noexcept
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/nporcino/build/local/include/opentime/rationalTime.h:174:20: error: cannot assign to non-static data member within const member function 'operator-='
            _value = value_rescaled_to(other._rate) - other._value;
            ~~~~~~ ^
/Users/nporcino/build/local/include/opentime/rationalTime.h:170:35: note: member function 'opentime::v1_0::RationalTime::operator-=' is declared const here
    constexpr RationalTime const& operator-=(RationalTime other) noexcept
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/nporcino/build/local/include/opentime/rationalTime.h:175:20: error: cannot assign to non-static data member within const member function 'operator-='
            _rate  = other._rate;
            ~~~~~  ^
/Users/nporcino/build/local/include/opentime/rationalTime.h:170:35: note: member function 'opentime::v1_0::RationalTime::operator-=' is declared const here
    constexpr RationalTime const& operator-=(RationalTime other) noexcept
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/nporcino/build/local/include/opentime/rationalTime.h:179:20: error: cannot assign to non-static data member within const member function 'operator-='
            _value -= other.value_rescaled_to(_rate);
            ~~~~~~ ^
/Users/nporcino/build/local/include/opentime/rationalTime.h:170:35: note: member function 'opentime::v1_0::RationalTime::operator-=' is declared const here
    constexpr RationalTime const& operator-=(RationalTime other) noexcept
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 errors generated.

Copy link
Contributor

@darbyjohnston darbyjohnston left a comment

Choose a reason for hiding this comment

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

Strange, I wonder how that got by the other compilers.

Is the inline keyword needed since the function definition is inside the class?

@meshula
Copy link
Collaborator Author

meshula commented Mar 18, 2022

Older versions of xcode/clang don't flag it either, and by older, I mean from versions released earlier this year.

inline is intended as a hint that the code should be inlined, as opposed to having a function created and called. I think it's still the case that it behaves that way, even inside a class although I'll admit the C++ spec is getting too large to retain in my monkey brain. My thought was that it inline is still a hint to inline, then it's appropriate for these for speed.

@darbyjohnston
Copy link
Contributor

I found this FAQ from a quick search that looks like the "inline" is not needed when the function is inside the class body:
"Is there another way to tell the compiler to make a member function inline?"
https://isocpp.org/wiki/faq/inline-functions#inline-member-fns-more

I liked this quote from the description:

This is often more convenient than the alternative of defining your inline functions outside the class body. However, although it is easier on the person who writes the class, it is harder on all the readers since it mixes what a class does (the external behavior) with how it does it (the implementation). Because of this mixture, you should define all your member functions outside the class body if your class is intended to be highly reused and your class’s documentation is the header file itself. This is another application of Spock’s logic: the needs of the many (all the people reusing your class) outweigh the needs of the few (those who maintain your class’s implementation) or the one (the class’s original author)

@meshula
Copy link
Collaborator Author

meshula commented Mar 19, 2022

I looked up the spec ~ https://en.cppreference.com/w/cpp/language/inline ~

The inline specifier, when used in a function's decl-specifier-seq, declares the function to be an inline function.
A function defined entirely inside a class/struct/union definition, whether it's a member function or a non-member friend function, is implicitly an inline function [if it is attached to the global module (since C++20)].

Sounds like removing it is fine since inline is at best a hint anyway. However the meaning flip-flops under C++20, if we introduce an opentimelineio module???! Good grief!

We might be forced to move to the out-of-class definition pattern at that point, but I don't want to take on a refactoring of this header to get over this clang-bump.

I don't think Spock would approve of his name being used to justify C++ isms. I have it on good authority he programs with a version of [INCITS 226-1994 S20018]* updated to be compatible with Daystrom's latest positronic systems.

src/opentime/rationalTime.h Outdated Show resolved Hide resolved
src/opentime/rationalTime.h Outdated Show resolved Hide resolved
@codecov-commenter
Copy link

Codecov Report

Merging #1242 (dbf6d67) into main (aa5351c) will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #1242   +/-   ##
=======================================
  Coverage   86.15%   86.15%           
=======================================
  Files         196      196           
  Lines       19632    19632           
  Branches     2302     2302           
=======================================
  Hits        16913    16913           
  Misses       2161     2161           
  Partials      558      558           
Flag Coverage Δ
py-unittests 86.15% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
src/opentime/rationalTime.h 90.00% <ø> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update aa5351c...dbf6d67. Read the comment docs.

@meshula
Copy link
Collaborator Author

meshula commented Mar 19, 2022

PS, per @darbyjohnston's note, I removed the inline keyword.

@meshula meshula merged commit 15a3688 into AcademySoftwareFoundation:main Mar 21, 2022
andrewmoore-nz added a commit to thecargocultnz/OpenTimelineIO that referenced this pull request Apr 5, 2022
* main:
  Add Python 3.10 to CI (AcademySoftwareFoundation#1256)
  Fix missing init metadata (AcademySoftwareFoundation#1251)
  Support OTIO_PLUGIN_MANIFEST_PATH being set to an emptry string (AcademySoftwareFoundation#1253)
  Add ALE adapter argument `ale_name_column_key` (AcademySoftwareFoundation#1248)
  AAF Adapter: Mob transcription heuristics (AcademySoftwareFoundation#1249)
  Bump src/deps/Imath from `bd6f74c` to `bd254da` (AcademySoftwareFoundation#1245)
  clang notices that constexpr can't be used on a mutating function (AcademySoftwareFoundation#1242)
jminor pushed a commit that referenced this pull request May 2, 2022
)

* clang notices that constexpr can't be used on a mutating function

* Update src/opentime/rationalTime.h

Co-authored-by: Nick Porcino <[email protected]>
@ssteinbach ssteinbach added this to the Public Beta 15 milestone Sep 19, 2022
@meshula meshula deleted the clang-fix branch September 21, 2022 21:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants