Topic: Proposal: Compilation-unit scoped private member functions


Author: christopher.dearlove@googlemail.com
Date: Fri, 22 Feb 2013 10:48:40 CST
Raw View
On Tuesday, December 18, 2012 10:06:37 PM UTC, Ian Collins wrote:
>  christopher.dearlove@googlemail.com wrote:
>>  On Friday, December 14, 2012 5:19:33 PM UTC, Ian Collins wrote:
>>>  Your proposal would not improve testability, the locally private
>>>  functions would, by virtue of their linkage, be impossible to test.
>>  How do you test a normal private function?
>  I wouldn't.

So your objection to the proposal is that it doesn't improve tetability,
something which the OP didn't claim, when the current alternative is
from your comment, untestable.

Not exactly a relevant objection.

>  In most cases if a function is too large to inline, the overhead
>  of calling is is minimal compared to the time spent in the function.
>  The inline keyword is never more than a hint, so any warnings are
>  probably spurious and could be suppressed.

And another objection that isn't to anything actually said by either
the OP or myself.

Daniel, as usual, had it right. There would be some gains. There
would be some costs (in standardisation and implementation). But
neither is about testability or inlining.


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: ootiib@hot.ee
Date: Fri, 22 Feb 2013 16:39:34 CST
Raw View
On Friday, 22 February 2013 18:48:40 UTC+2, christophe...@googlemail.com  wrote:
> On Tuesday, December 18, 2012 10:06:37 PM UTC, Ian Collins wrote:
> >  christopher.dearlove@googlemail.com wrote:
> >>  On Friday, December 14, 2012 5:19:33 PM UTC, Ian Collins wrote:
> >>>  Your proposal would not improve testability, the locally private
> >>>  functions would, by virtue of their linkage, be impossible to test.
> >>  How do you test a normal private function?
> >  I wouldn't.
>
> So your objection to the proposal is that it doesn't improve tetability,
> something which the OP didn't claim, when the current alternative is
> from your comment, untestable.

I trust that main problem with public functions that have huge set of
responsibilities is that those are expensive to test.

Such functions contain some core functionality and when software evolves
are most often altered by maintenance. Good set of automated tests is
only way to keep them under control.

There are no difference how and if at all to split those into private
parts that do not relieve that main problem.

Splitting the responsibilities between several easier-to-test smaller
classes is the usual path taken to reduce the complexity and said
costs. Current proposal failed to mention the most usual practice in
"Background".

The proposed solution likely distracts developers from solving the real
issue; the class that has been overburdened with responsibilities and
its complex non-testable member functions are real issue.

> Not exactly a relevant objection.

It felt relevant in the context of large functions.

> >  In most cases if a function is too large to inline, the overhead
> >  of calling is is minimal compared to the time spent in the function.
> >  The inline keyword is never more than a hint, so any warnings are
> >  probably spurious and could be suppressed.
>
> And another objection that isn't to anything actually said by either
> the OP or myself.

Didn't you discuss inlining and warnings because of inlining? Ian did
not seemingly object ... he just mentioned that any of that does
not matter much.


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Ian Collins <ian-news@this.is.invalid>
Date: Sat, 23 Feb 2013 18:21:56 -0800 (PST)
Raw View
christopher.dearlove@googlemail.com wrote:
>
>
> On Tuesday, December 18, 2012 10:06:37 PM UTC, Ian Collins wrote:
>>
>>   christopher.dearlove@googlemail.com wrote:
>>>
>>>   On Friday, December 14, 2012 5:19:33 PM UTC, Ian Collins wrote:
>>>>
>>>>   Your proposal would not improve testability, the locally private
>>>>   functions would, by virtue of their linkage, be impossible to test.
>>>
>>>   How do you test a normal private function?
>>
>>   I wouldn't.
>
>
> So your objection to the proposal is that it doesn't improve tetability,
> something which the OP didn't claim, when the current alternative is
> from your comment, untestable.


No, I was commenting on the the line directly above my reply, the line
you conveniently snipped:

[regarding approaches to implementing complex/lengthy member
functions] "Write huge, unwieldy member functions that become
incredibly difficult to validate / test / document"

One alternative, not the one I suggested which you also conveniently snipped.

> Not exactly a relevant objection.


Well the proposal aimed at avoiding something that results in hard to
test code...

>>   In most cases if a function is too large to inline, the overhead
>>   of calling is is minimal compared to the time spent in the function.
>>   The inline keyword is never more than a hint, so any warnings are
>>   probably spurious and could be suppressed.
>
>
> And another objection that isn't to anything actually said by either
> the OP or myself.


Er, over zealous snipping again, this time your own comments.

--
Ian Collins


[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: Jason McKesson <jmckesson@googlemail.com>
Date: Sat, 23 Feb 2013 23:22:30 -0800 (PST)
Raw View
On Friday, February 22, 2013 2:39:34 PM UTC-8, oot...@hot.ee wrote:
> On Friday, 22 February 2013 18:48:40 UTC+2, christophe...@googlemail.com  wrote:
> > On Tuesday, December 18, 2012 10:06:37 PM UTC, Ian Collins wrote:
> > >  christophe...@googlemail.com  wrote:
> > >>  On Friday, December 14, 2012 5:19:33 PM UTC, Ian Collins wrote:
> > >>>  Your proposal would not improve testability, the locally private
> > >>>  functions would, by virtue of their linkage, be impossible to test.
> > >>  How do you test a normal private function?
> > >  I wouldn't.
> >
> > So your objection to the proposal is that it doesn't improve tetability,
> > something which the OP didn't claim, when the current alternative is
> > from your comment, untestable.
>
> I trust that main problem with public functions that have huge set of
> responsibilities is that those are expensive to test.
>
> Such functions contain some core functionality and when software evolves
> are most often altered by maintenance. Good set of automated tests is
> only way to keep them under control.
>
> There are no difference how and if at all to split those into private
> parts that do not relieve that main problem.
>
> Splitting the responsibilities between several easier-to-test smaller
> classes is the usual path taken to reduce the complexity and said
> costs. Current proposal failed to mention the most usual practice in
> "Background".

"Most usual practice" is a loaded term. There are no "most usual
practices" for just about anything in C++. Some people love
test-driven design; some people avoid it like the plague. Some people
love templates and use them whenever possible; others don't. And so
on.

Many people do use test-driven coding techniques. But calling them
"usual practice" is simply a fact not in evidence. C++ has to serve
everyone, even people who don't do test-driven coding.

Or to put it another way, a possible feature of C++ should not be
discounted for the sole reason that it wouldn't be applicable to one
particular coding style. The fact that you could solve this problem in
some other way does not stop it from being a problem for someone who
doesn't feel that they should have to go through that much refactoring
to get the problem solved. And the fact that test-driven coding tends
to avoid these kinds of functions to begin with does not change the
fact that these kinds of functions *still get written*.

Or, to put another way, people who use bad design still need crutches ;)

Personally, I'd say that the far bigger problem is that the proposal
is generally driven by issues of compile time. In effect, he wants a
form of Pimpl, but just for private member functions. The only reason
to want this is to be able to add members without touching the header
and thus provoking a potentially vast recompile. Otherwise he could
just put them in the header, since private members are, by definition,
*not* part of the "public API".

This is an issue that is rooted in minimizing recompilation times. And
the modules proposal will be dealing with recompiling in a *far* more
effective way. In short, this, like Pimpl in general, will be a moot
point once we get modules. You'll just make the functions private, and
nobody will care, since any recompilation will be lightning fast.

And if the issue really is to remove them from the class just so that
people can't see them by looking at the header... that's not reason
enough to add a feature to the language. By that logic, we should be
able to remove private variables from the header too, possibly
replaced with some std::aligned_storage or whatnot.


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: christopher.dearlove@googlemail.com
Date: Mon, 25 Feb 2013 10:59:51 CST
Raw View
On Sunday, February 24, 2013 2:21:56 AM UTC, Ian Collins wrote:
>  I was commenting on the the line directly above my reply, the line you conveniently snipped

Apologies, but I partly blame Google. I checked for references to testing and there weren't any - except they were in a piece Google Groups display had hidden from what you'd quoted and I hadn't noticed.

(And no, I don't have an alternative to Google here.)

So of the OP's comments, testing is a red herring, it's hard either way.

(I did actually ask about modules, IIRC.)


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Balog Pal<pasa@lib.hu>
Date: Mon, 25 Feb 2013 11:01:07 CST
Raw View
On 12/14/2012 6:19 PM, Ian Collins wrote:
>>   Currently many C++ programmers revert to one of these approaches to
>>  implementing complex/lengthy member functions:
>>
>>   1. Write huge, unwieldy member functions that become incredibly
>>  difficult to validate / test / document,
>
>  Your proposal would not improve testability, the locally private
>  functions would, by virtue of their linkage, be impossible to test.

IMO "impossible" goes too far -- those who want to test the private
functions directly can put the test in that TU or #include the
implementation file in the test case. Those who test privates through
public interface get the same as before.

But if term "testability" is used in a wider sense, not limited to
automatic code execution, the proposal provides tools to provide more
locality and flexibility. What is positive. *If* the premise of "minor
language change" holds IMO it worth investigating.

>  It is better to split the functionality into smaller objects than to
>  design a class with member function that end up doing too much (with
>  results in the bloated code you describe earlier).

There are cases where you mostly operate with functions and creating
more objects does not help.

And my estimate on private function attributes is that majority would
fit listed restriction, so could be put out of class.

And having privates in the class headers is quite PITA now for a ton of
reasons while PIMPL is also painful at best. So I consider anything in
between is value.

Just to mention one painful case, that would be solved by the proposal:
if my private functions use types from some different header, but I'm
lucky enough to not need any of those types in the class state (or can
work that around). It's not exactly rare, and I could go back to include
those foreign headers with implementation only.

>  I can see some merit in the suggestion, but it looks to much like a
>  crutch for bad design rather than a cure...

To me it looks like a patch on imperfections the language has. And on
one that is addressed/worked around on daily basis in many suboptimal
ways.  Yes, it is not a root-cause cure (what possibly a perfect
"modules" solution would be) but on the correct vector.

If we're positive that a better proposal will cover the cases in the
next release, sure, let's concentrate efforts on that one, otherwise I
think "light" improvements are better processed.




--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Balog Pal<pasa@lib.hu>
Date: Mon, 25 Feb 2013 11:01:25 CST
Raw View
On 2/24/2013 8:22 AM, Jason McKesson wrote:
>  This is an issue that is rooted in minimizing recompilation times. And
>  the modules proposal will be dealing with recompiling in a *far* more
>  effective way.

Is that proposal moving? I see the last paper in N3347 from more than a
year ago. What is the current status?


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Andy Lutomirski <luto@amacapital.net>
Date: Thu, 28 Feb 2013 22:16:20 -0800 (PST)
Raw View
On 02/25/2013 09:01 AM, Balog Pal wrote:
>
> On 12/14/2012 6:19 PM, Ian Collins wrote:
>>>   Currently many C++ programmers revert to one of these approaches to
>>>  implementing complex/lengthy member functions:
>>>
>>>   1. Write huge, unwieldy member functions that become incredibly
>>>  difficult to validate / test / document,
>>
>>  Your proposal would not improve testability, the locally private
>>  functions would, by virtue of their linkage, be impossible to test.
>
> IMO "impossible" goes too far -- those who want to test the private
> functions directly can put the test in that TU or #include the
> implementation file in the test case. Those who test privates through
> public interface get the same as before.
>
> But if term "testability" is used in a wider sense, not limited to
> automatic code execution, the proposal provides tools to provide more
> locality and flexibility. What is positive. *If* the premise of "minor
> language change" holds IMO it worth investigating.
>
>>  It is better to split the functionality into smaller objects than to
>>  design a class with member function that end up doing too much (with
>>  results in the bloated code you describe earlier).
>
> There are cases where you mostly operate with functions and creating
> more objects does not help.
>
> And my estimate on private function attributes is that majority would
> fit listed restriction, so could be put out of class.
>
> And having privates in the class headers is quite PITA now for a ton of
> reasons while PIMPL is also painful at best. So I consider anything in
> between is value.
>
> Just to mention one painful case, that would be solved by the proposal:
> if my private functions use types from some different header, but I'm
> lucky enough to not need any of those types in the class state (or can
> work that around). It's not exactly rare, and I could go back to include
> those foreign headers with implementation only.
>
>>  I can see some merit in the suggestion, but it looks to much like a
>>  crutch for bad design rather than a cure...
>
> To me it looks like a patch on imperfections the language has. And on
> one that is addressed/worked around on daily basis in many suboptimal
> ways.  Yes, it is not a root-cause cure (what possibly a perfect
> "modules" solution would be) but on the correct vector.
>
> If we're positive that a better proposal will cover the cases in the
> next release, sure, let's concentrate efforts on that one, otherwise I
> think "light" improvements are better processed.

Another reason: libraries.  If cleaning up the implementation of a class
in a library requires adding a new non-virtual private member function,
you risk running into spurious ODR issues.  This proposal eliminates
that problem.

(If you can give these special function static or extern linkage upon
request, then you can test them easily and you can access them from
multiple files in a library while still retaining the benefits.)

--Andy


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: kfsone@googlemail.com
Date: Wed, 21 Nov 2012 11:29:09 -0800 (PST)
Raw View
I'd like to propose a relatively minor language change that would help with code-hygiene in two main senses:
  . Encourage compartmentalization (break large functions up into named fragments),
  . Encourage privacy and encapsulation (conceal the compartmentalization from the public API),

The intent is something closer to c-style "static" for member functions, i.e giving them compilation-unit scope.

In addition to being treated as both a private member function and compilation-unit private (akin to a c-style static), the following would also be applied:

 . Cannot be virtual,
 . Cannot be abstract,
 . Cannot be exposed via "friend" status,
 . Cannot be an operator,
 . Cannot share a /name/ with a publicly-defined member regardless of argument fingerprint,
 . Not visible to derived classes even if they are in the same compilation unit.

---Foo.h---
     class Foo
     {
     #include <string>
     public:
         Foo() : m_string(""), m_int(0) {}

         void bigFunction();

         void otherFunction();

     private:
         void privateFunction();

     private:
         std::string m_string;
         unsigned int m_int;
     };
---Foo.h---

---Foo1.cpp---
     #include "Foo.h"

     // Member function with compilation-unit scope only.
     private void Foo::helper1()
     {
         m_string = "Hello";
         m_int = 1;
     }

     // Prototype flavor.
     private void Foo::helper42() const;

     // Declared in the public Foo definition.
     void Foo::bigFunction()
     {
         helper1();    // aka this->helper1();
         /* ... */
         helper42();    // aka this->helper42();
     }

     void Foo::helper42() const    // I would prefer to require you to type 'private void Foo::helper42()' but this is consistent with use of static/inline etc.
     {
         m_string = "World";
         m_int = 42;
     }

     class Bar : public Foo
     {
         void barFunction()
         {
             helper1();    // INVALID: helper1 is NOT inherited.
         }
     };
---Foo1.cpp---

---Foo2.cpp---
     #include "Foo.h"

     private void Foo::helper1()
     {
         // OK: the helper1() in Foo1.cpp is not visible here;
         // this definition has zero bearing on Foo1.cpp.
     }

     // INVALID: There is a "privateFunction" definition in the class.
     private void Foo::privateFunction(int, float, char, std::string&);

     void Foo::privateFunction()    // Publicly-defined version from Foo.h
     {
         helper1();                // OK: Calls the Foo2.cpp Foo::helper1()
         helper42();                // INVALID: Foo::helper42() is scoped to Foo1.cpp.
     }

     private int& Foo::GetI() { return m_i; }

     void GetIFromFoo(Foo* foo) { return foo->GetI(); }    // INVALID. GetI is private to Foo.
---Foo2.cpp---


How should I go about submitting a standard change request for something like this?


Background:

Currently many C++ programmers revert to one of these approaches to implementing complex/lengthy member functions:

1. Write huge, unwieldy member functions that become incredibly difficult to validate / test / document,
2. Split the functions into potentially dozens of member functions, all of which are then exposed as "private:" in the public class definition,
3. Split the functions into dozens of static functions which are not member scoped and thus need to be friended or other encapsulation breaking mechanisms,
4. Use the Pimpl solution which leads to lots of noisy, useless boilerplate code.

C#'s "partial" class concept allows you to solve this by writing non-public member functions only in the compilation unit where they are needed. The downside being that they aren't really "private" to the compilation unit, and unless you declare the class "sealed" anyone can come along and add to it - a complete burst of the encapsulation bubble.

This approach retains encapsulation integrity in that only existing members can access it; it merely allows you to break a member's implementation into named sub-routines without exposing those implementation details through the public definition of the class.

As one colleague put it: "Essentially, it is C-style static functions, with access to class members."

-Oliver


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: Francis Glassborow<francis.glassborow@btinternet.com>
Date: Fri, 14 Dec 2012 09:10:54 -0800 (PST)
Raw View
On 21/11/2012 19:29, kfsone@googlemail.com wrote:
>  I'd like to propose a relatively minor language change that would help with code-hygiene in two main senses:
>     . Encourage compartmentalization (break large functions up into named fragments),
>     . Encourage privacy and encapsulation (conceal the compartmentalization from the public API),
>

Obviously I have failed to grasp what you are trying to achieve because
when faced with complicated member function definitions I have always
used something like the following:

in Example.h

class Example {
    void foo();
    // rest of public interface
private
    // private interface including
    int a;
    float f;
    double d;
    type t;
};


in Example,cpp

#include "Example.h"
    namespace {
        inline void helper1(int&  i, type const&  t){
           // whatever
        }
        inline void helper2(float&  f){
            ?? whatever
        }
// etc
    }
    void Example::foo(){
         helper1(i, t);
         helper2(f);
// etc
    }


On most implementations there will not even be a cost for those pass be
reference, the implementation will simply inline everything and use the
original member data directly.

Now what does your proposal offer that the above does not provide (that
is also worth the expenditure of 100+ hours of WG21 human resources)

Francis



--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?=<daniel.kruegler@googlemail.com>
Date: Fri, 14 Dec 2012 09:11:11 -0800 (PST)
Raw View
Am 21.11.2012 20:29, schrieb kfsone@googlemail.com:
>  I'd like to propose a relatively minor language change that would help with code-hygiene in two main senses:

[..]

>  How should I go about submitting a standard change request for something like this?

Please take a look at

http://isocpp.org/std/submit-a-proposal

>  Background:
>
>  Currently many C++ programmers revert to one of these approaches to implementing complex/lengthy member functions:
>
>  1. Write huge, unwieldy member functions that become incredibly difficult to validate / test / document,
>  2. Split the functions into potentially dozens of member functions, all of which are then exposed as "private:" in the public class definition,
>  3. Split the functions into dozens of static functions which are not member scoped and thus need to be friended or other encapsulation breaking mechanisms,
>  4. Use the Pimpl solution which leads to lots of noisy, useless boilerplate code.
>
>  C#'s "partial" class concept allows you to solve this by writing non-public member functions only in the compilation unit where they are needed. The downside being that they aren't really "private" to the compilation unit, and unless you declare the class "sealed" anyone can come along and add to it - a complete burst of the encapsulation bubble.
>
>  This approach retains encapsulation integrity in that only existing members can access it; it merely allows you to break a member's implementation into named sub-routines without exposing those implementation details through the public definition of the class.
>
>  As one colleague put it: "Essentially, it is C-style static functions, with access to class members."

Basically I can understand the advantages, the question will be whether
the benefit outweights possible specification problems.

But this remark is just a personal comment and it should not discourage you.

HTH&  Greetings from Bremen,

Daniel Kr   gler



--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: Ian Collins<ian-news@this.is.invalid>
Date: Fri, 14 Dec 2012 09:19:33 -0800 (PST)
Raw View
kfsone@googlemail.com wrote:
>  I'd like to propose a relatively minor language change that would help with code-hygiene in two main senses:
>     . Encourage compartmentalization (break large functions up into named fragments),
>     . Encourage privacy and encapsulation (conceal the compartmentalization from the public API),
>
>  The intent is something closer to c-style "static" for member functions, i.e giving them compilation-unit scope.
>
>  In addition to being treated as both a private member function and compilation-unit private (akin to a c-style static), the following would also be applied:
>
>   . Cannot be virtual,
>   . Cannot be abstract,
>   . Cannot be exposed via "friend" status,
>   . Cannot be an operator,
>   . Cannot share a /name/ with a publicly-defined member regardless of argument fingerprint,
>   . Not visible to derived classes even if they are in the same compilation unit.
>
>  ---Foo.h---
>        class Foo
>        {
>        #include<string>
>        public:
>            Foo() : m_string(""), m_int(0) {}
>
>            void bigFunction();
>
>            void otherFunction();
>
>        private:
>            void privateFunction();
>
>        private:
>            std::string m_string;
>            unsigned int m_int;
>        };
>  ---Foo.h---
>
>  ---Foo1.cpp---
>        #include "Foo.h"
>
>        // Member function with compilation-unit scope only.
>        private void Foo::helper1()
>        {
>            m_string = "Hello";
>            m_int = 1;
>        }
>
>        // Prototype flavor.
>        private void Foo::helper42() const;
>
>        // Declared in the public Foo definition.
>        void Foo::bigFunction()
>        {
>            helper1();    // aka this->helper1();
>            /* ... */
>            helper42();    // aka this->helper42();
>        }
>
>        void Foo::helper42() const    // I would prefer to require you to type 'private void Foo::helper42()' but this is consistent with use of static/inline etc.
>        {
>            m_string = "World";
>            m_int = 42;
>        }
>
>        class Bar : public Foo
>        {
>            void barFunction()
>            {
>                helper1();    // INVALID: helper1 is NOT inherited.
>            }
>        };
>  ---Foo1.cpp---
>
>  ---Foo2.cpp---
>        #include "Foo.h"
>
>        private void Foo::helper1()
>        {
>            // OK: the helper1() in Foo1.cpp is not visible here;
>            // this definition has zero bearing on Foo1.cpp.
>        }
>
>        // INVALID: There is a "privateFunction" definition in the class.
>        private void Foo::privateFunction(int, float, char, std::string&);
>
>        void Foo::privateFunction()    // Publicly-defined version from Foo.h
>        {
>            helper1();                // OK: Calls the Foo2.cpp Foo::helper1()
>            helper42();                // INVALID: Foo::helper42() is scoped to Foo1.cpp.
>        }
>
>        private int&  Foo::GetI() { return m_i; }
>
>        void GetIFromFoo(Foo* foo) { return foo->GetI(); }    // INVALID. GetI is private to Foo.
>  ---Foo2.cpp---
>
>
>  How should I go about submitting a standard change request for something like this?
>
>
>  Background:
>
>  Currently many C++ programmers revert to one of these approaches to implementing complex/lengthy member functions:
>
>  1. Write huge, unwieldy member functions that become incredibly difficult to validate / test / document,

Your proposal would not improve testability, the locally private
functions would, by virtue of their linkage, be impossible to test.

It is better to split the functionality into smaller objects than to
design a class with member function that end up doing too much (with
results in the bloated code you describe earlier).

I can see some merit in the suggestion, but it looks to much like a
crutch for bad design rather than a cure...

--
Ian Collins


[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: christopher.dearlove@googlemail.com
Date: Mon, 17 Dec 2012 08:52:12 -0800 (PST)
Raw View
On Friday, December 14, 2012 5:19:33 PM UTC, Ian Collins wrote:
>  Your proposal would not improve testability, the locally private
>  functions would, by virtue of their linkage, be impossible to test.

How do you test a normal private function?

I can see your point, and Francis' point, about gain vs. cost. The
largest gain I can see (just having seen the proposal outline) is
that if I refactor a member function (public or private) by putting
some of it into a new function, this allows doing this without
changing the header file and hence forcing a recompilation. As Francis
says, you can do this by passing member data by reference, but even if
you inline the functions (and they may be large enough that some compilers
will warn too large to inline, conflicting with the usual practice of
getting rid of all warnings as well as errors) that's losing the
programmer's convenience and clarity of not having to redeclare data
members.

However will modules offer some or more of this gain?


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: Ian Collins<ian-news@this.is.invalid>
Date: Tue, 18 Dec 2012 16:06:37 CST
Raw View
christopher.dearlove@googlemail.com wrote:
>  On Friday, December 14, 2012 5:19:33 PM UTC, Ian Collins wrote:
>>    Your proposal would not improve testability, the locally private
>>    functions would, by virtue of their linkage, be impossible to test.
>
>  How do you test a normal private function?

I wouldn't.  If the function isn't tested via a public interface, I
would create a new class to do the work and test that.

Once upon a time I was in favour of making the test class a friend, but
over time and after much debate within my team, we realised we produced
better code, with more reusable components, by not doing this.

>  I can see your point, and Francis' point, about gain vs. cost. The
>  largest gain I can see (just having seen the proposal outline) is
>  that if I refactor a member function (public or private) by putting
>  some of it into a new function, this allows doing this without
>  changing the header file and hence forcing a recompilation. As Francis
>  says, you can do this by passing member data by reference, but even if
>  you inline the functions (and they may be large enough that some compilers
>  will warn too large to inline, conflicting with the usual practice of
>  getting rid of all warnings as well as errors) that's losing the
>  programmer's convenience and clarity of not having to redeclare data
>  members.

In most cases if a function is too large to inline, the overhead of
calling is is minimal compared to the time spent in the function.  The
inline keyword is never more than a hint, so any warnings are probably
spurious and could be suppressed.

--
Ian Collins


[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]