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

Updates for Code rules #94

Open
makortel opened this issue Apr 9, 2020 · 29 comments
Open

Updates for Code rules #94

makortel opened this issue Apr 9, 2020 · 29 comments

Comments

@makortel
Copy link
Contributor

makortel commented Apr 9, 2020

The Code rules (http://cms-sw.github.io/cms_coding_rules.html) would benefit from some updates (list has been updated based on the discussion below)

@makortel
Copy link
Contributor Author

makortel commented Apr 9, 2020

I was thinking to address these myself, but wanted to open an issue in the mean time.

@kpedro88
Copy link
Contributor

kpedro88 commented Apr 9, 2020

while we're here, another informal rule should be formalized: use std::abs() not fabs()

maybe also: "use c++ headers like rather than c headers like <math.h>"?

@makortel
Copy link
Contributor Author

makortel commented Apr 9, 2020

Do the Core Guidelines say anything about either?

@kpedro88
Copy link
Contributor

kpedro88 commented Apr 9, 2020

avoiding fabs is something we've recommended for a while to prevent undesirable type conversions (since c++11 improved std::abs())

i don't see anything about c++ vs c headers, but i think this is also something we commonly recommend

@makortel
Copy link
Contributor Author

makortel commented Apr 9, 2020

I know and agree, I was just wondering if the Core Guidelines would have a recommendation we could refer to (sorry I was unclear).

@smuzaffar
Copy link
Contributor

For c vs c++ headers, although there is nothing in the Core guidelines but we force it via clang-tidy check https://clang.llvm.org/extra/clang-tidy/checks/modernize-deprecated-headers.html

@kpedro88
Copy link
Contributor

kpedro88 commented Apr 9, 2020

i also notice that our ban on cout is not described in the code rules, this should definitely be added

@makortel
Copy link
Contributor Author

makortel commented Apr 9, 2020

i also notice that our ban on cout is not described in the code rules, this should definitely be added

It sort-of falls under 7.2 ("Ensure code is thread-safe"), but yes, it would be clearer to mention it explicitly.

Sounds like there is room for gather a bit more stuff and do one larger update (with a presentation in the core meeting and proper announcement of the update).

@kpedro88
Copy link
Contributor

kpedro88 commented Apr 9, 2020

another one that I don't see explicitly in the rules:

  • use git versioning to retain old versions of code in the development history, rather than leaving commented-out code in files. if code is only commented out temporarily, a clear comment should be added describing why it's temporarily disabled and under what conditions it will be re-enabled.

@kpedro88
Copy link
Contributor

kpedro88 commented Apr 9, 2020

could also add "avoid const_cast"

@fwyzard
Copy link
Contributor

fwyzard commented Apr 16, 2020

Proposal: relax

Do not to inline virtual functions

to something like

Do not to inline virtual functions (*)

(*) inlining is permitted for simple functions like accessors and setters, as long as there is at least one non-inline virtual function in the class

@silviodonato
Copy link

Is it written somewhere about avoiding using namespace in header files?

@smuzaffar
Copy link
Contributor

It is kind of part of original CMs coding huide lines document
https://cds.cern.ch/record/687032/files/note98_070.pdf

Use ‘using namespace’ only in local scope.

@makortel
Copy link
Contributor Author

Is it written somewhere about avoiding using namespace in header files?

It is not part of our current code rules (although our tools flag it), which is why I'm suggesting to add it (from issue description

)

@makortel
Copy link
Contributor Author

Maybe we should add something about thread_local as well.

@slava77
Copy link
Contributor

slava77 commented Aug 20, 2020

what about (currently 4.7) Do not forward-declare an entity from another package. ?
It seems to be systematically violated.
Should some note like not really enforced and is widely not followed be added?

@makortel
Copy link
Contributor Author

what about (currently 4.7) Do not forward-declare an entity from another package. ?
It seems to be systematically violated.
Should some note like not really enforced and is widely not followed be added?

Would that be much different from removing the rule? (ok, by not removing someone could still adhere the rule, which would be beneficial)

I think we should also consider actually enforcing the rule, at least on new code. Not following it has a risk of increasing maintenance cost.

@slava77
Copy link
Contributor

slava77 commented Aug 21, 2020

what about (currently 4.7) Do not forward-declare an entity from another package. ?
It seems to be systematically violated.
Should some note like not really enforced and is widely not followed be added?

Would that be much different from removing the rule? (ok, by not removing someone could still adhere the rule, which would be beneficial)

I think we should also consider actually enforcing the rule, at least on new code. Not following it has a risk of increasing maintenance cost.

BTW, where is the maintenance cost, and why is rule 4.6 allowing forward declarations from the same package?
The obvious explicit maintenance cost is that users of the package have to include header files for the forward-declared types when such type members are needed.
But according to rule 4.6 I'd guess that this cost is not really counted.
So, what remains is the cost of maintaining the BuildFile dependency declarations.
Would it be OK then to allow the forward declarations from other packages if the package itself exports dependency on that package?

@davidlange6
Copy link
Contributor

davidlange6 commented Aug 21, 2020 via email

@wddgit
Copy link

wddgit commented Aug 21, 2020

If we are actually considering enforcing this rule, we might want to consider making some exceptions.

I think we are allowed to forward declare by including a header file like FWCore/Framework/interface/Frameworkfwd.h, even outside FWCore/Framework. Is this true?

There has been some discussion in the past that a related group of packages maintained by the same people can forward declare classes from other packages in the same group. The Core packages have many such forward declarations. ( I am guilty of adding many of them, although not all and I think I started doing that by copying the pattern already there long ago before this rule existed). Such a definition would be harder to enforce because we would have to define the groups of packages...

Are there other reasonable exceptions?

When I was originally learned C++ I was strongly encouraged to use forward declarations and you still see that advice some places.

Some of the pros and cons are discussed here: https://google.github.io/styleguide/cppguide.html#Forward_Declarations

@makortel
Copy link
Contributor Author

I think we are allowed to forward declare by including a header file like FWCore/Framework/interface/Frameworkfwd.h, even outside FWCore/Framework. Is this true?

Yes, including headers of forward declarations is fine.

@makortel
Copy link
Contributor Author

BTW, where is the maintenance cost, and why is rule 4.6 allowing forward declarations from the same package?

Let's say there is a type Foo that is a class. For some reason the implementation needs to be changed to a class template, such that a type alias along using Foo = FooTemplate<SomeType>. Now all the forward declarations along

class Foo;

need to be changed to

template <typename T>
class FooTemplate;
using Foo = FooTemplate<SomeType>;

If the forward declarations are scattered around in many places outside of the package defining the type, that would require a lot of work.

If the forward declarations are placed in one header for the package for the clients of that package to include, it is sufficient for the package maintainer to cover all clients by just updating that header (like FWCore/Framework/interface/Frameworkfwd.h that @wddgit mentioned).

Forward declarations within a package can be thought of being up to the package maintainer(s) to decide how to deal with (scattering the declarations vs. gathering them into a header).

@davidlange6
Copy link
Contributor

davidlange6 commented Aug 21, 2020 via email

@makortel
Copy link
Contributor Author

But it seems to me that this sort of benefit is small compared to the cost (in a system with >1000 packages), as it is what appears to me as a corner case.

Could you elaborate what you refer to with "cost"? Cost of changing the inter-package forward declarations to go via headers? Cost of forward declarations in general? Something else?

@Dr15Jones
Copy link
Contributor

Using forward declarations is a very easy way to cause 1 definition rule violations (the forward declaration declares a class but the name was changed to be a typedef). I've actually encountered this quite a number of times when changing (or fixing) CMSSW code.

Given that forward declarations are useful for decoupling systems (which we do want to do) then the safest way the C++ programming community has found to use them is to have forward declaring headers where that header lives in the same software area (e.g. for CMSSW a package) as the full header. Our coding rules are meant to reflect what the C++ community sees as best practices.

@davidlange6
Copy link
Contributor

davidlange6 commented Aug 21, 2020 via email

@fwyzard
Copy link
Contributor

fwyzard commented Apr 6, 2021

Which of these changes (and of the existing rules) can be implemented in clang-tidy, even without a "fix up" rule ?

I assume most L2s have better ways to spend their time than making the same suggestions over and over again.

Also, can we make at least the error reporting (without the automatic fixes) part of scram b ?

@smuzaffar
Copy link
Contributor

@makortel
Copy link
Contributor Author

makortel commented Apr 6, 2021

To make some progress I made two PRs of the updates discussed here: #98 for updating the links in TOC and to C++ core guidelines, and #99 for the actual contents update.

Maybe we should go through the rules systematically and try to add automated checks. Maybe even denote the level of enforcement in the rules? (e.g. along "by eye in review", "checked without fixup", "checked with fixup")

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

No branches or pull requests

9 participants