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

Nick Treleaven nick.treleaven at xxxxx
Wed Aug 28 15:19:57 UTC 2013


On 27/08/2013 02:48, Lex Trotman wrote:
> 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.

Thanks for considering it ;-)

>> 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.

If we want to write OOP code, allow "virtual" and "class". Personally I 
tend to think for Geany OOP is mostly useful for GTK. If we want that, 
we would need gtkmm bindings.

Another reason why I suggest we don't use OOP is that getting 
overloading right with inheritance is difficult for C++ beginners, and 
can cause bugs with experienced devs. Avoiding OOP simplifies the 
unintuitive corner cases of C++, and is easier for C programmers.

> 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 :).

We have a fairly large potential contributor base.

>> 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

Another project was against Neil moving to C++11, not just us. Nice 
though C++11 is. As things stand though, we know using more C++98 won't 
cause problems for users. C99 possibly might. C++11 may do.

>> * 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.

I don't want to use references instead of pointers, only where 
references make the code easier to maintain. E.g. 'Output' arguments and 
sometimes in local scope to simplify repeated expressions.

>> * 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.

+1

>> * 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.

I don't know how well it would work in practice. But it might be better 
to stick to one type for reference counting than two.

>> * 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.

There's a GLib macro for that.

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

Yes.

>> 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.

I don't think it would be significant pain. I'm happy to be the guinea 
pig though.

>>> 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
> :)

Yes, I don't want to move to C++ idioms unless there's a significant 
benefit, considered on a case by case basis.

>> 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.

I'd keep the API types (and all fundamental types) in C.

>> 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.

IMO features should be judged by weighing usefulness vs maintainability 
& community skillset.

>> -fno-rtti (disable runtime info for object inheritance)
>>
>
> Hardly worth it :)

How will we keep the ABI compatible with C then? ;-)

>> 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.  :)

Agree, where practical. But Colomban doesn't like it.

>> 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.

OK, you may be right. I thought it would make it clearer that 
inheritance and virtual functions are not allowed (even though they work 
with structs).

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

I think inheritance + virtuals can be hard to maintain. And harder for 
some contributors to grok.

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

I like private. I don't plan on using friend, but it's not so bad.

>> 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)

I would prefer to keep our code simple by not defining our own 
containers. In Geany's src, I think we should avoid it for simplicity.

>> 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.

OK.

>> 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 :)

I assume you refer to tagmanager. I'm not sure if TM needs to be OOP. I 
don't fancy rewriting it either ;-)




More information about the Devel mailing list