-
-
Notifications
You must be signed in to change notification settings - Fork 661
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
ENH: Add C++17 [[nodiscard]]
to Image "Transform" member functions
#3993
ENH: Add C++17 [[nodiscard]]
to Image "Transform" member functions
#3993
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add "If this return value can be
ignored, it is preferable (for performance reasons) to call the corresponding
overload that has one parameter instead." to the documentation of these methods, so if someone does get a warning they can easily figure out what to do.
Thanks @dzenanz I agree, will add something like that with a force-push to this PR. Note that C++20 allows adding a message to the nodiscard attribute:
When does ITK upgrade to C++20? 😸 |
Maybe also add a new macro, called |
@dzenanz Can you please make that a pull request? 😃 |
Added a note to the overloads of `TransformPhysicalPointToIndex` and `TransformPhysicalPointToContinuousIndex` that have two parameters (returning a `bool`), as was suggested by Dženan Zukić at InsightSoftwareConsortium#3993 (review)
Replaced a call to `TransformPhysicalPointToContinuousIndex` with its faster overload, within `SLICImageFilter::BeforeThreadedGenerateData()`. Follow-up to pull request InsightSoftwareConsortium#2901 commit 6a8569e "PERF: Use the faster `TransformPhysicalPointToContinuousIndex` overload"
Print the `bool` return values of `TransformPhysicalPointToIndex` and `TransformPhysicalPointToContinuousIndex`, in tests from "Core/Common". The apparently accidentally ignored return values were found by using the C++17 `[[nodiscard]]` attribute, as part of pull request InsightSoftwareConsortium#3993
It would usually be a mistake when a user would unintentionally ignore the return value of those member functions. Specifically, the overloads of `TransformPhysicalPointToIndex` and `TransformPhysicalPointToContinuousIndex` that have two parameters both return a `bool` value. If this return value can be ignored, it is preferable (for performance reasons) to call the corresponding overload that has one parameter instead. The compiler may now produce a warning when the return value of any of those member functions is unintentionally ignored.
7edeb05
to
da2af56
Compare
You missed a couple in Examples/DataRepresentation/Path/PolyLineParametricPath1.cxx:105:3: warning: ignoring return value of function declared with 'nodiscard' attribute [-Wunused-result] |
Fixed Mac/Darwin Clang warnings saying: > warning: ignoring return value of function declared with 'nodiscard' attribute [-Wunused-result] From https://open.cdash.org/viewBuildError.php?type=1&buildid=8600267
Added a note to the overloads of `TransformPhysicalPointToIndex` and `TransformPhysicalPointToContinuousIndex` that have two parameters (returning a `bool`), as was suggested by Dženan Zukić at #3993 (review)
Print the `bool` return values of `TransformPhysicalPointToIndex` and `TransformPhysicalPointToContinuousIndex`, in tests from "Core/Common". The apparently accidentally ignored return values were found by using the C++17 `[[nodiscard]]` attribute, as part of pull request #3993
Quite a fallout from this PR, 27 new warnings. |
And if some of the remote modules are included, the count goes up to 72: |
@dzenanz This means that those |
It would probably be helpful to put it under legacy ifdef. That would be easier to accomplish if we go the macro route: #3993 (comment) 😄 |
@N-Dekker I think it would be best to put it inside an ITK_LEGACY_REMOVE section. Better yet to to combine @dzenanz previous suggestions #ifdef ITK_LEGACY_REMOVE
#. if C++ > 20
# define ITK_NO_DISCARD(message) [[nodiscard("message")]]
# else
# define ITK_NO_DISCARD(message) [[nodiscard]]
# endif
#else
# define ITK_NO_DISCARD(message)
#endif |
Sorry I don't really like the idea of making But maybe I just don't understand your proposal. |
I don't think that anything is a legacy-remove-only feature forever. During major version upgrades, we systematically remove legacy behaviors, only leaving the new behaviors. But for now, only people with |
In practice, these warnings only appear in legacy code, calling the old The other uses of |
Which others? |
This PR added |
Ah, I now understand what you meant. It is wholly pointless to call those transform methods if you don't use the result. So yes, in those cases |
Thanks, so then we could decide to use plain |
I disagree with @dzenanz a little bit. It may be pointless in context of ITK as it exists today, but using the LEGACY_REMOVE approach allows a smooth transition to enforcing the new preferred mechanism over time. It takes a long time to allow transitioning old code to new interfaces overtime. There still exists a lot of code that depends on ITK that was written before the new non-bounds checked version of the "Point Transform*To*(const Point)" functions existed. |
Just some additional info here: the extra overloads for ImageBase Transform member functions were added with pull request #868 commit 65233e3, almost four years ago, and they were included already with the very first release of ITK 5.0 Please note also that this PR does not propose to deprecate the old versions. It only just warns the user who calls the old |
@N-Dekker I don't disagree, but some in the community will. The macros were suggested as a path of least community frustration, along with the benefit of allowing really nice messages for C++20 users. Many in the community only want to use tools built on ITK, and don't want the burden of digging through warnings. Those of us who do the development want the ability to see those warnings, but we often do not have time to change all depenadant poorly written code all at once. When working on data analysis, I like to build ITK_LEGACY_REMOVE=OFF so that I can focus on problems that may be related to the data analysis. When writing code or testing performance, I use ITK_LEGACY_REMOVE=ON to prepare for the future. This comment is to present my POV. I am OK with either solution. Personally I am not affect much either way. |
IMHO, TransformPhysicalPointToContinuousIndex is not ideal candidate for A slice of one image is represented as infinite collision plane and 4 rays are send from the edges of the slice of another image, so inside or outside is not important at this point. (It is done this way to work with non-uniform DICOM series, every slice is defined in physical space). Here is small trivial test to show what happens if the point is outside.
cc @dzenanz Edit: OK, I have already fixed the warning with |
Thanks for your extensive comment @issakomi Indeed the warning can be suppressed quite easily in ITK user code, either by a |
I am not sure that the overload was in ITK 4. I think Fedora still has no ITK 5 devel. package. I am not sure, I don't maintain the Fedora package myself. Probably I shall use preprocessor to support both ways depending on ITK version. Flathub distribution is easier, I can link statically with the latest ITK. #if ((ITK_VERSION_MAJOR == 5 && ITK_VERSION_MINOR >= 4) || ITK_VERSION_MAJOR > 5)
const auto index =
image->TransformPhysicalPointToContinuousIndex<float>(point);
#else
itk::ContinuousIndex<float, 3> index;
image->TransformPhysicalPointToContinuousIndex(point,index);
#endif |
OK, have to admit there is in fact an improvement if inside/outside things are skipped. |
Thanks @issakomi. On the other side, I have to admit that the calling the By the way, would it help you if this specific |
If an application wants to support both ITK 5.4+, and ITK5.3-, an |
I turned the proposed changes into a PR: #4007. |
It would usually be a mistake when a user would unintentionally ignore the return value of those member functions. Specifically, the overloads of
TransformPhysicalPointToIndex
andTransformPhysicalPointToContinuousIndex
that have two parameters both return abool
value. If this return value can be ignored, it is preferable (for performance reasons) to call the corresponding overload that has one parameter instead.The compiler may now produce a warning when the return value of any of those member functions is unintentionally ignored.