Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

"Bjarne Stroustrup announces C++ Core Guidelines"

595 views
Skip to first unread message

Lynn McGuire

unread,
Sep 22, 2015, 4:42:24 PM9/22/15
to
"Bjarne Stroustrup announces C++ Core Guidelines"
https://isocpp.org/blog/2015/09/bjarne-stroustrup-announces-cpp-core-guidelines

"This morning in his opening keynote at CppCon, Bjarne Stroustrup announced the C++ Core Guidelines
(github.com/isocpp/CppCoreGuidelines), the start of a new open source project on GitHub to build modern authoritative guidelines for
writing C++ code. The guidelines are designed to be modern, machine-enforceable wherever possible, and open to contributions and
forking so that organizations can easily incorporate them into their own corporate coding guidelines."

"The initial primary authors and maintainers are Bjarne Stroustrup and Herb Sutter, and the guidelines so far were developed with
contributions from experts at CERN, Microsoft, Morgan Stanley, and several other organizations. The guidelines are currently in a
“0.6” state, and contributions are welcome. As Stroustrup said: “We need help!”"

Lynn

Jorgen Grahn

unread,
Sep 23, 2015, 2:44:47 AM9/23/15
to
> '0.6' state, and contributions are welcome. As Stroustrup said: 'We need help!'"

Sounds like any other coding guidelines: I'm for them only when I
agree with them ... or am I too cynical?

On the other hand, the main problem with C++ IMHO is the many
conflicting styles and approaches you see in real-life code. The
worst ones (treat C++ as if it was 1995 || C || Java || Smalltalk)
aren't likely to be recommended here ...

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Juha Nieminen

unread,
Sep 23, 2015, 4:39:13 AM9/23/15
to
Jorgen Grahn <grahn...@snipabacken.se> wrote:
> Sounds like any other coding guidelines: I'm for them only when I
> agree with them ... or am I too cynical?

I'd say there are two types of coding guidelines (which can be mixed):
Those that concentrate on code safety and validity, and those that concentrate
on cosmetic minutiae.

An example of the former is the so-called "rule of three" (I suppose "rule
of four" in modern C++). The "rule of three" is not mandatory in order to
make a program work, but it makes programs safer.

An example of the latter is nitpicking about where opening curly braces
should be placed and what kind of prefixes you should use in your variable
names.

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

Öö Tiib

unread,
Sep 23, 2015, 7:09:14 AM9/23/15
to
On Wednesday, 23 September 2015 11:39:13 UTC+3, Juha Nieminen wrote:
>
> An example of the former is the so-called "rule of three" (I suppose "rule
> of four" in modern C++). The "rule of three" is not mandatory in order to
> make a program work, but it makes programs safer.

Those are "rule of five" (define all 5 or none) and "rule of zero" (prefer
none) . Unfortunately the Microsoft's newest compiler does not
support "rule of zero" since it can not make implicit move constructors.

Richard

unread,
Sep 23, 2015, 6:05:33 PM9/23/15
to
[Please do not mail me a copy of your followup]

Jorgen Grahn <grahn...@snipabacken.se> spake the secret code
<slrnn04ii9.e...@frailea.sa.invalid> thusly:

>Sounds like any other coding guidelines: I'm for them only when I
>agree with them ... or am I too cynical?

My guess is that you will agree with most of them because that aren't
about things like identifier names or whitespace, but more about
things like RAII, communicating your intent more clearly through code
and so-on.

I discovered quite a few ideas in there that I would like to adopt and
they weren't ideas I'd heard of before, so it's not the same-old
same-old rehashed once again.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Ian Collins

unread,
Sep 23, 2015, 6:14:36 PM9/23/15
to
Jorgen Grahn wrote:
> On Tue, 2015-09-22, Lynn McGuire wrote:
>> "Bjarne Stroustrup announces C++ Core Guidelines"
>> https://isocpp.org/blog/2015/09/bjarne-stroustrup-announces-cpp-core-guidelines
>>
>> "This morning in his opening keynote at CppCon, Bjarne Stroustrup announced the C++ Core Guidelines
>> (github.com/isocpp/CppCoreGuidelines), the start of a new open source project on GitHub to build modern authoritative guidelines for
>> writing C++ code. The guidelines are designed to be modern, machine-enforceable wherever possible, and open to contributions and
>> forking so that organizations can easily incorporate them into their own corporate coding guidelines."
>>
>> "The initial primary authors and maintainers are Bjarne Stroustrup and Herb Sutter, and the guidelines so far were developed with
>> contributions from experts at CERN, Microsoft, Morgan Stanley, and several other organizations. The guidelines are currently in a
>> '0.6' state, and contributions are welcome. As Stroustrup said: 'We need help!'"
>
> Sounds like any other coding guidelines: I'm for them only when I
> agree with them ... or am I too cynical?

From reading what is there, they appear to have made the sensible
decision to steer clear of the pettiness found in many coding guidelines.

One point from the quote above that will find favour with teams I'm
familiar with is "machine-enforceable wherever possible". Too many
standards fall down when it comes to practical enforcement.

--
Ian Collins

Jorgen Grahn

unread,
Sep 24, 2015, 6:48:47 AM9/24/15
to
On Wed, 2015-09-23, Richard wrote:
> [Please do not mail me a copy of your followup]
>
> Jorgen Grahn <grahn...@snipabacken.se> spake the secret code
> <slrnn04ii9.e...@frailea.sa.invalid> thusly:
>
>>Sounds like any other coding guidelines: I'm for them only when I
>>agree with them ... or am I too cynical?
>
> My guess is that you will agree with most of them because that aren't
> about things like identifier names or whitespace, but more about
> things like RAII, communicating your intent more clearly through code
> and so-on.

Unfortunately, you can disagree about those things too. (I think I'm
more or less on Stroustrup's wavelength, except I don't use
inheritance a lot.)

> I discovered quite a few ideas in there that I would like to adopt and
> they weren't ideas I'd heard of before, so it's not the same-old
> same-old rehashed once again.

Lesson: I should start by reading what's there. I already cloned the
repository, so ...

Richard

unread,
Sep 24, 2015, 1:01:08 PM9/24/15
to
[Please do not mail me a copy of your followup]

Jorgen Grahn <grahn...@snipabacken.se> spake the secret code
<slrnn07l7n.e...@frailea.sa.invalid> thusly:

>On Wed, 2015-09-23, Richard wrote:
>> things like RAII, communicating your intent more clearly through code
>> and so-on.
>
>Unfortunately, you can disagree about those things too. (I think I'm
>more or less on Stroustrup's wavelength, except I don't use
>inheritance a lot.)

IMO inheritance is overused in any language that supports it. I think
people often confuse OOP to mean "it's all about inheritance".

>> I discovered quite a few ideas in there that I would like to adopt and
>> they weren't ideas I'd heard of before, so it's not the same-old
>> same-old rehashed once again.
>
>Lesson: I should start by reading what's there. I already cloned the
>repository, so ...

Some things I saw for the first time that I liked:

- a template class not_null<T*> to clearly indicate that this is a raw
pointer that should never be null

- a template class owner<T*> to indicate that having this raw pointer
means ownership and not access through indirection.

Using these allows automated tools to discover misuse of these raw
pointers. Determining the intended semantics of raw pointers has
always been difficult to automate.

woodb...@gmail.com

unread,
Sep 30, 2015, 4:21:50 PM9/30/15
to
I disagree with this one

NL.16: Use a conventional class member declaration order

Reason: A conventional order of members improves readability.

When declaring a class use the following order

types: classes, enums, and aliases (using)
constructors, assignments, destructor
functions
data

Used the public before protected before private order.

Private types and functions can be placed with private data.

---------------------------------------------

I suggest to make the data members first.


Brian
Ebenezer Enterprises - 'Is it not lawful for me to
do what I wish with what is my own? Or is your eye
envious because I am generous?' "So the last shall
be first, and the first last." Matthew 20:15,16

http://webEbenezer.net

mad...@acm.org

unread,
Sep 30, 2015, 4:55:47 PM9/30/15
to
One presumes class data members would be private, else what's the point of having a class?

Given that, putting the data members first would be contrary to the generally accepted public, protected, private ordering with a class.

You are not suggesting public data members I am certain.

Randy.

Paavo Helde

unread,
Oct 1, 2015, 1:54:41 AM10/1/15
to
r...@zedat.fu-berlin.de (Stefan Ram) wrote in news:data-members-
2015093...@ram.dialup.fu-berlin.de:

> The data members are the key to understanding
> the implementation. Therefore, they must be declared first.

Normally, a class would be implemented once and used many times. So the
usage aspect is far more important than the implementation. For using the
class one does not need to understand the implementation (requiring this
could become very counter-productive); one rather needs to understand the
public interface instead.

So the interface part is used and needed for both for the class users and
class developers, whereas the implementation part is only needed for class
developers. Viewed this way, it is immediately clear which part is more
important and should come first in the class definition. In an ideal world
the implementation part of the class would be split off and placed only in
the implementation file, but unfortunately this is not the way how C++
works.

Cheers
Paavo

Öö Tiib

unread,
Oct 1, 2015, 8:37:07 AM10/1/15
to
On Wednesday, 30 September 2015 23:21:50 UTC+3, woodb...@gmail.com wrote:
> On Tuesday, September 22, 2015 at 3:42:24 PM UTC-5, Lynn McGuire wrote:
> > "Bjarne Stroustrup announces C++ Core Guidelines"
> > https://isocpp.org/blog/2015/09/bjarne-stroustrup-announces-cpp-core-guidelines
> >
> > "This morning in his opening keynote at CppCon, Bjarne Stroustrup announced the C++ Core Guidelines
> > (github.com/isocpp/CppCoreGuidelines), the start of a new open source project on GitHub to build modern authoritative guidelines for
> > writing C++ code. The guidelines are designed to be modern, machine-enforceable wherever possible, and open to contributions and
> > forking so that organizations can easily incorporate them into their own corporate coding guidelines."
> >
> > "The initial primary authors and maintainers are Bjarne Stroustrup and Herb Sutter, and the guidelines so far were developed with
> > contributions from experts at CERN, Microsoft, Morgan Stanley, and several other organizations. The guidelines are currently in a
> > "0.6" state, and contributions are welcome. As Stroustrup said: "We need help!""
> >
> > Lynn
>
> I disagree with this one
>
> NL.16: Use a conventional class member declaration order
>
> Reason: A conventional order of members improves readability.
>
> When declaring a class use the following order
>
> types: classes, enums, and aliases (using)
> constructors, assignments, destructor
> functions
> data
>
> Used the public before protected before private order.
>
> Private types and functions can be placed with private data.
>
> ---------------------------------------------
>
> I suggest to make the data members first.

Why you suggest impossible things?

It is typically impossible to have data members before
"types: classes, enums, and aliases (using)" since the data
member declarations often use the types and then it won't
compile.

Also you don't elaborate so it is perhaps how you like
to see your own code that is written for yourself. That is
however something what no one else cares about.

Daniel

unread,
Oct 1, 2015, 8:55:44 AM10/1/15
to
On Thursday, October 1, 2015 at 1:54:41 AM UTC-4, Paavo Helde wrote:
>
> So the interface part is used and needed for both for the class users and
> class developers, whereas the implementation part is only needed for class
> developers. Viewed this way, it is immediately clear which part is more
> important and should come first in the class definition.

Au contraire, it isn't clear at all :-) Would it make any difference to a typical user of, say, std::string, if the author of std::basic_string arranged the constituents with private data members first? There may have been a time when C++ header files were less implementation and more interface, but they were never wholly that, and with today's header only-template libraries and proxy returns, far less so.

In fact, typical users of std::string are going to consult cppreferenc.com or cplusplus.com, not the header. And they want to see documentation for std::string, not std::basic_string. And if a function returns a proxy, they want to see what it resolves to, not some incomprehensible template thing. And more generally, any class exposed to users deserves some API docs, markdown and wiki make this easy.

In Java, which puts everything in the class body, and supports generated API docs, the convention is to put the private data members first, to make life easier for the implementer and maintainer. It seems reasonable to me.

Daniel

Scott Lurndal

unread,
Oct 1, 2015, 9:04:37 AM10/1/15
to
The default security for a class is private. Thus, one presumes
that unless otherwise specified, the data members would be private
regardless of where in the class definition they occur.

Daniel

unread,
Oct 1, 2015, 9:34:25 AM10/1/15
to
Even if Brian's coding standards were completely unbending (if they had, for example, been given to him by his god), I am sure that with only a little thought (very little), he would have a work around for that difficulty. But generally speaking people who would like to see data members first are more likely to be practical people who would not be dogmatic on that point.

The argument for public - protected - private, in that order, is more one of convention, that's typically how it's done in C++.

Daniel

Mr Flibble

unread,
Oct 1, 2015, 12:32:48 PM10/1/15
to
On 30/09/2015 23:47, Stefan Ram wrote:
> mad...@acm.org writes:
>> One presumes class data members would be private, else what's
>> the point of having a class?
>
> Usually data members are public, as - for example - in,
>
> 20.3.2 Class template pair
> namespace std { template< class T1, class T2 >
> struct pair { T1 first; T2 second; ... }}
>
> But, I agree that it's better to make data members private
> /if/ the class should happen to have invariants.

I disagree: any non-const data members that contribute to a class
invariant MUST be private.

>
>> Given that, putting the data members first would be contrary
>> to the generally accepted public, protected, private ordering
>> with a class.
>
> One needs to know the data members first to understand the
> constructors and member functions. How else can one judge
> whether /all/ data members are properly initialized in the
> constructor when one has not yet read their declarations,
> for example? The data members are the key to understanding
> the implementation. Therefore, they must be declared first.

I strongly disagree: data members that must be private (see above) are
an implementation detail of the class and SHOULD be declared last. When
considering the USERS of class rather than the IMPLEMENTERS of a class
then you need to think in terms of ABSTRACTIONS not data members when
looking at classes with invariants.

>
> Then come the lower-level functions and finally the higher-
> level functions (bottom-up). The lower-level functions are
> more close to the data member. But very-high level functions
> of the class, who do not need direct access to the data
> members should be non-members.

Perhaps you are saying here that you should prefer free functions to
public members? If so then I agree however I am not sure about your
"high-level" and "low-level" classification. Private members should
appear after public members.

/Flibble

woodb...@gmail.com

unread,
Oct 1, 2015, 1:42:16 PM10/1/15
to
Types
Data
Ctors, dtors
Functions

If you don't have local typess the data is first.

> Also you don't elaborate so it is perhaps how you like
> to see your own code that is written for yourself. That is
> however something what no one else cares about.

The guideline doesn't elaborate either.

From what I can tell a lot of people write classes the way
I suggested.

Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net

Öö Tiib

unread,
Oct 1, 2015, 2:20:24 PM10/1/15
to
Things that are meant to be read are usually organized so that
what is meant for biggest audience comes first and
details schmetails last. In a class the public interface
is what concerns most of the readers, so plain old courtesy
is to put it first. If you write the code for yourself
only then it does not matter but then also why should others
care what conventions you use?

Jorgen Grahn

unread,
Oct 1, 2015, 2:36:01 PM10/1/15
to
On Thu, 2015-10-01, Daniel wrote:
> On Thursday, October 1, 2015 at 1:54:41 AM UTC-4, Paavo Helde wrote:
>>
>> So the interface part is used and needed for both for the class users and
>> class developers, whereas the implementation part is only needed for class
>> developers. Viewed this way, it is immediately clear which part is more
>> important and should come first in the class definition.
>

> Au contraire, it isn't clear at all :-) Would it make any difference
> to a typical user of, say, std::string, if the author of
> std::basic_string arranged the constituents with private data members
> first?

Probably not, but almost none of the header files out there are
<string> ...

> There may have been a time when C++ header files were less
> implementation and more interface, but they were never wholly that,
> and with today's header only-template libraries and proxy returns, far
> less so.

I think the vast majority of header files will always contain plain
non-templated classes (and function prototypes, and so on).

And even with moderate use of templates, where's the problem?

template<class T>
class Foo {
...
};

doesn't need to be unreadable than a normal class.

Reading the GNU version of std::basic_string ... yes, it's unreadable.
But that's because
a) its interface is so big
b) it mixes public and private blocks. I count eight or nine
switches public, private, public again ...
c) the documentation is included.

j4n bur53

unread,
Oct 1, 2015, 6:00:49 PM10/1/15
to
Hi,

Daniel schrieb:
> In Java, which puts everything in the class body, and
> supports generated API docs, the convention is to put
> the private data members first, to make life easier for
> the implementer and maintainer. It seems reasonable to me.

Yes, thats true, the fields are usually mentioned first,
and usually they are made private, and the access is
mediated through setters and getters, if at all.

But then came Android, and for performance reasons it
was recommended not to make private fields, but instead
public fields without setters and getters.

In general there are no strict rules what should come
first and what should come later. Also note there are
is not only public and private visibility, but also
package local also for fields, and protected only for
methods and constructors.

Further the API docs generators have a parameter which
visibility level should go into the doc. If you have
the desire you can generate an API doc that contains
even the private class members.

Bye


j4n bur53

unread,
Oct 1, 2015, 6:02:00 PM10/1/15
to
j4n bur53 schrieb:
> In general there are no strict rules what should come
> first and what should come later.

Mainly because Java doesn't need forward declarations.
There is a small exception, constants need to refer to
already defined and constant evaluable expressions.

Alf P. Steinbach

unread,
Oct 1, 2015, 11:49:44 PM10/1/15
to
On 9/30/2015 10:21 PM, woodb...@gmail.com wrote:
> On Tuesday, September 22, 2015 at 3:42:24 PM UTC-5, Lynn McGuire wrote:
>> "Bjarne Stroustrup announces C++ Core Guidelines"
>> https://isocpp.org/blog/2015/09/bjarne-stroustrup-announces-cpp-core-guidelines
>>
>[snip]
>
> I disagree with this one
>
> NL.16: Use a conventional class member declaration order
>
> Reason: A conventional order of members improves readability.
>
> When declaring a class use the following order
>
> types: classes, enums, and aliases (using)
> constructors, assignments, destructor
> functions
> data
>
> Used the public before protected before private order.
>
> Private types and functions can be placed with private data.
>
> ---------------------------------------------
>
> I suggest to make the data members first.

I also disagree with the rule, it seems non-sensical, and yes, like you,
for common use of the code (as opposed to documentation) I find it
better to have data first. And generally, I find it better to declare
things before they're used. That's recognized as a sound rule in almost
every other context, and it doesn't cease to be a good idea in C++.

For a long time I tried to group things logically, e.g. accessors
followed by mutators, but it turned out to have too many exceptions, and
I now think that it's more important to e.g. place `const` and
non-`const` variants of a method together.

Unless special accessibility is needed, at the end of a class I place
(1) destructor, if any, and (2) constructors, with the standard ones first.


Cheers,

- Alf

Vir Campestris

unread,
Oct 2, 2015, 4:50:56 PM10/2/15
to
On 30/09/2015 23:47, Stefan Ram wrote:
> One needs to know the data members first to understand the
> constructors and member functions. How else can one judge
> whether/all/ data members are properly initialized in the
> constructor when one has not yet read their declarations,
> for example? The data members are the key to understanding
> the implementation. Therefore, they must be declared first.

I disagree.

When reading the class header chances are you want to use it - so you
are interested in the interface. Which is the public stuff - so it comes
first.

The data is an implementation detail, and I'm happy to hide it.

Andy

Jorgen Grahn

unread,
Oct 2, 2015, 5:41:05 PM10/2/15
to
On Fri, 2015-10-02, Stefan Ram wrote:
> Vir Campestris <vir.cam...@invalid.invalid> writes:
>>On 30/09/2015 23:47, Stefan Ram wrote:
>>>One needs to know the data members first to understand the
>>>constructors and member functions. How else can one judge
>>>whether/all/ data members are properly initialized in the
>>>constructor when one has not yet read their declarations,
>>>for example? The data members are the key to understanding
>>>the implementation. Therefore, they must be declared first.
>>When reading the class header chances are you want to use it - so you
>>are interested in the interface. Which is the public stuff - so it comes
>>first.
>
> When one wants to use a class, one reads its documentation
> (the documentation can be generated using Doxygen or be
> written as a separate document such as cppreference).

I don't -- like Vir I read the header file to see the API. And it
seems those C++ Core Guidelines aim to support us, which is nice.

Chris Vine

unread,
Oct 3, 2015, 11:26:19 AM10/3/15
to
On 2 Oct 2015 21:40:52 GMT
I do not often seem to find myself agreeing with Stefan, but I am
pleased that on this occasion I do.

IMO the correct place to provide documentation for a library is in the
library documentation, which can be generated from the header file
using doxygen or other third-party tools. If the library author cannot
be bothered to document the public interfaces of the library, then I
would not want to use it. Enforcing an arbitrary rule about the
ordering of class members in the class definition as a substitute for
inadequate or non-existent documentation seems crazy to me.

Nonetheless, I thought I was pretty old school in preferring to provide
member data declarations (usually private) before member function
declarations (usually public) in class definitions. Particularly when
looking at an inline method, including all methods defined within the
body of a template class definition, I like to look at the code in an
upwards direction to find the object data that the method is operating
on and not scrabble around for some mention of it later in the header
file. It is interesting that it appears I am not alone in that
preference. I fully realize that the look-up rules for struct/class
definitions mean that (unlike with most other uses of undeclared
variables in C++) there is no language impediment to having an inline
method operate on a data member before that data member has been
declared. However, I do not like the practice.

Of course, for non-library code, there may not be a need for separate
documentation. But for these, the people interested in the code are
only the original author(s) and any subsequent maintainer(s). As
mentioned, for these I prefer the declare-before-use approach.

Chris

Jorgen Grahn

unread,
Oct 3, 2015, 5:27:49 PM10/3/15
to
On Sat, 2015-10-03, Chris Vine wrote:
> On 2 Oct 2015 21:40:52 GMT
> Jorgen Grahn <grahn...@snipabacken.se> wrote:
>> On Fri, 2015-10-02, Stefan Ram wrote:
>> > Vir Campestris <vir.cam...@invalid.invalid> writes:
>> >>On 30/09/2015 23:47, Stefan Ram wrote:
>> >>>One needs to know the data members first to understand the
>> >>>constructors and member functions. How else can one judge
>> >>>whether/all/ data members are properly initialized in the
>> >>>constructor when one has not yet read their declarations,
>> >>>for example? The data members are the key to understanding
>> >>>the implementation. Therefore, they must be declared first.
>> >>When reading the class header chances are you want to use it - so
>> >>you are interested in the interface. Which is the public stuff - so
>> >>it comes first.
>> >
>> > When one wants to use a class, one reads its documentation
>> > (the documentation can be generated using Doxygen or be
>> > written as a separate document such as cppreference).
>>
>> I don't -- like Vir I read the header file to see the API. And it
>> seems those C++ Core Guidelines aim to support us, which is nice.
>
> I do not often seem to find myself agreeing with Stefan, but I am
> pleased that on this occasion I do.
>
> IMO the correct place to provide documentation for a library

Oh. I was talking about non-library code only. I was going to state
that above, but changed my mind because I thought it was obvious.

After all, most code is not intended as reuable libraries.

Chris Vine

unread,
Oct 4, 2015, 3:04:00 AM10/4/15
to
On 3 Oct 2015 21:27:19 GMT
I was responding to your comment that "I read the header file to see
the API". I do not do so: I look at the documentation to see the API.

If your point does not concern libraries (or other similar code intended
to be used by other modules which ought to be documented), then the
interest group for the hypothetical header file containing class
definitions comprises the authors and maintainers of the code. In
order for the maintainer to maintain (and so understand) any given
class method, she needs to look at the data that the class is operating
on.

For inline and/or template methods in particular, that in my view is
something best done by declaring the class data before declaring the
public methods. I see zero advantage in declaring the public methods
in advance of the data, as proposed in the style guide.

Chris

Öö Tiib

unread,
Oct 5, 2015, 2:34:15 AM10/5/15
to
On Sunday, 4 October 2015 10:04:00 UTC+3, Chris Vine wrote:
> On 3 Oct 2015 21:27:19 GMT
> Jorgen Grahn <grahn...@snipabacken.se> wrote:
> > On Sat, 2015-10-03, Chris Vine wrote:
> > > I do not often seem to find myself agreeing with Stefan, but I am
> > > pleased that on this occasion I do.
> > >
> > > IMO the correct place to provide documentation for a library
> >
> > Oh. I was talking about non-library code only. I was going to state
> > that above, but changed my mind because I thought it was obvious.
> >
> > After all, most code is not intended as reuable libraries.
>
> I was responding to your comment that "I read the header file to see
> the API". I do not do so: I look at the documentation to see the API.
>
> If your point does not concern libraries (or other similar code intended
> to be used by other modules which ought to be documented), then the
> interest group for the hypothetical header file containing class
> definitions comprises the authors and maintainers of the code.

C++ does not contain modules. "Modules" are usually just some sort
of group of classes. In C++ programs there are sometimes hundreds of
classes. Most of those classes do not participate in interface
of "module".

> In
> order for the maintainer to maintain (and so understand) any given
> class method, she needs to look at the data that the class is operating
> on.

It perhaps depends if you get work that your "class Foo needs maintenance"
or do you get work that "your program acts oddly / non-suitably".

>
> For inline and/or template methods in particular, that in my view is
> something best done by declaring the class data before declaring the
> public methods. I see zero advantage in declaring the public methods
> in advance of the data, as proposed in the style guide.

"Methods"? Smells like Java here.

Daniel

unread,
Oct 5, 2015, 9:06:17 AM10/5/15
to
On Monday, October 5, 2015 at 2:34:15 AM UTC-4, Öö Tiib wrote:
>
> C++ does not contain modules.

If Herb Sutter and Andrei Alexandrescu are allowed to use "modules" in a looser sense ("Don't allow exceptions to propagate across module boundaries"), I don't see why Chris can't.

> In C++ programs there are sometimes hundreds of
> classes. Most of those classes do not participate in interface
> of "module".
>
Indeed.

> > order for the maintainer to maintain (and so understand) any given
> > class method, she needs to look at the data that the class is operating
> > on.
>
> It perhaps depends if you get work that your "class Foo needs maintenance"
> or do you get work that "your program acts oddly / non-suitably".
>
Unclear. Generally, the maintainer has to understand the implementation.

> > I see zero advantage in declaring the public methods
> > in advance of the data.
>
> "Methods"? Smells like Java here.

Not to mention C#, Python, Javascript, D, and C++ (where it's a synonym for member function) ...

Daniel

Öö Tiib

unread,
Oct 5, 2015, 11:40:04 AM10/5/15
to
On Monday, 5 October 2015 16:06:17 UTC+3, Daniel wrote:
> On Monday, October 5, 2015 at 2:34:15 AM UTC-4, Öö Tiib wrote:
> >
> > C++ does not contain modules.
>
> If Herb Sutter and Andrei Alexandrescu are allowed to use "modules" in a looser sense ("Don't allow exceptions to propagate across module boundaries"), I don't see why Chris can't.

ad verecundiam? Book author typically explains what they mean with a
word. Without explaining a "module" is just "some sort of group of
classes" in C++. I already explained it but you snipped that.

>
> > In C++ programs there are sometimes hundreds of
> > classes. Most of those classes do not participate in interface
> > of "module".
> >
> Indeed.

The documentation however is about interface of "module"
(whatever it means in particular context).

>
> > > order for the maintainer to maintain (and so understand) any given
> > > class method, she needs to look at the data that the class is operating
> > > on.
> >
> > It perhaps depends if you get work that your "class Foo needs maintenance"
> > or do you get work that "your program acts oddly / non-suitably".
> >
> Unclear.

Defect reports or feature requests that concern classes are only about
libraries. Most C++ code are not such libraries. On most cases the
defect reports or feature requests are about behavior of particular
programs.

> Generally, the maintainer has to understand the implementation.

Maintainer has first to understand what the classes are supposed to
do. That is easier when public interface is put first. Implementation
details are of interest only when it is clear that a class does not do
what it is supposed to do.

>
> > > I see zero advantage in declaring the public methods
> > > in advance of the data.
> >
> > "Methods"? Smells like Java here.
>
> Not to mention C#, Python, Javascript, D, and C++ (where it's a synonym for member function) ...

Especially weird is to read "template methods" like Chris wrote.
"Template method" is name of behavioral design pattern and has
nothing to do with "member function templates" of C++. Of course
anyone can write how and what they want and mean whatever they
think with it. Messy classes and incomprehensible documentation.
Actual reality.

Tobias Müller

unread,
Oct 5, 2015, 12:23:36 PM10/5/15
to
Alf P. Steinbach <alf.p.stein...@gmail.com> wrote:
> On 9/30/2015 10:21 PM, woodb...@gmail.com wrote:
>> On Tuesday, September 22, 2015 at 3:42:24 PM UTC-5, Lynn McGuire wrote:
>>> "Bjarne Stroustrup announces C++ Core Guidelines"
>>> https://isocpp.org/blog/2015/09/bjarne-stroustrup-announces-cpp-core-guidelines
>>>
>> [snip]
>>
>> I disagree with this one
>>
>> NL.16: Use a conventional class member declaration order
>>
>> Reason: A conventional order of members improves readability.
>>
>> When declaring a class use the following order
>>
>> types: classes, enums, and aliases (using)
>> constructors, assignments, destructor
>> functions
>> data
>>
>> Used the public before protected before private order.
>>
>> Private types and functions can be placed with private data.
>>
>> ---------------------------------------------
>>
>> I suggest to make the data members first.
>
> I also disagree with the rule, it seems non-sensical, and yes, like you,
> for common use of the code (as opposed to documentation) I find it
> better to have data first. And generally, I find it better to declare
> things before they're used. That's recognized as a sound rule in almost
> every other context, and it doesn't cease to be a good idea in C++.

That's why classes/enums are declared first.
But in C++ usually you don't _use_ data members in the class definition.
Except possibly for inline functions, but I always put after the class
definition.

Tobi

Jorgen Grahn

unread,
Oct 5, 2015, 3:00:29 PM10/5/15
to
On Sun, 2015-10-04, Chris Vine wrote:
> On 3 Oct 2015 21:27:19 GMT
> Jorgen Grahn <grahn...@snipabacken.se> wrote:
>> On Sat, 2015-10-03, Chris Vine wrote:
>> > I do not often seem to find myself agreeing with Stefan, but I am
>> > pleased that on this occasion I do.
>> >
>> > IMO the correct place to provide documentation for a library
>>
>> Oh. I was talking about non-library code only. I was going to state
>> that above, but changed my mind because I thought it was obvious.
>>
>> After all, most code is not intended as reuable libraries.
>
> I was responding to your comment that "I read the header file to see
> the API". I do not do so: I look at the documentation to see the API.

I was sloppy when I wrote both my postings -- sorry.

> If your point does not concern libraries (or other similar code intended
> to be used by other modules which ought to be documented), then the
> interest group for the hypothetical header file containing class
> definitions comprises the authors and maintainers of the code.

Yes -- and that was exactly the sitation I was thinking about.

But when I'm modifying the code, of course I'm seeing APIs! I may be
allowed to modify class Foo, but unless I find a problem with it I
will treat it as something fixed. It's an API, but I'm allowed to
read the implementation if I need to, and change the implementation or
the interface if necessary (since I have control over all code using
it, and can adjust it).

That too looks silly now that I reread it ... because that's obviously
how you use header files in C++, isn't it? Divide and conquer, and so
on. That's what they are for /within/ a project.

> In order for the maintainer to maintain (and so understand) any given
> class method, she needs to look at the data that the class is operating
> on.

You need the /option/ to do so, but most of the time you want to deal
with the interface only. I cannot keep all of the implementation
details in my head at once ...

Richard

unread,
Oct 6, 2015, 11:07:23 AM10/6/15
to
[Please do not mail me a copy of your followup]

Vir Campestris <vir.cam...@invalid.invalid> spake the secret code
<0cudnY2LDKaBc5PL...@brightview.co.uk> thusly:

>When reading the class header chances are you want to use it - so you
>are interested in the interface. Which is the public stuff - so it comes
>first.
>
>The data is an implementation detail, and I'm happy to hide it.

Bingo.

If you need to understand the private members of a class in order to
understand how to use it's public interface, then it is very likely
that the class is poorly designed and doesn't have an intention
revealing set of public methods.

Having to study the implementation of a function or class in order to
understand how to use it properly is a design smell. It means that
the interface itself doesn't reveal enough about the semantics of the
function or class for you to understand how to use it properly.

The standard library does pretty well in this regard; so far I have
never needed to reverse engineer anything in the standard library or
inspect any private data members in order to know what these functions
or classes do and how they are to be used. This is a good thing too,
because for some reason people who write standard library
implementations seem to enjoy the most cryptic of coding styles -- and
we're not just talking about how the identifiers begin with _.

SG

unread,
Oct 15, 2015, 7:27:12 AM10/15/15
to
On Wednesday, September 23, 2015 at 1:09:14 PM UTC+2, Öö Tiib wrote:
> On Wednesday, 23 September 2015 11:39:13 UTC+3, Juha Nieminen wrote:
> >
> > An example of the former is the so-called "rule of three" (I suppose "rule
> > of four" in modern C++). The "rule of three" is not mandatory in order to
> > make a program work, but it makes programs safer.
>
> Those are "rule of five" (define all 5 or none) and "rule of zero"
> (prefer none) .

The "rule of five" isn't a thing. It's a little more subtle. For
example, the following class is (useless but) perfectly fine:

class indirect_int {
int* ptr;
public:
indirect_int(int v)
: ptr(new int(v)) {}

// just 2 user-defined special member functions ...

~indirect_int()
{ delete ptr; }
indirect_int(indirect_int && x)
: ptr(x.ptr) { x.ptr = nullptr; }
};

That's because a user-supplied move ctor or move assignment operator
will inhibit the creation of other compiler-generated copy or move
operations. Ideally, this inhibition would also kick in if the user
declares a dtor, copy ctor and copy assignment operator. Actually,
the 2011 rules are described this way. There is just a special
exception for C++98 compatibility. But that exception is already
*deprecated*. So, in C++11 mode (or higher) a compiler *should*
actually warn about the use of such a deprecated rule that makes the
compiler generate a copy operation that probably does the wrong thing.
So, given

class indirect_int {
int* ptr;
public:
indirect_int(int v)
: ptr(new int(v)) {}

// just 2 user-defined special member functions ...

~indirect_int()
{ delete ptr; }
};

int main() {
indirect_int a(23);
indirect_int b = a;
} // <-- double-free error here

I would expect a *good* compiler to issue a warning like this:

indirect_int b = a;
^
This makes the compiler generate a copy ctor according to
a deprecated rule. If you want indirect_int really to be
copyable consider making it explicit:

indirect_int(indirect_int const&) = default;
indirect_int& operator=(indirect_int const&) = default;

However, the more likely case is that this generated copy
ctor does the wrong thing because you declared a dtor for
indirect_int. In this case, you should add

indirect_int(indirect_int const&) = delete;
indirect_int& operator=(indirect_int const&) = delete;

to the class definition.

Unforunately, last time I checked, no compiler would actually issue a
warning in such a case in C++11 mode. :-( Things could be so much
simpler for beginners...

Öö Tiib

unread,
Oct 18, 2015, 4:13:20 PM10/18/15
to
I like the way how you think but real compilers don't do what you say
these *should*. So the subtle issue is still very real.

> So, given
>
> class indirect_int {
> int* ptr;
> public:
> indirect_int(int v)
> : ptr(new int(v)) {}
>
> // just 2 user-defined special member functions ...
>
> ~indirect_int()
> { delete ptr; }
> };
>
> int main() {
> indirect_int a(23);
> indirect_int b = a;
> } // <-- double-free error here
>
> I would expect a *good* compiler to issue a warning
> like this:
>
> indirect_int b = a;
> ^
> This makes the compiler generate a copy ctor according to
> a deprecated rule.

I would also love warning, but it is tricky to make good suggestion how to
achieve that it does not look rather confusing.
For example when the above 'indirect_int' is used as member in a class
made by rule of zero and then object of that class is copied.

> Unforunately, last time I checked, no compiler would actually issue a
> warning in such a case in C++11 mode. :-( Things could be so much
> simpler for beginners...

Yes. Neither in C++11 nor in C++14 mode. The vendors of compilers
interpret that deprecation somehow differently and so we have to keep
enforcing safe usage with our coding standards.

asetof...@gmail.com

unread,
Oct 25, 2015, 2:13:30 AM10/25/15
to
One presumes class data members would be private, else what's the point of having a class?

Given that, putting the data members first would be contrary to the generally accepted public, protected, private ordering with a class.

You are not suggesting public data members I am certain.

Randy.
_____________

It is the same problem of "const"...

One write a new word "const"
and all theory
when could be enough programmer
think more or does some trick

For example I have the trick-law
that function can change its arg
only if they are passed through
one pointer and never by reference.

The same for classes: All has to be
public and are useful the same
because
reduce code size and are good
for create and better destroy
objects, in right places

And all memory remain always
Below the control of the
programmer the same
because programmer write
constructor and destructor


Vladislav Yaroslavlev

unread,
Nov 15, 2015, 5:13:00 PM11/15/15
to
On Wednesday, September 23, 2015 at 2:09:14 PM UTC+3, Öö Tiib wrote:
> On Wednesday, 23 September 2015 11:39:13 UTC+3, Juha Nieminen wrote:
> >
> > An example of the former is the so-called "rule of three" (I suppose "rule
> > of four" in modern C++). The "rule of three" is not mandatory in order to
> > make a program work, but it makes programs safer.
>
> Those are "rule of five" (define all 5 or none) and "rule of zero" (prefer
> none) . Unfortunately the Microsoft's newest compiler does not
> support "rule of zero" since it can not make implicit move constructors.

It is fixed in VS 2013 Update 5 and in VS 2015.

Daniel

unread,
Nov 16, 2015, 10:03:29 AM11/16/15
to
On Sunday, October 25, 2015 at 2:13:30 AM UTC-4, asetof...@gmail.com wrote:
> One presumes class data members would be private, else what's the point of having a class?
>
> Given that, putting the data members first would be contrary to the generally accepted public, protected, private ordering with a class.
>
There's at least one practical c++ specific reason for putting the data members first, it makes it easier to line up the constructor initializer lists with the order in which data members are declared, which is a good thing to do in C++.

Public, protected, private ordering is just a convention, it's usefulness to the developer is vanishing with modern practices using templates, inline functions etc., try quickly groking any of the standard library or boost classes by glancing at their headers. At the same time, tooling has become quote good for introspecting classes within an editor environment, and for producing class documentation.
>
> It is the same problem of "const"...
>
The problem with const is that it doesn't mean pure, which it would have to mean were compilers able to take advantage of it, or programmers to reason about it.

Daniel

woodb...@gmail.com

unread,
Nov 16, 2015, 2:34:19 PM11/16/15
to
On Monday, November 16, 2015 at 9:03:29 AM UTC-6, Daniel wrote:
> On Sunday, October 25, 2015 at 2:13:30 AM UTC-4, asetof...@gmail.com wrote:
> > One presumes class data members would be private, else what's the point of having a class?
> >
> > Given that, putting the data members first would be contrary to the generally accepted public, protected, private ordering with a class.
> >
> There's at least one practical c++ specific reason for putting the data members first, it makes it easier to line up the constructor initializer lists with the order in which data members are declared, which is a good thing to do in C++.


I'm not sure why that is easier. To me the main reason to
put data members first has already been mentioned by Alf in
this thread:

"And generally, I find it better to declare things before
they're used."

That provides a helpful clue to those working on the code.
They know that by scrolling up they will find what they
are looking for.

Brian
Ebenezer Enterprises - So far G-d has helped us.
http://webEbenezer.net

Jorgen Grahn

unread,
Nov 16, 2015, 4:03:47 PM11/16/15
to
On Mon, 2015-11-16, Daniel wrote:
...

> Public, protected, private ordering is just a convention, it's
> usefulness to the developer is vanishing with modern practices using
> templates, inline functions etc., try quickly groking any of the
> standard library or boost classes by glancing at their headers.

But those aren't typical classes! It's a major mistake IMO to look
at a standard library implementation or Boost, and think your own
application-specific code has to look that way, too. It doesn't.

>> It is the same problem of "const"...
>>
> The problem with const is that it doesn't mean pure, which it would
> have to mean were compilers able to take advantage of it, or
> programmers to reason about it.

Who can't reason about const? It's not hard: "const Foo* foo" just
means "I can't use 'foo' to modify anything". True; the name is
misleading.

Bo Persson

unread,
Nov 16, 2015, 4:09:28 PM11/16/15
to
Right, unlike scrolling down which is really hard.


Bo Persson


Vir Campestris

unread,
Nov 16, 2015, 4:40:02 PM11/16/15
to
On 16/11/2015 19:33, woodb...@gmail.com wrote:
> I'm not sure why that is easier. To me the main reason to
> put data members first has already been mentioned by Alf in
> this thread:
>
> "And generally, I find it better to declare things before
> they're used."
>
> That provides a helpful clue to those working on the code.
> They know that by scrolling up they will find what they
> are looking for.

People using the code have no business looking in your internal data.
They should be looking at your public methods - so they come first.

Andy

Alf P. Steinbach

unread,
Nov 16, 2015, 5:28:19 PM11/16/15
to
On 11/16/2015 10:39 PM, Vir Campestris wrote:
> On 16/11/2015 19:33, woodb...@gmail.com wrote:
>> I'm not sure why that is easier. To me the main reason to
>> put data members first has already been mentioned by Alf in
>> this thread:
>>
>> "And generally, I find it better to declare things before
>> they're used."
>>
>> That provides a helpful clue to those working on the code.
>> They know that by scrolling up they will find what they
>> are looking for.
>
> People using the code have no business looking in your internal data.

That's a weird statement.

Someone looking at a class' documentation, where such exists, won't
usually be looking for internal representation. But then, they're not
looking at the code. They're looking at documentation, e.g.
documentation of the standard library, not its code.

Looking at the code and using the code is what you do when the
documentation isn't sufficient for what you want to do. Then one would
be very foolish to restrict oneself to the parts of the code providing
the absolutely least information beyond the documentation. There would
be almost no point in that.

And for the not uncommon case of undocumented code, looking at only
signatures of public methods will in most cases be insufficient to use a
class, not to mention to change it or derive from it in any way.

So, it generally doesn't make sense to avoid looking at representation
when one does look at the code. It doesn't make sense for a
well-documented class. It doesn't make sense for an undocumented class.


> They should be looking at your public methods - so they come first.

This idea is flawed in so many ways.


Cheers,

- Alf

Chris Vine

unread,
Nov 16, 2015, 7:27:43 PM11/16/15
to
On 16 Nov 2015 21:03:20 GMT
It doesn't mean that. It means "I can't use foo to modify the object
foo points to". (Or to be more exact, it means "I can't use foo to
modify any non-mutable data of the object foo points to", but I don't
want to confuse the basic point that const does not mean pure,
irrespective of whether there is any mutable object data around.)
"const" does not mean "no side effects".

Chris

woodb...@gmail.com

unread,
Nov 16, 2015, 8:52:15 PM11/16/15
to
There's the consistency with functions that others
have pointed out. It's the consistency that you
don't have to think about what the context is that's
nice.

I agree scrolling down isn't difficult so think the
functions can go at the end. Users can jump to the
end of the file easily enough.

Brian
Ebenezer Enterprises
http://webEbenezer.net

Scott Lurndal

unread,
Nov 17, 2015, 8:52:26 AM11/17/15
to
No, they should be looking at the generated doxygen documentation
for the class, not the header file :-).

Tobias Müller

unread,
Nov 17, 2015, 5:29:32 PM11/17/15
to
<woodb...@gmail.com> wrote:
> To me the main reason to
> put data members first has already been mentioned by Alf in
> this thread:
>
> "And generally, I find it better to declare things before
> they're used."

How do you "use" private data members in a public member function
*declaration*?

You can only use private data members in a member function *definition*.
And those are usually outside of the class definition body.

Tobi

Alf P. Steinbach

unread,
Nov 17, 2015, 5:49:28 PM11/17/15
to
I think it's a good idea to use a single convention instead of multiple
conventions, when it's practical to use a single one.

The convention of placing data members up top covers the case of having
definition before use where the data members are used in an in-class
function definition, whether that function is member or friend.

The convention of placing data members last doesn't cover that case.


Cheers & hth.,

- Alf

Tobias Müller

unread,
Nov 18, 2015, 1:41:53 AM11/18/15
to
Alf P. Steinbach <alf.p.stein...@gmail.com> wrote:
> I think it's a good idea to use a single convention instead of multiple
> conventions, when it's practical to use a single one.
>
> The convention of placing data members up top covers the case of having
> definition before use where the data members are used in an in-class
> function definition, whether that function is member or friend.
>
> The convention of placing data members last doesn't cover that case.

Consequently I never use in-class function definitions (except for some
rare cases where the body is empty and I'm lazy).

IMO even the most simple in-class function definitions hurt the readability
of a class definition.

And yes, I prefer reading header files to a generated doxygen. Especially
because the header is always up to date and just one "go to definition"
away.

Tobi

Juha Nieminen

unread,
Nov 18, 2015, 4:12:53 AM11/18/15
to
Tobias Müller <tro...@bluewin.ch> wrote:
> Consequently I never use in-class function definitions (except for some
> rare cases where the body is empty and I'm lazy).

In general, yes. However, with some complex template classes it can become
quite a nuisance to have to write half a dozen lines of code for something
that would be a one-liner in-class. Especially if you have lots of such
very short functions.

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

Öö Tiib

unread,
Nov 18, 2015, 4:40:50 AM11/18/15
to
On Wednesday, 18 November 2015 00:49:28 UTC+2, Alf P. Steinbach wrote:
> On 11/17/2015 11:26 PM, Tobias Müller wrote:
> > <woodb...@gmail.com> wrote:
> >> To me the main reason to
> >> put data members first has already been mentioned by Alf in
> >> this thread:
> >>
> >> "And generally, I find it better to declare things before
> >> they're used."
> >
> > How do you "use" private data members in a public member function
> > *declaration*?
> >
> > You can only use private data members in a member function *definition*.
> > And those are usually outside of the class definition body.
>
> I think it's a good idea to use a single convention instead of multiple
> conventions, when it's practical to use a single one.

That is indeed good idea but it seems to contradict with what you further
say. Might be my bad English.

> The convention of placing data members up top covers the case of having
> definition before use where the data members are used in an in-class
> function definition, whether that function is member or friend.

When the member functions and friend functions are defined sometimes
in-class but sometimes outside of class then that is not single
convention. Always in class however seriously clutters any real pieces
of code. Therefore function definitions always outside of class is
sole candidate of single convention here?

>
> The convention of placing data members last doesn't cover that case.

I do not see how. All the data members (when there are any) can be
always put as the very last (between last 'private:' and '};') in
class definition. Often these can not be put very first (before
nested type definitions).

Jorgen Grahn

unread,
Nov 18, 2015, 4:08:16 PM11/18/15
to
On Tue, 2015-11-17, Chris Vine wrote:
> On 16 Nov 2015 21:03:20 GMT
> Jorgen Grahn <grahn...@snipabacken.se> wrote:
>> On Mon, 2015-11-16, Daniel wrote:
>> ...
>>
>> > Public, protected, private ordering is just a convention, it's
>> > usefulness to the developer is vanishing with modern practices using
>> > templates, inline functions etc., try quickly groking any of the
>> > standard library or boost classes by glancing at their headers.
>>
>> But those aren't typical classes! It's a major mistake IMO to look
>> at a standard library implementation or Boost, and think your own
>> application-specific code has to look that way, too. It doesn't.
>>
>> >> It is the same problem of "const"...
>> >>
>> > The problem with const is that it doesn't mean pure, which it would
>> > have to mean were compilers able to take advantage of it, or
>> > programmers to reason about it.
>>
>> Who can't reason about const? It's not hard: "const Foo* foo" just
>> means "I can't use 'foo' to modify anything". True; the name is
>> misleading.
>
> It doesn't mean that. It means "I can't use foo to modify the object
> foo points to".

Sorry; I can't see the difference, unless you mean foo->bar->baz = 1,
which I agree would be fair to describe.

(I simplified by ignoring the case where you can const_cast foo,
because it's a very rare thing to do.)

> (Or to be more exact, it means "I can't use foo to
> modify any non-mutable data of the object foo points to", but I don't
> want to confuse the basic point that const does not mean pure,
> irrespective of whether there is any mutable object data around.)
> "const" does not mean "no side effects".

I don't know what "pure" means either, to be honest,

woodb...@gmail.com

unread,
Nov 18, 2015, 5:14:15 PM11/18/15
to
On Wednesday, November 18, 2015 at 12:41:53 AM UTC-6, Tobias Müller wrote:
> Alf P. Steinbach <alf.p.stein...@gmail.com> wrote:
> > I think it's a good idea to use a single convention instead of multiple
> > conventions, when it's practical to use a single one.
> >
> > The convention of placing data members up top covers the case of having
> > definition before use where the data members are used in an in-class
> > function definition, whether that function is member or friend.
> >
> > The convention of placing data members last doesn't cover that case.
>
> Consequently I never use in-class function definitions (except for some
> rare cases where the body is empty and I'm lazy).
>

I'm using them more over the past year or two. I've
found some minor advantages from going this route in
terms of executable/binary code size.

> IMO even the most simple in-class function definitions hurt the readability
> of a class definition.

Well, there are some advantages to using in class
functions like less lines of code. Imo that makes
the library or program, as a whole, easier to work
with. The more compact form for the software
also helps in terms of downloading/bandwidth.
If a few compilers look like they can do a better
job with the internal version, I may go that route.


Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net

Ian Collins

unread,
Nov 18, 2015, 5:27:07 PM11/18/15
to
Tobias Müller wrote:
> Alf P. Steinbach <alf.p.stein...@gmail.com> wrote:
>> I think it's a good idea to use a single convention instead of multiple
>> conventions, when it's practical to use a single one.
>>
>> The convention of placing data members up top covers the case of having
>> definition before use where the data members are used in an in-class
>> function definition, whether that function is member or friend.
>>
>> The convention of placing data members last doesn't cover that case.
>
> Consequently I never use in-class function definitions (except for some
> rare cases where the body is empty and I'm lazy).

So you never use templates?

> IMO even the most simple in-class function definitions hurt the readability
> of a class definition.

Short, especially one line, public inline functions have their place in
non-template code, I prefer not to have inline protected or private
inline function. The former may be heavily used in client code, so
making them available to the optimiser for inlining makes sense.

--
Ian Collins

Chris Vine

unread,
Nov 18, 2015, 6:42:59 PM11/18/15
to
On 18 Nov 2015 21:08:04 GMT
I do not know what 'foo->bar->baz = 1' refers to, as I have not seen
your Foo class definition (have I missed a post somewhere? - if so my
apologies). You said '"const Foo* foo" just means "I can't use 'foo'
to modify anything"'. I took from this (and from the posting to which
you were replying) that this was intended as a general statement about
the qualities of 'const', rather than about a particular Foo class
definition which I have not seen. Saying that foo cannot modify
anything is a statement that it is pure. Taken on that basis, what you
said was wrong. This is valid code, but it modifies 'a', 'b', and the
state of the output stream:

#include <iostream>
int a = 0;
struct Foo {
static int b;
int do_it1() const {++a; std::cout << a << '\n'; return a;}
int do_it2() const {++b; std::cout << b << '\n'; return b;}
};
int Foo::b = 0;
int main () {
const Foo* foo = new Foo;
foo->do_it1();
foo->do_it2();
delete foo;
}

> (I simplified by ignoring the case where you can const_cast foo,
> because it's a very rare thing to do.)
>
> > (Or to be more exact, it means "I can't use foo to
> > modify any non-mutable data of the object foo points to", but I
> > don't want to confuse the basic point that const does not mean pure,
> > irrespective of whether there is any mutable object data around.)
> > "const" does not mean "no side effects".
>
> I don't know what "pure" means either, to be honest,

It refers to the absence of side effects. It requires amongst other
things that a function only depend on its arguments (in particular, not
on mutable state), and that the same input value(s) should always
produce the same return value. No function returning void could be
pure, because otherwise it would not do anything. It enables many
compiler optimizations, including lazy evaluation, common subexpression
elimination and memoization, and (because it doesn't silently change
program state) makes programs easier to reason about and facilitates
safe concurrency - all pure functions are by definition thread safe).
D has a 'pure' keyword, for example. I think all constexpr functions
must in fact be pure (I must look that up some time), but there are
many pure functions which are not constexpr.

This is not to be confused with gcc's C function 'const' attribute,
which does require purity.

Chris

Öö Tiib

unread,
Nov 18, 2015, 9:15:07 PM11/18/15
to
On Thursday, 19 November 2015 00:27:07 UTC+2, Ian Collins wrote:
> Tobias Müller wrote:
> > Alf P. Steinbach <alf.p.stein...@gmail.com> wrote:
> >> I think it's a good idea to use a single convention instead of multiple
> >> conventions, when it's practical to use a single one.
> >>
> >> The convention of placing data members up top covers the case of having
> >> definition before use where the data members are used in an in-class
> >> function definition, whether that function is member or friend.
> >>
> >> The convention of placing data members last doesn't cover that case.
> >
> > Consequently I never use in-class function definitions (except for some
> > rare cases where the body is empty and I'm lazy).
>
> So you never use templates?

AFAIK every member or friend function of class or class template
(also templates of such functions and inline functions) can be
defined outside of class definition. So the only question is if it
is worth doing on case of templates and inline functions.

Scott Lurndal

unread,
Nov 19, 2015, 10:41:28 AM11/19/15
to
Ian Collins <ian-...@hotmail.com> writes:
>Tobias Müller wrote:
>> Alf P. Steinbach <alf.p.stein...@gmail.com> wrote:
>>> I think it's a good idea to use a single convention instead of multiple
>>> conventions, when it's practical to use a single one.
>>>
>>> The convention of placing data members up top covers the case of having
>>> definition before use where the data members are used in an in-class
>>> function definition, whether that function is member or friend.
>>>
>>> The convention of placing data members last doesn't cover that case.
>>
>> Consequently I never use in-class function definitions (except for some
>> rare cases where the body is empty and I'm lazy).
>
>So you never use templates?

While I write template functions, I've not yet encountered a case
where it was necessary to write a template class (as opposed to
_using_ one from a library).

I also place private data members at the top of the class, and
define inline functions after the class (which allows them to be
moved to a separate header file when circular dependencies exist).

Multiline functions within the class definition seriously impair
readability, IMO.

Tobias Müller

unread,
Nov 19, 2015, 3:16:28 PM11/19/15
to
<woodb...@gmail.com> wrote:
> On Wednesday, November 18, 2015 at 12:41:53 AM UTC-6, Tobias Müller wrote:
>> [...]
>> Consequently I never use in-class function definitions (except for some
>> rare cases where the body is empty and I'm lazy).
>>
>
> I'm using them more over the past year or two. I've
> found some minor advantages from going this route in
> terms of executable/binary code size.

I find this hard to believe. I still use inline functions in the header,
just not in the class body. Those should be equivalent.

>> IMO even the most simple in-class function definitions hurt the readability
>> of a class definition.
>
> Well, there are some advantages to using in class
> functions like less lines of code. Imo that makes
> the library or program, as a whole, easier to work
> with.


How so. I don't care about the size of the files as long as the *relevant*
part (the class definition) is concise.
By stuffing everything into the class body, you make it harder to work
with, not easier.

> The more compact form for the software
> also helps in terms of downloading/bandwidth.

Usually you use compression for that.

Tobi


Tobias Müller

unread,
Nov 19, 2015, 3:20:45 PM11/19/15
to
Ian Collins <ian-...@hotmail.com> wrote:
> Tobias Müller wrote:
>> Consequently I never use in-class function definitions (except for some
>> rare cases where the body is empty and I'm lazy).
>
> So you never use templates?
>
>> IMO even the most simple in-class function definitions hurt the readability
>> of a class definition.
>
> Short, especially one line, public inline functions have their place in
> non-template code, I prefer not to have inline protected or private
> inline function. The former may be heavily used in client code, so
> making them available to the optimiser for inlining makes sense.

I often use inline functions and templates, sure. Just not inside the class
body. It's equivalent but the same.

Tobi


Tobias Müller

unread,
Nov 19, 2015, 3:22:40 PM11/19/15
to
Tobias Müller <tro...@bluewin.ch> wrote:
> I often use inline functions and templates, sure. Just not inside the class
> body. It's equivalent but the same.

*not* the same.


Robert Wessel

unread,
Nov 19, 2015, 5:23:06 PM11/19/15
to
On Thu, 19 Nov 2015 15:41:13 GMT, sc...@slp53.sl.home (Scott Lurndal)
wrote:
They do, but that's a trade-off like everything else. OTOH, it should
*not* be a tradeoff when considering code size and optimization,
assuming a semi-competent compiler and link time code generation.

Richard

unread,
Nov 20, 2015, 2:09:50 PM11/20/15
to
[Please do not mail me a copy of your followup]

=?UTF-8?Q?Tobias=20M=C3=BCller?= <tro...@bluewin.ch> spake the secret code
<62653928.469655998.415...@news.eternal-september.org> thusly:

><woodb...@gmail.com> wrote:
>> On Wednesday, November 18, 2015 at 12:41:53 AM UTC-6, Tobias Müller wrote:
>>> [...]
>>> Consequently I never use in-class function definitions (except for some
>>> rare cases where the body is empty and I'm lazy).
>>>
>>
>> I'm using them more over the past year or two. I've
>> found some minor advantages from going this route in
>> terms of executable/binary code size.
>
>I find this hard to believe. I still use inline functions in the header,
>just not in the class body. Those should be equivalent.

To clarify what I think you're saying to make sure I understand it,
let me propose a concrete example and you tell me if I got it right.

You prefer:

class Foo
{
public:
inline int f();
};

int Foo::f()
{
// possibly multiple statements
return 42;
}

over

class Foo
{
publicL
int f()
{
// possibly multiple statements
return 42;
}
};

Is that correct?

At first, I interpreted your earlier statements as implying that
you didn't use any inline functions at all.

I usually either write free functions in a header and declare them as
inline, or I define the function in a class declaration to make it an
inline member function. So I had to look up the syntax details on the
first example to make sure I got it correctly. Inline specifier
<http://en.cppreference.com/w/cpp/language/inline> implies that I
decorate the declaration of a function as inline and don't need the
inline keyword on the definition. Coliru says this compiles without
warning on gcc.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Scott Lurndal

unread,
Nov 20, 2015, 2:33:47 PM11/20/15
to
legaliz...@mail.xmission.com (Richard) writes:
>[Please do not mail me a copy of your followup]
>
>=?UTF-8?Q?Tobias=20M=C3=BCller?= <tro...@bluewin.ch> spake the secret code
><62653928.469655998.415...@news.eternal-september.org> thusly:
>
>><woodb...@gmail.com> wrote:
>>> On Wednesday, November 18, 2015 at 12:41:53 AM UTC-6, Tobias Müller wrote:
>>>> [...]
>>>> Consequently I never use in-class function definitions (except for some
>>>> rare cases where the body is empty and I'm lazy).
>>>>
>>>
>>> I'm using them more over the past year or two. I've
>>> found some minor advantages from going this route in
>>> terms of executable/binary code size.
>>
>>I find this hard to believe. I still use inline functions in the header,
>>just not in the class body. Those should be equivalent.
>
>To clarify what I think you're saying to make sure I understand it,
>let me propose a concrete example and you tell me if I got it right.
>
>You prefer:
>
> class Foo
> {
> public:
> inline int f();
> };
>
> int Foo::f()
> {
> // possibly multiple statements
> return 42;
> }
>

I'd write it as

class Foo
{
public:
int f(void);
};

inline int
Foo::f(void)
{
body;
}

This allows one to move the inline to non-inline without
the need to edit the declaration within the class body
as well as maintaining readability of the class body.

Richard

unread,
Nov 20, 2015, 11:29:26 PM11/20/15
to
[Please do not mail me a copy of your followup]

sl...@pacbell.net spake the secret code
<fAK3y.81096$TJ2....@fx21.iad> thusly:

>I'd write it as

OK, so a minor tweak to what I was thinking.

> int f(void);

Aside: why the C-ism?

(void) is for C prototypes because no argument list in C means "declare
this function with an unknown number of arguments of unknown type"
and "(void)" explicitly means "takes no arguments". In C++ the (void)
is totally unnecessary.

Jorgen Grahn

unread,
Nov 21, 2015, 7:41:31 AM11/21/15
to
On Wed, 2015-11-18, Chris Vine wrote:
> On 18 Nov 2015 21:08:04 GMT
> Jorgen Grahn <grahn...@snipabacken.se> wrote:
>> On Tue, 2015-11-17, Chris Vine wrote:
>> > On 16 Nov 2015 21:03:20 GMT
>> > Jorgen Grahn <grahn...@snipabacken.se> wrote:
>> >> On Mon, 2015-11-16, Daniel wrote:
...
>> >> >> It is the same problem of "const"...
>> >> >>
>> >> > The problem with const is that it doesn't mean pure, which it
>> >> > would have to mean were compilers able to take advantage of it,
>> >> > or programmers to reason about it.
>> >>
>> >> Who can't reason about const? It's not hard: "const Foo* foo" just
>> >> means "I can't use 'foo' to modify anything". True; the name is
>> >> misleading.
>> >
>> > It doesn't mean that. It means "I can't use foo to modify the
>> > object foo points to".
>>
>> Sorry; I can't see the difference, unless [...]

[Snip more, later text by us both.]

Ok, now I see the difference. Yes, I meant "the object foo points
to". Of course const doesn't turn C++ into a purely functional
programming language.

I was sloppy with the "modify anything". I was focused more on the
aliasing aspect -- that the object const Foo* foo points to may be
involved a second time via a plain Foo* somewhere.

All that never gave me any problems, except for a while I believed
const was more important for optimization than it actually is. That
misconception didn't hurt anyone, and it made me generate fewer bugs.

Scott Lurndal

unread,
Nov 23, 2015, 9:54:00 AM11/23/15
to
legaliz...@mail.xmission.com (Richard) writes:
>[Please do not mail me a copy of your followup]
>
>sl...@pacbell.net spake the secret code
><fAK3y.81096$TJ2....@fx21.iad> thusly:

>> int f(void);
>
>Aside: why the C-ism?
>
>(void) is for C prototypes because no argument list in C means "declare
>this function with an unknown number of arguments of unknown type"
>and "(void)" explicitly means "takes no arguments". In C++ the (void)
>is totally unnecessary.

Yet, I've been using int f(void) since 1989 with C++ and
see no reason to stop. I prefer it over int f(). YMMV.
0 new messages