-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Document current coding style guidelines. #2298
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
base: master
Are you sure you want to change the base?
Conversation
README/RCodingStyle.hxx
Outdated
/// Functions that access only public members of ROOT classes shall be in here. | ||
/// \param a - first TExampleClass to add. | ||
/// \param b - second TExampleClass to add. | ||
double Add(const TExampleClass& a, const TExampleClass& b); |
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.
Did you mean to change the binding of the & (and *):
double Add(const TExampleClass &a, const TExampleClass &b);
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.
yes please! :P
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.
Nice, we really needed this! Is this retroactive for new classes? I.e., should I make RDataFrame
& friends compliant?
@@ -0,0 +1,67 @@ | |||
/// \file RCodingStyle.cxx | |||
/// \author Axel Naumann <axel@cern.ch> |
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.
how does this look for multiple authors?
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.
Should be addressed.
README/RCodingStyle.cxx
Outdated
@@ -0,0 +1,67 @@ | |||
/// \file RCodingStyle.cxx | |||
/// \author Axel Naumann <axel@cern.ch> | |||
/// \date 2018-07-06 |
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.
what date is this? creation or last modification?
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.
Should be addressed.
README/RCodingStyle.cxx
Outdated
|
||
// This file demonstrates the coding styles to be used for new ROOT files. | ||
// For much of the rationale see Scott Meyer's "Efficient Modern C++" and the | ||
// [C++ core guildlines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md), |
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.
"guildlines"
README/RCodingStyle.cxx
Outdated
* For the list of contributors see $ROOTSYS/README/CREDITS. * | ||
*************************************************************************/ | ||
|
||
// This file demonstrates the coding styles to be used for new ROOT files. |
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.
"style" singular?
README/RCodingStyle.cxx
Outdated
// Now the same order as for the header: | ||
// ROOT headers in alphabetical order; all new ROOT headers are under `ROOT/` | ||
#include "ROOT/TSeq.hxx" | ||
// Old ones are found in include/ without prefix. Try to use the new ones. |
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.
what do you mean with "Try to use the new ones"? The percentage of functionality that is available both in ROOT/R*
headers and in T*
headers is very little afaik?
Or is this a "Try out the new ones when available!" (as in, advertisement more than guideline)? In which case my comment would be that there is no way for users to know whether ROOT offers a ROOT/RString.hxx
as a modern substitute for TString.h
, except for searching for it in the doxygen docs case by case. And even then the names are not always the same, e.g. the modern TH1F.h
is not ROOT/RH1F.hxx
.
README/RCodingStyle.hxx
Outdated
/// Disabled if `T` is of reference type. | ||
|
||
template <int IDX, // Template parameters are all-capital letters | ||
class T, // We use "class", not "typename"; `T` is fine for generic class names |
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.
damn, that's a lot of search-and-replace in RDataFrame's headers 😋
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.
No worries. Some inconsistencies are fine; people won't even notice. It's more important that we agree on what to do from here on.
/// on the template parameters, e.g. `IDX` must be positive, `T` must be copyable. | ||
/// Disabled if `T` is of reference type. | ||
|
||
template <int IDX, // Template parameters are all-capital letters |
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.
this is the only new convention that I don't like, it makes template-heavy code a bit heavy to look at (just go to TypeTraits.hxx
and capitalize all template parameters...) and macro-like.
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.
It helps to identify template parameters as such. I often use a using declaration to "convert" the template param to a type (with type-spelling).
But I see your point. Let's discuss at a team meeting!
README/RCodingStyle.hxx
Outdated
|
||
// Use `= delete` instead of private, unimplemented. | ||
// To avoid copy and move construction and assignment, `delete` the copy | ||
// constructor and copy-assignment operator: |
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.
does this mean that you prefer to not have the move-ctor deleted?
README/RCodingStyle.hxx
Outdated
/// they "inherit" the virtuality of the virtual base class destructor). | ||
virtual ~RCodingStyle() {} | ||
|
||
/// Overridden virtual functions do not specify `virtual` but `override` or `final`. |
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.
I would say either override
or final
: exactly one of the two, as per CppCoreGuidelines
README/RCodingStyle.hxx
Outdated
/// Functions that access only public members of ROOT classes shall be in here. | ||
/// \param a - first TExampleClass to add. | ||
/// \param b - second TExampleClass to add. | ||
double Add(const TExampleClass& a, const TExampleClass& b); |
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.
RExampleClass
0b18907
to
f78f9bd
Compare
I don't think we should invest effort in retrofitting this to |
static const std::string &StaticFunc() { | ||
// NOTE that this initialization is thread-safe! | ||
static std::string sString = "SomeString"; | ||
return sString; |
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.
What about return "SomeString";
?
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.
a) that's not the point of this demo-function, and b) that won't give you a string&
.
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.
I have improved the code, I hope it's less confusing now?
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.
Yes, but maybe git commit --amend
is better than adding a separate change for this.
* * | ||
* For the licensing terms see $ROOTSYS/LICENSE. * | ||
* For the list of contributors see $ROOTSYS/README/CREDITS. * | ||
*************************************************************************/ |
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.
Do we need this header on every file? The top 3 lines are obsolete almost immediately, and git is there for that, while the copyright can be in a file at top level stating that that's the copyright unless a different one exists in the file. Also, many files don't have the header in any case:
epsft-53 root $ git ls-files | grep '\.[ch][x][x]' | wc -l
2847
epsft-53 root $ git ls-files | grep '\.[ch][x][x]' | xargs -n1 grep 'Rene Brun' | wc -l
1739
and many others are out of date:
epsft-53 root $ grep -hor '1995-[0-9]\+' | sort | uniq -c
4 1995-01
1 1995-10
4 1995-1996
114 1995-1997
3 1995-1998
3 1995-1999
1308 1995-2000
70 1995-2001
149 1995-2002
49 1995-2003
279 1995-2004
213 1995-2005
137 1995-2006
321 1995-2007
184 1995-2008
48 1995-2009
20 1995-2010
55 1995-2011
57 1995-2012
77 1995-2013
11 1995-2014
44 1995-2015
53 1995-2016
89 1995-2017
29 1995-2018
1 1995-8
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.
The top 3 lines are obsolete almost immediately, and git is there for that,
There is a difference between touching a file and writing it. I have argued before that this is a nice way of leaving traces also for people with limited participation in ROOT, and it's a good way of knowing whom to contact / ownership.
the copyright can be in a file at top level stating that that's the copyright unless a different one exists in the file
Multiple opinions exist on that one.
Also, many files don't have the header in any case
Indeed we have many files that have a different (c).
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.
There is a difference between touching a file and writing it. I have argued before that this is a nice way of leaving traces also for people with limited participation in ROOT, and it's a good way of knowing whom to contact / ownership.
I still think that git blame
is more than sufficient for that, but the final choice is up to you.
// The first non-comment, non-empty line must be the #include guard. | ||
// Acceptable forms are: | ||
// ROOT_RCodingStyle, ROOT_RCodingStyle_hxx, ROOT_RCodingStyle_Hxx, | ||
// ROOT_RCODINGSTYLE, ROOT_RCODINGSTYLE_HXX |
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.
Why not choose one only?
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.
What or whom could a difference here confuse? What's the advantage of choosing one? They should be file-local, I sort of like that nobody can rely on them outside this file ;-)
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 likely mangle at least the component path in include protector. It may become very ugly to debug if the include protector names are duplicate between two unrelated files.
I'd make sense to me to stick with one include protector style (the latter).
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.
Choosing only one is good for consistency. Isn't this trying to improve exactly that? I don't really care which one we choose, as long as it's consistent throughout the code. At the very least one choice should be recommended over the others. There's also #pragma once
, but since it's not in any standard, maybe we should stay away from that.
|
||
// Especially within header files, reduce the number of included headers as | ||
// much as possible, at the expense of more forward declarations. | ||
// EXCEPTION: standard library classes must be #included, not forward declared. |
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.
Even the easy-to-forward-declare ones?
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.
Like?
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.
Doh, I get your point :)
README/RCodingStyle.hxx
Outdated
// Include non-ROOT, non-stdlib headers last. | ||
// Rationale: non-ROOT, non-stdlib headers often #define like mad. Reduce interference | ||
// with ROOT or stdlib headers. | ||
#include <png.h> |
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.
That sounds weird. In principle png.h may depend on stl. That's not a problem for non-ROOT packages but what about the ones that are on the borderline: eg libafterimage and others that are patched by us.
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.
png.h may depend on stl
No. System headers never depend on C++ and should thus come last.
static std::string fgNameBadPleaseUseStaticFunctionStaticVariable; | ||
|
||
protected: | ||
/// FOURTH section: non-public functions. |
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.
There seems to be no THIRD.
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.
// THIRD section: data members.
?
README/RCodingStyle.hxx
Outdated
double Add(const TExampleClass &a, const TExampleClass &b); | ||
|
||
} // namespace ROOT | ||
#endif // #ifndef ROOT_RCodingStyle |
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.
I'd omit the #ifndef
, it's meaning is implied by the previous token ;)
Starting build on |
1 similar comment
Starting build on |
@@ -174,5 +174,5 @@ public: | |||
double Add(const TExampleClass &a, const TExampleClass &b); | |||
|
|||
} // namespace ROOT | |||
#endif // #ifndef ROOT_RCodingStyle | |||
#endif // ROOT_RCodingStyle |
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.
Commenting on the commit message... Maybe a Suggested-by:
tag in the body of the commit would be better?
There's a JIRA issue on me for the style of commit messages, maybe we should discuss this today too?
Build failed on slc6/gcc48. Errors:
|
dcc01dc
to
68471fc
Compare
Starting build on |
Build failed on slc6/gcc48. Errors:
|
Starting build on |
Starting build on |
Starting build on |
Build failed on centos7/clang39. Errors:
|
@@ -0,0 +1,83 @@ | |||
/// \file RCodingStyle.cxx |
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.
Sometimes it makes sense to add \brief
section which describes the contents and the purpose of the files.
// Parts of ROOT might want to use sub-namespaces for *internal* code. | ||
// Such code might include the following two namespaces: | ||
namespace Detail { | ||
// Contains code that is not expected to be seen by the everage user. |
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.
typo everage
Starting build on |
ROOT::RExampleClass::~RExampleClass() | ||
{ | ||
} |
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.
why not ROOT::RExampleClass::~RExampleClass() = default;
?
// Include ROOT's headers first, in alphabetical order: | ||
// Rationale: make sure that ROOT headers are standalone. | ||
// Do not use #include guards at the point of `#include`. | ||
// Rationale: compilers optimize this themselves, this is interfering with their optimization. | ||
// Use <>, not "". | ||
// Rationale: "" looks at ./ first; as ROOT headers are included by user code | ||
// that adds context fragility. | ||
#include <ROOT/TSeq.hxx> | ||
// Include v6 ROOT headers last. | ||
// You're welcome to state what's used from a header, i.e. why it's included. | ||
#include <Rtypes.h> // for ULong64_t | ||
|
||
// Now include other C++ headers hat are not from the stdlib: | ||
// e.g. #include <cppyy/CPpYy.h> | ||
|
||
// Include stdlib headers next, in alphabetical order. | ||
#include <string> | ||
|
||
// Include C headers last. | ||
// Rationale: non-ROOT, non-stdlib headers often #define like mad. Reduce interference | ||
// with ROOT or stdlib headers. | ||
#include <curses.h> |
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.
It would be great if these rules could be automated via the IncludeCategories
setting in clang-format.
/// Static functions line up alphabetically with the others. | ||
static int GetSeq() { return kSeq; } | ||
|
||
/// It is fine to have one-line function declarations. |
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.
I guess you mean function definitions.
/// \param[in] input A collection of strings to use. | ||
/// \return Always return true but if it could fail would return false in that case. | ||
/// | ||
/// All functions must have at least one line of comments, parseable/useable by doxygen. |
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.
That sounds very strict to me. Simple functions with good names should not need comments.
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.
I agree and disagree. One line of comment should be mandatory, because otherwise the docs look like this:
https://root.cern/doc/master/classTInterpreter.html
This one line should be one sentence, ending with a .
, so doxygen automatically recognises this as a \brief
.
I agree, though, that after having written a single sentence, you may leave out the rest for trivial functions.
|
||
/// Virtual destructors of derived classes may be decorated with `virtual` (even though | ||
/// they "inherit" the virtuality of the virtual base class destructor). | ||
virtual ~RCodingStyle() {} |
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.
Should probably be virtual ~RCodingStyle() = default;
.
/// \param[in] input A collection of strings to use. | ||
/// \return Always return true but if it could fail would return false in that case. | ||
/// | ||
/// All functions must have at least one line of comments, parseable/useable by doxygen. |
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.
I agree and disagree. One line of comment should be mandatory, because otherwise the docs look like this:
https://root.cern/doc/master/classTInterpreter.html
This one line should be one sentence, ending with a .
, so doxygen automatically recognises this as a \brief
.
I agree, though, that after having written a single sentence, you may leave out the rest for trivial functions.
// that adds context fragility. | ||
#include <ROOT/TSeq.hxx> | ||
// Include v6 ROOT headers last. | ||
// You're welcome to state what's used from a header, i.e. why it's included. |
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.
In practice, this might be outdated the second time a file is touched.
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.
Fully agree!
} | ||
|
||
/// Instead of static data members (whether private or public), use outlined static | ||
/// functions. This solves the static initializion fiasco, and delays the initialization |
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.
/// functions. This solves the static initializion fiasco, and delays the initialization | |
/// functions. This solves the static initialization fiasco, and delays the initialization |
}; | ||
|
||
///\class RCodingStyle | ||
/// This is exhaustive documentation of the class template, explaining the constraints |
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.
The first thing after the \class macro should be the brief documentation. Doxygen takes the first sentence of the docs if no \brief
is passed, so try to just write one sentence in one line that ends with a .
.
///\class RCodingStyle | ||
/// This is exhaustive documentation of the class template, explaining the constraints | ||
/// on the template parameters, e.g. | ||
/// `IDX` must be positive, `T` must be copyable. |
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.
Recommend using doxygen's\tparam
, e.g.:
/// `IDX` must be positive, `T` must be copyable. | |
/// \tparam IDX The index type. Must be positive. | |
/// \tparam T A class that is copyable. |
RCodingStyle() = default; | ||
|
||
// Open a group: | ||
/// \{ \name copy pperations |
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.
/// \{ \name copy pperations | |
/// \{ \name copy operations |
// Parts of ROOT might want to use sub-namespaces for *internal* code. | ||
// Such code might include the following two namespaces: | ||
namespace Detail { | ||
// Contains code that is not expected to be seen by the everage user. |
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.
// Contains code that is not expected to be seen by the everage user. | |
// Contains code that is not expected to be seen by the average user. |
/// \param a - first RExampleClass to add. | ||
/// \param b - second RExampleClass to add. |
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.
I think that doxygen generates better docs without the -
:
/// \param a - first RExampleClass to add. | |
/// \param b - second RExampleClass to add. | |
/// \param a First RExampleClass to add. | |
/// \param b Second RExampleClass to add. |
No description provided.