[Geany-Devel] Let's move to C++98 - Re: Lets move to C99

Lex Trotman elextr at xxxxx
Tue Aug 27 01:48:57 UTC 2013


Hi Nick,

Thanks for the well thought out sensible proposal.  In general I agree with
the idea of progressively moving appropriate parts of the code to using
appropriate C++ features.  Of course, as usual, I disagree on some of the
details and I'm sure we would disagree on some of the selections of files,
but thats healthy.

Comments below.

Cheers
Lex


On 27 August 2013 01:07, Nick Treleaven <nick.treleaven at btinternet.com>wrote:

> From the C99 discussion:
>
> lex:
> >>> Unless we follow the example of gcc itself and upgrade to C++ :)
>
> me:
> >> Not sure that's a good idea for Geany now, although I'm glad that gcc
> >> did it. They use a restricted subset IIRC. I miss templates and RAII in
> >> C though.
>
> I now think gradually using a (quite heavily restricted) subset of C++98
> for *some* source files might be better than moving to C99 (more on that
> below). I still support C99 over just C90 though. (I don't do a lot of
> Geany coding now, but I plan to do some from time to time, so obviously
> this is just my opinion and less important than more active devs).
>

I'll address the "restricted subset" idea here and refer back from relevant
places below.  My experience of a couple of projects migrating to C++ is
that applying strict "limits" on the C++ features just leads to
implementing those features poorly in the code itself.  One common one is
to not allow virtual functions, but in my experience that just leads to the
use of function pointers and the associated ugly syntax and increase in
errors.  Since the runtime costs are still there, all you have saved is the
cost of the pointer in the object (or at least reduced it to a flag
indicating the object type, but then you have to test it each use, again
error prone).

The approach that seems to have worked better is the same as that required
for C++ in general, *appropriate* use of features.  Whilst that is easier
to control in a corporate situation where programmers can be trained
properly, review by senior devs should catch the more egregious misuses
within Geany, its not like we have a huge developer base to train anyway :).


>
> Reasons:
>
> * No build problems for Long Term Support distros that don't support C99
> (but clearly do compile scintilla's C++98).
>

Neil is attempting to move Scintilla forward, it might soon be using C++03.5


>
> * RAII - this is a pretty essential feature for safe resource management.
> It's a stupid acronym though, it's basically automatic scoped destruction:
>
> http://en.wikipedia.org/wiki/**Resource_Acquisition_is_**Initialization<http://en.wikipedia.org/wiki/Resource_Acquisition_is_Initialization>


Agree on both the usefulness and the silly name :)


>
>
> * References can be useful in making code more readable vs pointers.
>

Unfortunately, since references are immutable, you can never get rid of
pointers in imperative style programs, that leads to code with a mix,
luckily getting it wrong (using . not ->) will be picked up by the compiler.


>
> * Developer enjoyment, productivity & gaining more experience with C++.
> (This might be an incentive for e.g. me to spend more time working on
> Geany). This has to be offset against those that might need to learn e.g.
> RAII.
>

Indeed there is a learning curve, but hopefully many will find that useful
and attractive.


>
> * Possibly we might use some STL containers internally.
>
>
Most definitely.



> * Possibly we could use a GObject wrapper for safe reference counting. I
> don't want to add any dependencies on C++ libraries though.
>

Or what almost all my C++03 programs have, a template headed:  /* The
ubiquitous intrusive reference counted smart pointer */ :)

Of course use gobject, for things that are gobjects, but don't bring it
into things that are not, the idea is to move to C++, not to tie more
closely to a C library.


>
> * Possibly we could have some template function utilities instead of
> unsafe macros. Although I think most header files should be kept C90
> compatible.
>

Yes existing headers that are used by the remaining C code will have to
remain C compatible, and will probably need:

#ifdef __cplusplus
extern "C" {
#endif

around them.

But (for C++ files) that doesn't prevent having extra headers with
templates in them.


>
> matt:
> > +1. While I'm also not sure it's a good idea in Geany and certainly
> > won't be pressing for it anytime soon, 90% of C++'s crumminess is due to
> > backwards compatibility with C, so I think it should be (theoretically,
> > not socially) possible to gradually transition from one to the other in
> > a project like Geany without too much pain.
>
> colomban:
> > I doubt it, C++ is sufficiently different from a C program not to be
> > compilable by a C++ compiler in many cases -- even if it is just for
> > some implicit casts C++ requires to be explicit (IIRC), and there are
> > plenty.  Or maybe it depends what "too much pain" means:)
>

So long as the gain is larger than the pain.


> >
> > Also, I doubt it's any kind of sensible either, because good C++ use is
> > sufficiently different from C to require large rewrite.  In this case,
> > better rewrite everything and don't keep the clumsy code
>
> I disagree it *requires* a large rewrite. You can make *good* use of some
> C++ features without having *idiomatic* use of C++. (E.g. dmd, the
> reference D compiler is not written in idiomatic C++ - it doesn't use the
> STL really, but it's still good code).
>

I agree with Nick, my experience is transitioning to C++ does not need a
big re-write just to get a compile.  You then *choose* what to re-write, to
take advantage of features to make life easier and safer.  Even I don't
advocate wholesale re-writing of random code to C++ idioms without a reason
:)


>
> I think it would be quite manageable. If we did this, I suggest just
> converting one source file at a time, and only files that can benefit from
> RAII and/or the more powerful type system.
>

Yes, so long as C compatible interfaces are available for as yet
unconverted files its fine, for example if GeanyDocument became a C++ class
appropriate headers would be needed.


>
> We would also need to disable some C++ features. I hoped we could do that
> with g++ flags, but I've only found this so far:
>

I addressed the problems with this general idea above.  It will also lead
to ongoing bikesheds on what features are "allowed" and why can't Geany
progress to use more useful features and ... This is both wasteful of
community time, and destructive of community spirit, better to encourage
use of appropriate features, and where an "advanced" feature is
appropriate, then it can be used without having to remove such constraints.


>
> -fno-rtti (disable runtime info for object inheritance)
>

Hardly worth it :)


>
> There ought to be a way to disable mixed code and declarations, but maybe
> not.
>

NEVER DECLARE ANYTHING UNTIL YOU HAVE A VALUE FOR IT.  :)

For those having trouble finding declarations not at the top of a scope,
remember Geany highlights types, so declarations stand out, just change
your theme to make them more visible Colomban ;)


>
> I don't know if this can be enforced by g++, but I suggest we disallow
> these keywords:
>
> class
>

Why, its just a struct with default hiding, this just forces the use of
struct xxx { private: .... }.  The use of private members is an important
part of the ability of the compiler to protect the programmers from
themselves, and a big plus of C++, since it makes it easier to ensure that
required invariants are maintained because only listed entities can change
the members.


> dynamic_cast
>

Agree it should *almost* never be used, and so just search for it is easy
enough.


> friend
>

Unless you are implying never to use private members, sometimes you *have *
to use friends.


> mutable
>

Its mostly useful for optimisations that we probably don't need ... yet :)


> operator
>

Thats required to define the ubiquitous reference counting smart pointer,
but agree that operators should *only* be used where their semantics mirror
the standard ones. (and of course only in interfaces which are not used by
C code)


> throw
>

Agree, when we have mixed C/C++ code, throwing an exception from C++
through C can cause all the resources in the C code to leak since it
doesn't have any destructors to clean up for it.


> virtual
>

Geany has a couple of places where a bastardised version of virtual
functions have been implemented in C, its ugly, hard to understand, and
error prone.  These cases *should* be replaced by C++ virtuals (if anyone
understands the C code enough to do it :)


>
> That could be enforced with a 'make check' build target.
>
> Thoughts?
>
> Regards,
> Nick
> ______________________________**_________________
> Devel mailing list
> Devel at lists.geany.org
> https://lists.geany.org/cgi-**bin/mailman/listinfo/devel<https://lists.geany.org/cgi-bin/mailman/listinfo/devel>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.geany.org/pipermail/devel/attachments/20130827/3a11748d/attachment-0001.html>


More information about the Devel mailing list