Smart C++ class splitter?

Discussion in 'C++' started by Daniel Pfeiffer, Apr 4, 2010.

  1. Hi,

    for a while now I've been looking for a smart C++ class splitter that allows
    programming in one file as in Java. This would eliminate the need of
    repeating all declarations differently in the definition.

    I guess the reason I can't find anything is that traditional make would be
    recompiling tons of stuff all the time. But modern alternatives like makepp
    would notice that the updated x.hh is the same as before, so there's no
    drawback any more. Essentially I want something like:

    /********** x.cpp: **********/
    #include <string>
    using namespace std;
    class X
    {
    static int i = 0; // illegal, some IDEs might barf :-(
    public:
    inline void f(string s) { ... }
    // bla bla
    void g(string s) { ... } // not to be inline!
    };


    This would get split into the following two files for the compiler to see:

    /********** x.hh: **********/
    #ifndef _X_CPP_
    #define _X_CPP_
    #line 1 "x.cpp"
    #include <string>

    class X
    {
    static int i;
    public:
    inline void f(std::string s) { ... }

    void g(std::string);
    };
    #endif

    /********** x.cc: **********/
    #include "x.hh"
    #line 2 "x.cpp"
    using namespace std;
    #line 5
    int X::i = 0;
    #line 9
    void X::g(string s) { ... }


    The other reason is probably that with namespaces, nested classes, enums,
    typedefs and whatnot, this rewriting is a rather tough one. But that's
    because the whole topic is a mess in C++. I guess this causes numerous
    compilations attempts, especially for beginners, until you get it right. All
    the more reason to do this!

    Any solutions or thoughts?

    best regards - Daniel
     
    Daniel Pfeiffer, Apr 4, 2010
    #1
    1. Advertising

  2. Daniel Pfeiffer

    Krice Guest

    On 4 huhti, 20:43, Daniel Pfeiffer <> wrote:
    > thoughts?


    In C++ the problem you described doesn't even exist. You made it.
     
    Krice, Apr 4, 2010
    #2
    1. Advertising

  3. Daniel Pfeiffer

    Robert Fendt Guest

    And thus spake Daniel Pfeiffer <>
    Sun, 04 Apr 2010 19:43:08 +0200:

    > drawback any more. Essentially I want something like:
    > [Inline definition]
    > This would get split into the following two files for the compiler to see:
    >
    > /********** x.hh: **********/
    > [Class interface]
    > /********** x.cc: **********/
    > [Class implementation]


    So you essentially want to write a class in inline form and
    then auto-refactor it into an interface and implementation. To
    be frank, I do not really see the benefit here, since splitting
    off the interface is (at least) as much a matter of readability
    and maintenance as compilation time.

    I see a few problems with your idea:

    (1) Control. Patterns like pointer-to-implementation build on
    the fact that the programmer can very carefully choose what bits
    of information he/she puts into which compilation unit. So
    auto-splitting would probably only work for 'simple' cases
    anyway.

    (2) Maintenance. You would have to maintain the inline version
    of the class in a file and put it through yet another
    preprocessor (like C++ didn't already have enough of those:
    macros, templates, and Qt adds its own preproc as well). This
    just adds complexity without apparent benefit (to me at least).

    (3) Readability. Separate interface headers serve among
    other things the important purpose of showing, well, the
    interface of the class at a glance. So, well-made headers are
    usually formatted consistently and are also the place where e.g.
    doxygen comments are placed. You would have to have those in
    your inline version as well, which will then become in the worst
    case a rather large junk piece of unreadable spaghetti code (->
    point (2)).

    That said, of course sometimes a class is developed in a hurry
    and cleaned up only afterwards (i.e., refactored into a separate
    interface definition, documented etc.). But in this situation
    (and also the other way round, i.e. implementing a previously
    designed class structure), the biggest help IMHO comes from a
    good IDE.

    So in my opinion one would benefit much more from work on
    improving available refactoring tools (like e.g. in Eclipse
    CDT). And V'Studio users could maybe nag MS to actually
    implement refactoring facilities for native C++ (i.e.,
    non-.NET). Just my $0.02.

    Regards,
    Robert
     
    Robert Fendt, Apr 4, 2010
    #3
  4. Daniel Pfeiffer

    Öö Tiib Guest

    On 4 apr, 20:43, Daniel Pfeiffer <> wrote:
    >
    > Any solutions or thoughts?


    I think you do not see the reason why it is so. For example: Someone
    developing in javascript has 3 files to deal with (.html, .css
    and .js). The contents of these 3 files can be merged into one
    (.html). However they usually avoid doing it. Why?

    How does your tool know what related headers you want to #include
    in .hh and what classes you want only to forward declare in .hh and
    #include in .cc?

    Or if to put it more generic: How does your tool know what you want to
    expose in interface and what you want to encapsulate and hide?
     
    Öö Tiib, Apr 4, 2010
    #4
  5. Hi,

    I'm replying here to all who took time to answer, since this one is most
    comprehensive.

    la 04/04/2010 08:16 PM Robert Fendt skribis:
    > And thus spake Daniel Pfeiffer <>
    > Sun, 04 Apr 2010 19:43:08 +0200:
    >
    >> drawback any more. Essentially I want something like:
    >> [Inline definition]
    >> This would get split into the following two files for the compiler to see:
    >>
    >> /********** x.hh: **********/
    >> [Class interface]
    >> /********** x.cc: **********/
    >> [Class implementation]

    >
    > So you essentially want to write a class in inline form and
    > then auto-refactor it into an interface and implementation. To
    > be frank, I do not really see the benefit here, since splitting
    > off the interface is (at least) as much a matter of readability
    > and maintenance as compilation time.
    >
    > I see a few problems with your idea:
    >
    > (1) Control. Patterns like pointer-to-implementation build on
    > the fact that the programmer can very carefully choose what bits
    > of information he/she puts into which compilation unit. So
    > auto-splitting would probably only work for 'simple' cases
    > anyway.


    I'm not trying to force this on anybody. If this were designed right, it
    would probably handle the vast majority of use cases correctly. But whenever
    you feel more comfortable or need something not possible with my approach, the
    two-file (or more) way is still perfectly valid. Also you could gradually
    introduce this where you see fit.

    I want an easier way only for those who'd like to use it. All languages that
    try to improve on C++, like Java, C# or D went for the single file approach.
    So many people seem to like that.

    > (2) Maintenance. You would have to maintain the inline version
    > of the class in a file and put it through yet another
    > preprocessor (like C++ didn't already have enough of those:
    > macros, templates, and Qt adds its own preproc as well). This
    > just adds complexity without apparent benefit (to me at least).


    Assuming the splitter were bug-free, this would just be one more pattern rule
    (at least with makepp, where dependencies fall into place automatically). So
    there's nothing to worry about.

    As for the benefit, it's a matter of taste. See about other languages above.

    > (3) Readability. Separate interface headers serve among
    > other things the important purpose of showing, well, the
    > interface of the class at a glance. So, well-made headers are
    > usually formatted consistently and are also the place where e.g.
    > doxygen comments are placed. You would have to have those in
    > your inline version as well, which will then become in the worst
    > case a rather large junk piece of unreadable spaghetti code (->
    > point (2)).


    Maybe the mess is just classes that are too big. For me having the (doxygen)
    comment with the method, rather than having to jump to it, seems like an
    advantage. As for showing just the interface, that is impossible with C++,
    where you're always forced to publish the private parts (unless you mask
    everything behind a pointer to a hidden class, IMHO an ugly idiom).

    Öö Tiib compared this to splitting js, css and html. But those, to me, are
    three different classes of information, so it seems right to separate them,
    just as I would still separate classes in my unified C++.

    He also addressed the tickly point of separating #include statements
    correctly. To this I see two solutions:

    1. the simplistic one provides some markup (e.g. #ifdef CXXSPLIT_HEADER) to
    help the splitter assign lines to one file or the other.

    2. the smart way would read the included headers (would need -D and -U options
    to get the #ifdefs right). It would learn everything declared therein, to
    find what is needed in which generated file. This was implied in my example
    where using namespace was elided from the header, and string turned into
    std::string. Should still be much faster than all the work the real compiler
    needs to do.

    > So in my opinion one would benefit much more from work on
    > improving available refactoring tools (like e.g. in Eclipse
    > CDT). And V'Studio users could maybe nag MS to actually
    > implement refactoring facilities for native C++ (i.e.,
    > non-.NET). Just my $0.02.


    It's sad that C++ is so complicated that you (almost) need an IDE just to
    write it. Gosh, that's only €0,0149 ;-)

    regards - Daniel
     
    Daniel Pfeiffer, Apr 7, 2010
    #5
  6. Daniel Pfeiffer

    Jonathan Lee Guest

    On Apr 6, 7:25 pm, Daniel Pfeiffer <> wrote:
    > I want an easier way only for those who'd like to use it.  All languages that
    > try to improve on C++, like Java, C# or D went for the single file approach.
    > So many people seem to like that.


    I'm with you on this. Almost everything in my header files could be
    mechanically pulled from the corresponding cpp file. If there was
    just a preprocessor directive that did what I was going to do anyway,
    I would be much happier.

    // #include "bigint.hpp"
    #import "bigint.cpp"

    --Jonathan
     
    Jonathan Lee, Apr 7, 2010
    #6
  7. Daniel Pfeiffer

    Öö Tiib Guest

    On Apr 7, 2:25 am, Daniel Pfeiffer <> wrote:
    > Hi,
    >
    > I'm replying here to all who took time to answer, since this one is most
    > comprehensive.


    Without going into further details ... lets assume it is doable tool
    and adds value to several from us.

    Have you read Daveed Vandevoorde's modules proposal to standard? I do
    not know how far it is currently. Usually progress there means getting
    less readable. Readable draft:
    http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1778.pdf

    Your tool could achieve both his and yours goals by translating code
    extended by that proposal into current C++ (with #includes and
    __declspec(dllexports) crap ).

    > It's sad that C++ is so complicated that you (almost) need an IDE just to write it. Gosh, that's only €0,0149 ;-)


    I am surprized that you brought up such "IDE is must to have for C++".
    I have observed direct opposite. People using basically a text editor
    + command line scripts are decently productive in C++ team. In Java or
    C# team a person with same toolset seems totally directionless.
     
    Öö Tiib, Apr 7, 2010
    #7
  8. la 04/07/2010 11:10 AM Öö Tiib skribis:
    > On Apr 7, 2:25 am, Daniel Pfeiffer <> wrote:


    > Without going into further details ... lets assume it is doable tool
    > and adds value to several from us.


    > Have you read Daveed Vandevoorde's modules proposal to standard? I do
    > not know how far it is currently. Usually progress there means getting
    > less readable. Readable draft:
    > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1778.pdf


    He's providing an exit from the messy heritage of C. His namespace <<
    operator overloading is funny though, but I can live with that.

    > Your tool could achieve both his and yours goals by translating code
    > extended by that proposal into current C++ (with #includes and
    > __declspec(dllexports) crap ).


    His semantics with really private and selective visibility goes beyond what is
    possible today, so I don't see how it could be translated back into current C++.

    >> It's sad that C++ is so complicated that you (almost) need an IDE just to write it. Gosh, that's only €0,0149 ;-)


    > I am surprized that you brought up such "IDE is must to have for C++".


    I answered to just that implication. I myself use only Emacs for quite a
    sizeable project ;-)

    > I have observed direct opposite. People using basically a text editor
    > + command line scripts are decently productive in C++ team. In Java or
    > C# team a person with same toolset seems totally directionless.


    Often enough it takes an extra round of compiler errors to get the header and
    implementation compatible, though :-( C++ doesn't flow in my veins, Perl does.
     
    Daniel Pfeiffer, Apr 7, 2010
    #8
  9. Daniel Pfeiffer

    Öö Tiib Guest

    On Apr 7, 11:25 pm, Daniel Pfeiffer <> wrote:
    > la 04/07/2010 11:10 AM Öö Tiib skribis:
    >
    > He's providing an exit from the messy heritage of C.  His namespace <<
    > operator overloading is funny though, but I can live with that.
    >


    Funny, yes, perhaps it might change. What is useful in his proposal is
    that there is a way for user to indicate what he wants to export and
    what he wants to hide without making .hh files himself.

    It is still better idea than other ideas:
    1) custom preprocessor things (#ifdef CXXSPLIT_HEADER) are even
    funnier.
    2) options of different heuristic split patterns on tool may lack
    specific splitting strategy that user wants.
    3) When tool first merges from .hh .cc, remembers how it was and later
    stores back so then how to refactor hiding/showing?

    > > Your tool could achieve both his and yours goals by translating code
    > > extended by that proposal into current C++ (with #includes and
    > > __declspec(dllexports) crap ).

    >
    > His semantics with really private and selective visibility goes beyond what is
    > possible today, so I don't see how it could be translated back into current C++.


    Yes, full support to his proposal is not possible to achieve only by
    preprocessing. Also, tool might be unable or not want to hide
    something that is possible (because of additional tricks needed may
    distant the result too lot from source). So it can create .hh files
    (and #include directives) that hide as lot it is able and #include as
    few it is able. At least it should not think itself what user might
    want to hide. When there are ambiguities and/or name conflicts when
    compiling the result then it is usually a case of hard-to-read code
    that review would flush anyway.
     
    Öö Tiib, Apr 8, 2010
    #9
  10. la 04/07/2010 03:35 AM Jonathan Lee skribis:
    > On Apr 6, 7:25 pm, Daniel Pfeiffer <> wrote:
    >> I want an easier way only for those who'd like to use it. All languages that
    >> try to improve on C++, like Java, C# or D went for the single file approach.
    >> So many people seem to like that.

    >
    > I'm with you on this. Almost everything in my header files could be
    > mechanically pulled from the corresponding cpp file. If there was
    > just a preprocessor directive that did what I was going to do anyway,
    > I would be much happier.


    I've found it: Lzz: The Lazy C++ Programmer's Tool
    <http://www.lazycplusplus.com/> gives just about the identical specification I
    gave :)

    They even thought of the people who must use a build tool that's not as smart
    as makepp. There are options to avoid rewriting header files when they would
    be unchanged.

    So sad I'm in a well established project :-( This makes me want to start on a
    new one!

    regards -- Daniel
     
    Daniel Pfeiffer, Apr 26, 2010
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andy Mackie
    Replies:
    4
    Views:
    3,014
    Mark Jerde
    Mar 4, 2004
  2. Lionel

    Splitter and Tabs

    Lionel, Jan 5, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    508
    Jignesh Desai
    Jan 5, 2005
  3. =?Utf-8?B?QW5nZWw=?=

    Splitter

    =?Utf-8?B?QW5nZWw=?=, Oct 5, 2005, in forum: ASP .Net
    Replies:
    4
    Views:
    2,502
    Kevin Spencer
    Oct 5, 2005
  4. Roedy Green

    file splitter utility.

    Roedy Green, Jun 5, 2005, in forum: Java
    Replies:
    2
    Views:
    610
    P.Hill
    Jun 7, 2005
  5. MotoK
    Replies:
    59
    Views:
    1,918
    Keith Thompson
    Sep 15, 2006
Loading...

Share This Page