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

[WIP] Test clang-tidy with selected checks #35

Closed
wants to merge 2 commits into from
Closed

Conversation

ianna
Copy link
Collaborator

@ianna ianna commented Dec 18, 2019

Apply fixes from clang-tidy with -checks='-*,
boost-use-to-string,
misc-string-compare,
misc-uniqueptr-reset-release,
modernize-deprecated-headers,
modernize-make-shared,
modernize-use-bool-literals,
modernize-use-equals-delete,
modernize-use-nullptr,
modernize-use-override,
performance-unnecessary-copy-initialization,
readability-container-size-empty,
readability-redundant-string-cstr,
readability-static-definition-in-anonymous-namespace,
readability-uniqueptr-delete-release'

https://clang.llvm.org/extra/clang-tidy/

@jpivarski - please, review and comment

…-string-compare,misc-uniqueptr-reset-release,modernize-deprecated-headers,modernize-make-shared,modernize-use-bool-literals,modernize-use-equals-delete,modernize-use-nullptr,modernize-use-override,performance-unnecessary-copy-initialization,readability-container-size-empty,readability-redundant-string-cstr,readability-static-definition-in-anonymous-namespace,readability-uniqueptr-delete-release'
@ianna ianna requested a review from jpivarski December 18, 2019 11:25
Copy link
Member

@jpivarski jpivarski left a comment

Choose a reason for hiding this comment

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

It looks to me like the only changes are:

  • replacing virtual with override (good: I didn't know about that one, but it's C++11 and I prefer it)
  • container.size() == 0 with container.empty() (fine: I should have known about that, as it's not a new thing, but okay)
  • using make_shared: I thought I couldn't use it, thinking that it's a C++14 thing, but I was wrong. It's defined in C++11.

I also added a note about json.h because looking over these changes reminded me that I'll need to hide the dependency on RapidJSON headers. (With them included in the .h file, dependent libraries like Josh's are forced to find and include the RapidJSON headers as well. If it were only used in the .cpp file, then they would get the functionality without having to find the includes. We use visibility=hidden, so there shouldn't be an issue with conflicting symbols, if he happened to include his own different version of RapidJSON.)

I'm in favor of these changes, the best one being virtualoverride. However, there are so many that I think we should coordinate when they get applied: I should merge my PR, then we run clang-tidy, then merge that. My current PR has so many changes that it would be difficult to merge this in.

In fact, I'll try making these three changes manually to my branch. Then when we apply clang-tidy on top of it, it will be easier to see if there are other changes it's trying to make that are hidden by the noise that these are making.

@@ -52,7 +53,7 @@ namespace awkward {
size_t cols = (size_t)numfields();
std::shared_ptr<RecordArray::ReverseLookup> keys = array_.reverselookup();
if (istuple()) {
keys = std::shared_ptr<RecordArray::ReverseLookup>(new RecordArray::ReverseLookup);
keys = std::make_shared<RecordArray::ReverseLookup>();
for (size_t j = 0; j < cols; j++) {
Copy link
Member

Choose a reason for hiding this comment

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

Isn't make_shared a C++14 thing?

Copy link
Member

Choose a reason for hiding this comment

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

I was wrong! This is "since C++11". I guess I should have been using this, so that there are fewer dangerous-looking new keywords around.

bool haskey(const std::string& key) const override;
const std::vector<std::string> keyaliases(int64_t fieldindex) const override;
const std::vector<std::string> keyaliases(const std::string& key) const override;
const std::vector<std::string> keys() const override;
Copy link
Member

Choose a reason for hiding this comment

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

Replacing virtual with override: okay. I didn't know about that, but it provides some additional safety.

@@ -163,7 +163,7 @@ namespace awkward {
}

const std::shared_ptr<SliceItem> Slice::head() const {
if (items_.size() != 0) {
if (!items_.empty()) {
Copy link
Member

Choose a reason for hiding this comment

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

I guess the intent here is more specific, so this is good.

virtual void beginrecord() { writer_.StartObject(); }
virtual void field(const char* x) { writer_.Key(x); }
virtual void endrecord() { writer_.EndObject(); }
void null() override { writer_.Null(); }
Copy link
Member

Choose a reason for hiding this comment

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

It's not visible in this snippet, but this file leaks a dependence on the RapidJSON headers that I'll need to hide in the .cpp file. I think that can be done by defining these ToJson classes without implementations in the header and moving all of the implementations to the .cpp file, but that's something that would have to be done manually.

@ianna
Copy link
Collaborator Author

ianna commented Dec 18, 2019

ok, I'm closing this PR for now.

@ianna ianna closed this Dec 18, 2019
@ianna
Copy link
Collaborator Author

ianna commented Dec 18, 2019

reopen to add clang-tidy fixes with a readability-redundant-smartptr-get check:
https://clang.llvm.org/extra/clang-tidy/checks/readability-redundant-smartptr-get.html

@ianna ianna reopened this Dec 18, 2019
Copy link
Member

@jpivarski jpivarski left a comment

Choose a reason for hiding this comment

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

Actually, if we could have the opposite of this, to force the inclusion of .get(), I'd prefer that. I was trying to be conscious of the difference between smart pointers and raw pointers everywhere.

@ianna
Copy link
Collaborator Author

ianna commented Dec 18, 2019

automated fixes with readability-avoid-const-params-in-decls check remove const in places where it could be a reference:

diff --git a/include/awkward/Index.h b/include/awkward/Index.h
index 40f7a59..2ad904b 100644
--- a/include/awkward/Index.h
+++ b/include/awkward/Index.h
@@ -32,7 +32,7 @@ namespace awkward {
 
     const std::string classname() const;
     const std::string tostring() const;
-    const std::string tostring_part(const std::string indent, const std::string pre, const std::string post) const;
+    const std::string tostring_part(std::string indent, std::string pre, std::string post) const;
     T getitem_at(int64_t at) const;
     T getitem_at_nowrap(int64_t at) const;
     void setitem_at_nowrap(int64_t at, T value) const;

https://clang.llvm.org/extra/clang-tidy/checks/readability-avoid-const-params-in-decls.html

@jpivarski
Copy link
Member

In the above example, I'm going to want to make sure that it says

const std::string tostring_part(const std::string& indent, const std::string& pre, const std::string& post) const;

I just haven't been diligent about making sure that all such cases are explicit.

Most of the function arguments are either simple numbers, which should be passed by value, or unmodified structures, which should be pass-by-const-reference. It's very rare that I'll want to copy a structure into the function (as the mistaken case above) or pass a non-const reference for remote modification (though there are a few cases, but I think they're numbers).

int64_t numer = abs(start - stop);
int64_t denom = abs(step);
int64_t numer = std::abs(start - stop);
int64_t denom = std::abs(step);
Copy link
Member

Choose a reason for hiding this comment

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

This is good. I like this.

@ianna ianna closed this Dec 18, 2019
@jpivarski
Copy link
Member

My last four commits to PR #33 applied the corrections that clang-tidy wants to make, but manually with much testing to make sure that it agrees with my intentions. If you run clang-tidy over that, we should see what residual changes it wants to make with much less noise.

This is not including the removal of .get() from shared pointers. I want to do that, as a reminder of the distinction between a shared pointer and a raw pointer. (There are a few, very rare cases where raw pointers are necessary, particularly for interacting with the bottom layer in the architecture through an "extern C" interface.)

@ianna
Copy link
Collaborator Author

ianna commented Dec 18, 2019

My last four commits to PR #33 applied the corrections that clang-tidy wants to make, but manually with much testing to make sure that it agrees with my intentions. If you run clang-tidy over that, we should see what residual changes it wants to make with much less noise.

This is not including the removal of .get() from shared pointers. I want to do that, as a reminder of the distinction between a shared pointer and a raw pointer. (There are a few, very rare cases where raw pointers are necessary, particularly for interacting with the bottom layer in the architecture through an "extern C" interface.)

Thanks, @jpivarski ! I'll do it tomorrow. I've been checking other clang-tidy checks. The good news is that most of them come clean. There are two we may want to look closely: modernize-pass-by-value (https://clang.llvm.org/extra/clang-tidy/checks/modernize-pass-by-value.html) and readability-avoid-const-params-in-decls

@ianna ianna deleted the clang-tidy-test branch December 20, 2019 09:18
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.

2 participants