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

STYLE: Add in-class {} member initializers to objects created by New() #3851

Conversation

N-Dekker
Copy link
Contributor

@N-Dekker N-Dekker commented Jan 4, 2023

For an object created by New(), the performance cost of adding a {} default member initializer to each of its non-static data members should be neglectable compared to the cost of allocating the object itself, as it is allocated on the heap.

In-class default member initialization effectively prevents Valgrind/Memcheck warnings like "Conditional jump or move depends on uninitialised value(s)", and Visual C++ Code Analysis warnings like "warning C26495: Variable is uninitialized. Always initialize a member variable (type.6)"

These cases are found using the regular expression \w.* m_\w[^{}=]+;, excluding static data members and data members of a reference (&) type.

@github-actions github-actions bot added area:Bridge Issues affecting the Bridge module area:Core Issues affecting the Core module area:Filtering Issues affecting the Filtering module area:IO Issues affecting the IO module area:Numerics Issues affecting the Numerics module area:Python wrapping Python bindings for a class area:Registration Issues affecting the Registration module area:Segmentation Issues affecting the Segmentation module area:Video Issues affecting the Video module type:Style Style changes: no logic impact (indentation, comments, naming) type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct labels Jan 4, 2023
Copy link
Member

@dzenanz dzenanz left a comment

Choose a reason for hiding this comment

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

Wouldn't this make it harder to spot a failure to really initialize these ivars in the constructor, or elsewhere?

@N-Dekker
Copy link
Contributor Author

N-Dekker commented Jan 4, 2023

Wouldn't this make it harder to spot a failure to really initialize these ivars in the constructor, or elsewhere?

Good question, but I'm not sure... Suppose a numeric data member is just zero-initialized by {}, while it should have been initialized to non-zero by the constructor, wouldn't that be easy to spot? Suppose a raw pointer is initialized as nullptr by {}, while it should have been initialized to a valid address in the constructor. Wouldn't that be easy to spot?

The use of uninitialized data isn't always spotted automatically, it may just have undefined behavior silently.

@N-Dekker
Copy link
Contributor Author

N-Dekker commented Jan 4, 2023

Instead of a bulk commit like this, we could just keep chasing uninitialized member variables one by one, as in PR #3845 (by Jon) #3843, and #3849 (by myself). Which is certainly useful, but also very time consuming. And we probably won't fix all of them that way, one by one. I think it's preferable to just initialize all data members by default. And only leave some particular data uninitialized in very special (performance critical) cases. What do you think?

@dzenanz
Copy link
Member

dzenanz commented Jan 4, 2023

I have mildly positive attitude towards this PR. I would like some other people to pitch in.

@N-Dekker
Copy link
Contributor Author

N-Dekker commented Jan 4, 2023

ITK.Linux has some warning at https://open.cdash.org/viewBuildError.php?type=1&buildid=8377051, but it seems unrelated to this PR, I don't know:

Modules/Core/Common/include/itkOctree.hxx:32:1: warning: const/copy propagation disabled: 49167 basic blocks and 82024 registers; increase --param max-gcse-memory above 504256752 [-Wdisabled-optimization]

@N-Dekker
Copy link
Contributor Author

N-Dekker commented Jan 4, 2023

FYI Here's a cheat sheet for the value initialized by {}:

Type Value initialized by {}
numeric type (int, unsigned, float, etc.) zero
bool false
pointer type nullptr
class that has a user-provided default-constructor default-constructed object
array all elements value-initialized (as if by {})
aggregate (struct) all data members value-initialized (as if by {})

@N-Dekker
Copy link
Contributor Author

N-Dekker commented Jan 4, 2023

/azp run ITK.Linux

@N-Dekker N-Dekker marked this pull request as ready for review January 4, 2023 20:18
@N-Dekker N-Dekker force-pushed the In-class-member-initializers-for-objects-created-by-New branch from 2bc139a to e5e27a9 Compare January 5, 2023 10:47
@N-Dekker
Copy link
Contributor Author

N-Dekker commented Jan 5, 2023

For the record, here is the discussion topic that I started on this subject: Adding in-class {} default member initializers to data members of ITK classes

The script I wrote to do the code changes is at https://gist.github.com/N-Dekker/738d28b8d7528a32c12e7a129160b00f

Copy link
Member

@thewtex thewtex left a comment

Choose a reason for hiding this comment

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

👏 ✨

Copy link
Member

@jhlegarreta jhlegarreta left a comment

Choose a reason for hiding this comment

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

Thanks for having taken the time to do this Niels.

A couple of in-line comments.

Please:

  • Translate the gist (:ok_hand:) into a script file so that it dwells in the ITK Maintenance Utilities. Remotes may be grateful at some point.
  • Apply this to non-default modules and examples (if not already done).
  • Write this in the ITK SW guide.

@dzenanz
Copy link
Member

dzenanz commented Jan 9, 2023

Give a few more days for others to comment/review, then merge? But corresponding update should go into the software guide either concurrently with the merge of this, or very soon afterwards.

@N-Dekker
Copy link
Contributor Author

N-Dekker commented Jan 9, 2023

Thanks for your feedback @dzenanz

Give a few more days for others to comment/review, then merge?

Sure, that's fine to me!

But corresponding update should go into the software guide either concurrently with the merge of this, or very soon afterwards.

Actually, it already says:

All member variables must be initialized when they are declared.

https://github.com/InsightSoftwareConsortium/ITKSoftwareGuide/blob/905c9bbc525adc73ff934d0ed24d06ef11151e22/SoftwareGuide/Latex/Appendices/CodingStyleGuide.tex#L1568

I just made a pull request to no longer exclude smart pointers. Instead, it proposes to exclude low level utility classes. Please check: InsightSoftwareConsortium/ITKSoftwareGuide#192

@N-Dekker N-Dekker force-pushed the In-class-member-initializers-for-objects-created-by-New branch from e5e27a9 to 27d1af3 Compare January 11, 2023 16:40
For an object created by `New()`, the performance cost of adding a `{}` default
member initializer to each of its non-static data members should be neglectable
compared to the cost of allocating the object itself, as it is allocated on the
heap.

In-class default member initialization effectively prevents Valgrind/Memcheck
warnings like "Conditional jump or move depends on uninitialised value(s)", and
Visual C++ Code Analysis warnings like "warning C26495: Variable is
uninitialized. Always initialize a member variable (type.6)"

These cases are found using the regular expression `  \w.* m_\w[^{}=]+;`,
excluding `static` data members and data members of a reference (`&`) type.

`Octree::m_ColorTable` was excluded, to avoid GCC warnings saying "const/copy
propagation disabled" and "GCSE disabled" [-Wdisabled-optimization].
@N-Dekker N-Dekker force-pushed the In-class-member-initializers-for-objects-created-by-New branch from 27d1af3 to a7aae35 Compare January 18, 2023 23:29
@N-Dekker
Copy link
Contributor Author

For your information, the last force-push just did another git rebase master, and solved the one little merge conflict.

@dzenanz dzenanz merged commit 5e2c49f into InsightSoftwareConsortium:master Jan 19, 2023
N-Dekker added a commit to N-Dekker/ITK that referenced this pull request Feb 4, 2023
Added in-class `{}` default member initializers to data members of classes
that have a `itkSimpleNewMacro` macro call.

Follow-up to pull request InsightSoftwareConsortium#3851
commit 5e2c49f
"STYLE: Add in-class `{}` member initializers to objects created by New()"
(which only looked at classes that have a `itkNewMacro`).
dzenanz pushed a commit that referenced this pull request Feb 6, 2023
Added in-class `{}` default member initializers to data members of classes
that have a `itkSimpleNewMacro` macro call.

Follow-up to pull request #3851
commit 5e2c49f
"STYLE: Add in-class `{}` member initializers to objects created by New()"
(which only looked at classes that have a `itkNewMacro`).
N-Dekker added a commit to N-Dekker/ITK that referenced this pull request Feb 6, 2023
Added in-class `{}` default member initializers to data members of classes
that have one or more virtual member functions.

For an object that has one or more virtual member functions, the performance
cost of adding a `{}` default member initializer to each of its non-static data
members should be acceptable, relative to cost of the initialization of its
virtual table.

Follow-up to pull request InsightSoftwareConsortium#3851
commit 5e2c49f
"STYLE: Add in-class `{}` member initializers to objects created by New()"
(which only looked at classes that have a `itkNewMacro`).
N-Dekker added a commit to N-Dekker/ITK that referenced this pull request Feb 8, 2023
Added in-class `{}` default member initializers to data members of classes
that have one or more virtual member functions.

For an object that has one or more virtual member functions, the performance
cost of adding a `{}` default member initializer to each of its non-static data
members should be acceptable, relative to cost of the initialization of its
virtual table.

Follow-up to pull request InsightSoftwareConsortium#3851
commit 5e2c49f
"STYLE: Add in-class `{}` member initializers to objects created by New()"
(which only looked at classes that have a `itkNewMacro`).
dzenanz pushed a commit that referenced this pull request Feb 8, 2023
Added in-class `{}` default member initializers to data members of classes
that have one or more virtual member functions.

For an object that has one or more virtual member functions, the performance
cost of adding a `{}` default member initializer to each of its non-static data
members should be acceptable, relative to cost of the initialization of its
virtual table.

Follow-up to pull request #3851
commit 5e2c49f
"STYLE: Add in-class `{}` member initializers to objects created by New()"
(which only looked at classes that have a `itkNewMacro`).
N-Dekker added a commit to N-Dekker/ITK that referenced this pull request Feb 23, 2023
The script that was used for the following pull requests:

pull request InsightSoftwareConsortium#3851
"STYLE: Add in-class `{}` member initializers to objects created by New()"

pull request InsightSoftwareConsortium#3913
"STYLE: Add in-class `{}` initializers to classes with virtual functions"

pull request InsightSoftwareConsortium#3917
"STYLE: Add in-class `{}` initializers to classes with override = default"
N-Dekker added a commit to N-Dekker/ITK that referenced this pull request Feb 23, 2023
The script that was used for the following pull requests:

pull request InsightSoftwareConsortium#3851
"STYLE: Add in-class `{}` member initializers to objects created by New()"

pull request InsightSoftwareConsortium#3913
"STYLE: Add in-class `{}` initializers to classes with virtual functions"

pull request InsightSoftwareConsortium#3917
"STYLE: Add in-class `{}` initializers to classes with override = default"
N-Dekker added a commit to N-Dekker/ITK that referenced this pull request Feb 25, 2023
The script that was used for the following pull requests:

pull request InsightSoftwareConsortium#3851
"STYLE: Add in-class `{}` member initializers to objects created by New()"

pull request InsightSoftwareConsortium#3913
"STYLE: Add in-class `{}` initializers to classes with virtual functions"

pull request InsightSoftwareConsortium#3917
"STYLE: Add in-class `{}` initializers to classes with override = default"
N-Dekker added a commit to N-Dekker/ITK that referenced this pull request Feb 25, 2023
The script that was used for the following pull requests:

pull request InsightSoftwareConsortium#3851
"STYLE: Add in-class `{}` member initializers to objects created by New()"

pull request InsightSoftwareConsortium#3913
"STYLE: Add in-class `{}` initializers to classes with virtual functions"

pull request InsightSoftwareConsortium#3917
"STYLE: Add in-class `{}` initializers to classes with override = default"
N-Dekker added a commit to N-Dekker/ITK that referenced this pull request Feb 25, 2023
The script that was used for the following pull requests:

pull request InsightSoftwareConsortium#3851
"STYLE: Add in-class `{}` member initializers to objects created by New()"

pull request InsightSoftwareConsortium#3913
"STYLE: Add in-class `{}` initializers to classes with virtual functions"

pull request InsightSoftwareConsortium#3917
"STYLE: Add in-class `{}` initializers to classes with override = default"
N-Dekker added a commit to N-Dekker/ITK that referenced this pull request Feb 25, 2023
The script that was used for the following pull requests:

pull request InsightSoftwareConsortium#3851
"STYLE: Add in-class `{}` member initializers to objects created by New()"

pull request InsightSoftwareConsortium#3913
"STYLE: Add in-class `{}` initializers to classes with virtual functions"

pull request InsightSoftwareConsortium#3917
"STYLE: Add in-class `{}` initializers to classes with override = default"
N-Dekker added a commit to N-Dekker/ITK that referenced this pull request Mar 1, 2023
Previous commits that added `{}` initializers to data members by means of
regular expressions had overlooked three-letter identifiers, like `m_E` and
`m_I`.

Follow-up to pull request InsightSoftwareConsortium#3851
commit 5e2c49f
"STYLE: Add in-class `{}` member initializers to objects created by New()"
N-Dekker added a commit to N-Dekker/ITK that referenced this pull request Mar 1, 2023
The script that was used for the following pull requests:

pull request InsightSoftwareConsortium#3851
"STYLE: Add in-class `{}` member initializers to objects created by New()"

pull request InsightSoftwareConsortium#3913
"STYLE: Add in-class `{}` initializers to classes with virtual functions"

pull request InsightSoftwareConsortium#3917
"STYLE: Add in-class `{}` initializers to classes with override = default"

pull request InsightSoftwareConsortium#3941
"STYLE: Add in-class `{}` member initializers to 3-letter data members"
N-Dekker added a commit to N-Dekker/ITK that referenced this pull request Mar 4, 2023
Previous commits that added `{}` initializers to data members by means of
regular expressions had overlooked member declarations that had a trailing
comment.

Follow-up to pull request InsightSoftwareConsortium#3851
commit 5e2c49f
"STYLE: Add in-class `{}` member initializers to objects created by New()"
N-Dekker added a commit to N-Dekker/ITK that referenced this pull request Mar 4, 2023
Previous commits that added `{}` initializers to data members by means of
regular expressions had overlooked member declarations that had a trailing
comment.

Follow-up to pull request InsightSoftwareConsortium#3851
commit 5e2c49f
"STYLE: Add in-class `{}` member initializers to objects created by New()"
N-Dekker added a commit to N-Dekker/ITK that referenced this pull request Mar 4, 2023
The script that was used for the following pull requests:

pull request InsightSoftwareConsortium#3851
"STYLE: Add in-class `{}` member initializers to objects created by New()"

pull request InsightSoftwareConsortium#3913
"STYLE: Add in-class `{}` initializers to classes with virtual functions"

pull request InsightSoftwareConsortium#3917
"STYLE: Add in-class `{}` initializers to classes with override = default"

pull request InsightSoftwareConsortium#3941
"STYLE: Add in-class `{}` member initializers to 3-letter data members"

pull request InsightSoftwareConsortium#3945
"STYLE: Add in-class `{}` member initializers having trailing comments"
N-Dekker added a commit to N-Dekker/ITK that referenced this pull request Mar 6, 2023
The script that was used for the following pull requests:

pull request InsightSoftwareConsortium#3851
"STYLE: Add in-class `{}` member initializers to objects created by New()"

pull request InsightSoftwareConsortium#3913
"STYLE: Add in-class `{}` initializers to classes with virtual functions"

pull request InsightSoftwareConsortium#3917
"STYLE: Add in-class `{}` initializers to classes with override = default"

pull request InsightSoftwareConsortium#3941
"STYLE: Add in-class `{}` member initializers to 3-letter data members"

pull request InsightSoftwareConsortium#3945
"STYLE: Add in-class `{}` member initializers having trailing comments"
hjmjohnson pushed a commit that referenced this pull request Mar 7, 2023
Previous commits that added `{}` initializers to data members by means of
regular expressions had overlooked member declarations that had a trailing
comment.

Follow-up to pull request #3851
commit 5e2c49f
"STYLE: Add in-class `{}` member initializers to objects created by New()"
dzenanz pushed a commit that referenced this pull request Mar 20, 2023
The script that was used for the following pull requests:

pull request #3851
"STYLE: Add in-class `{}` member initializers to objects created by New()"

pull request #3913
"STYLE: Add in-class `{}` initializers to classes with virtual functions"

pull request #3917
"STYLE: Add in-class `{}` initializers to classes with override = default"

pull request #3941
"STYLE: Add in-class `{}` member initializers to 3-letter data members"

pull request #3945
"STYLE: Add in-class `{}` member initializers having trailing comments"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:Bridge Issues affecting the Bridge module area:Core Issues affecting the Core module area:Filtering Issues affecting the Filtering module area:IO Issues affecting the IO module area:Numerics Issues affecting the Numerics module area:Python wrapping Python bindings for a class area:Registration Issues affecting the Registration module area:Segmentation Issues affecting the Segmentation module area:Video Issues affecting the Video module type:Style Style changes: no logic impact (indentation, comments, naming) type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants