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] Update to code rules #99

Draft
wants to merge 2 commits into
base: code
Choose a base branch
from
Draft

Conversation

makortel
Copy link
Contributor

@makortel makortel commented Apr 6, 2021

Changes in contents that have been brought up in #94 (up to further discussion).

@makortel makortel mentioned this pull request Apr 6, 2021

## 5 -- Documentation Rules
1. Always comment complex, tricky, or non-intuitive portions of code.
2. When revising code, be sure to update and revise comments.
3. Do not leave commented-out code in files. Instead, use git versioning to retain old versions of code in the development history. If code is only commented out temporarily, a clear comment should be added describing why it is temporarily disabled and under what conditions it will be re-enabled.
Copy link
Contributor

Choose a reason for hiding this comment

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

The "use git versioning to retain old versions of code" assumes that one knows to look in the git history for older versions of the code - people other than the original developer (who may very well have left CMS by the time the code is looked at again) may have no idea that an alternative version was ever available.
In addition, the very loose approach to a git history used in CMSSW makes it often very hard to figure out which commits contain useful code, and which ones are just iteration of non-working code before the final version is merged.

In addition, some code make a lot more sense being commented out than outright removed. For example, commented-out debug statements tell the people that read he code how to check some internal states, etc.
To those that advocate using #ifdefs for this, please explain how

#ifdef SOME_RANDOM_DEBUG_FLAG
    std::cout << "internal state: " << myObject.state() << std::endl;
#endif  // SOME_RANDOM_DEBUG_FLAG

is more readable or better maintainable than

    //std::cout << "internal state: " << myObject.state() << std::endl;

?

Copy link
Contributor

Choose a reason for hiding this comment

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

It's more maintainable because the debug statement can be activated without editing the code. (I agree that the readability is not great.)

The key point is really in the last sentence of this code rule: files littered with commented-out code are hard to understand for someone looking at them for the first time, because it's usually not indicated why the commented-out code is there.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree for the case where there are a bunch of statements that could be something somebody has tried and didn't work, or something that was there before and has been changed, etc.

However I don't think that

    //std::cout << "internal state: " << myObject.state() << std::endl;

is hard to understand - neither why the comment is there, nor what it would do if uncommented.

It's more maintainable because the debug statement can be activated without editing the code.

True - unless there are #define/#undef for that symbol in the source file, then it does need to be edited.
Or unless you want to enable only one of those messages, not all of them.

Copy link
Contributor

Choose a reason for hiding this comment

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

In my opinion

//std::cout << "internal state: " << myObject.state() << std::endl;

is really hard to understand :-) This does not tell me if it was added during the development phase and user forgot to remove it or if it was really to indicate the it is for debugging purpose in future. Better to either use #ifdef or add a comment to indicate that why this comment is there.

Copy link
Contributor

Choose a reason for hiding this comment

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

Then we disagree.

Copy link
Contributor

Choose a reason for hiding this comment

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

Of course, for this specific example an ideal solution would be to have a usable system for debug statements, with a clear syntax, support for the most common idioms (not only the ones that the Core Software team deems "appropriate" for the developers to use), and a simply way of turning the debug information on and off.

@@ -88,10 +88,15 @@ If necessary to create a unique name, one can add the directory name:
27. Provide meaningful argument names in method declarations in the header file to indicate usage, unless the type fully describes the usage.
28. Try to avoid excessively long lines of code that impair readability.
29. Data members of a class must not be redefined in derived classes since doing so hides the original data member and could create confusion between the original and redefined data members.
30. Use `std::abs()` instead of `fabs()`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Why only abs and not all the math functions ?

Copy link
Contributor

Choose a reason for hiding this comment

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

yes why abs only? By the way, clang-tidy has this check https://clang.llvm.org/extra/clang-tidy/checks/performance-type-promotion-in-math-fn.html but this will only apply to math functions with implicit float to double conversion.

Copy link
Contributor

Choose a reason for hiding this comment

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

https://blog.audio-tk.com/2018/03/20/writing-custom-checks-for-clang-tidy/ suggests how to add clang-tidy checks for such deprecated functions. @gartung may be we can include these in our llvm build?

Copy link
Member

Choose a reason for hiding this comment

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

Yes a custom checker can be made for that.

Copy link
Contributor

Choose a reason for hiding this comment

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

@gartung , have to looked in to this? Can we add a custom checker for this?

Copy link
Contributor

Choose a reason for hiding this comment

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

sorry to jump in now in this old thread, but I see developers using fabs instead of std::abs (and even worse using abs for floats) . Was the ckecker discussed above made or is there any objection in moving on with adding this 4.30 rule?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not so sure any more that we should discourage the use of fabs.
In fact, people may end up using a lot more conversions to/from doubles without realising it:

auto x = f(...);            // returns a float
auto y = std::abs(x * 2.);  // returns a double

At least fabs etc. are explicit about being single precision.

Copy link
Contributor

@mmusich mmusich Mar 15, 2024

Choose a reason for hiding this comment

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

I'm not so sure any more that we should discourage the use of fabs.
In fact, people may end up using a lot more conversions to/from doubles without realising it:

good observation, will keep in mind while reviewing.

Copy link
Contributor

Choose a reason for hiding this comment

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

the case about x * 2. should probably be formalized as a rule/reminder that single precision code should rely on single precision literals.
auto y = std::fabs(x * 2.) where x is a float should still return a double; std::fabsf would be a float with a warning if a 2. is used.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, yes, fabfs.

@@ -88,10 +88,15 @@ If necessary to create a unique name, one can add the directory name:
27. Provide meaningful argument names in method declarations in the header file to indicate usage, unless the type fully describes the usage.
28. Try to avoid excessively long lines of code that impair readability.
29. Data members of a class must not be redefined in derived classes since doing so hides the original data member and could create confusion between the original and redefined data members.
30. Use `std::abs()` instead of `fabs()`.
31. Use C++ headers, e.g. `#include <cmath>` instead of `#include <math.h>`.
32. Use MessageLogger instead of `std::cout` and `std::cerr` (\*). Allowed exception: standalone programs should use `std::cout` and `std::cerr`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Then please fix the message logger poor usability.
Enabling debugging messages for individual modules is at best a pain.

@makortel
Copy link
Contributor Author

We should probably revive doing these updates, but in smaller chunks (maybe even one at a time) to be able to conclude.

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.

None yet

7 participants