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).
Reasons:
* No build problems for Long Term Support distros that don't support C99 (but clearly do compile scintilla's C++98).
* 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
* References can be useful in making code more readable vs pointers.
* 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.
* Possibly we might use some STL containers internally.
* Possibly we could use a GObject wrapper for safe reference counting. I don't want to add any dependencies on C++ libraries though.
* Possibly we could have some template function utilities instead of unsafe macros. Although I think most header files should be kept C90 compatible.
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:)
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 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.
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:
-fno-rtti (disable runtime info for object inheritance)
There ought to be a way to disable mixed code and declarations, but maybe not.
I don't know if this can be enforced by g++, but I suggest we disallow these keywords:
class dynamic_cast friend mutable operator throw virtual
That could be enforced with a 'make check' build target.
Thoughts?
Regards, Nick
On Mon, 26 Aug 2013 16:07:13 +0100 Nick Treleaven nick.treleaven@btinternet.com wrote:
I now think gradually using a (quite heavily restricted) subset of C++98 for *some* source files might be better than moving to C99 [...]
Reasons:
- RAII - this is a pretty essential feature for safe resource
management.
This works for global/static and auto classes. We can wrap a gchar *s = g_strdup_printf() in a class, but I'd rather not... and you want to ban "class".
- References can be useful in making code more readable vs pointers.
But using both heavily (as GLib/GTK+ required pointers) will make it harder to read.
- 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.
Hmmm?..
- Possibly we might use some STL containers internally.
There things are heavily templated. They generate more code, compilation is slower, and (unless improved significantly from the last time I tried them) the code is overall slower than using GArray/GList. Moreover, you propose to ban "class".
- Possibly we could use a GObject wrapper for safe reference counting.
Why? Where? How to do that without classes and destructors? Note that gcc has a non-standard extension for RAII, which works with the base C types. And Geany compiles with gcc only.
- Possibly we could have some template function utilities instead of
unsafe macros.
Do we need these macros to work with different types? If not, "inline is already declared in a portable manner in the GLib headers and can be used normally."
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:
-fno-rtti (disable runtime info for object inheritance)
+1. Earlier versions of Qt/KDE did that, don't know about current.
There ought to be a way to disable mixed code and declarations, but maybe not.
Not AFAIK.
I don't know if this can be enforced by g++, but I suggest we disallow these keywords:
class
There isn't, that's THE most basic feature of C++. And you can write classes with struct and union.
dynamic_cast
-fno-rtti
friend
No classes -> no usage for friends.
mutable operator
throw
-fno-exceptions
virtual
No classes -> no virtual methods.
Thoughts?
Sorry, but IMHO, that seems even more pointless than using C99.
On 26/08/2013 19:54, Dimitar Zhekov wrote:
On Mon, 26 Aug 2013 16:07:13 +0100 Nick Treleaven nick.treleaven@btinternet.com wrote:
- RAII - this is a pretty essential feature for safe resource
management.
This works for global/static and auto classes. We can wrap a gchar *s = g_strdup_printf() in a class, but I'd rather not...
We don't always need a gchar*. For string processing we could use the STL basic_string (or Scintilla SString).
- References can be useful in making code more readable vs pointers.
But using both heavily (as GLib/GTK+ required pointers) will make it harder to read.
Just use them where they help ;-)
- 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.
Hmmm?..
Time spent for contributors who don't know C++ to learn the parts we use. What's the question?
- Possibly we might use some STL containers internally.
There things are heavily templated. They generate more code, compilation is slower, and (unless improved significantly from the last time I tried them) the code is overall slower than using GArray/GList.
Slower compilation may be an issue. The minor performance/bloat differences you mention would not be a problem for Geany IMO.
Assuming we're comparing the same design in C vs templated C++ code, the C++ code would normally have an advantage because more code can be inlined. It might be at a disadvantage because of code bloat though, but the inlining may outweigh that. Are you sure you tested the C++ code with full compiler optimization?
Moreover, you propose to ban "class".
struct = class but with public member visibility by default.
- Possibly we could use a GObject wrapper for safe reference counting.
Why? Where? How to do that without classes and destructors?
Obviously you need destructors for RAII. I meant ban the keyword 'class' in Geany code, not in STL code.
Note that gcc has a non-standard extension for RAII, which works with the base C types. And Geany compiles with gcc only.
Really? Have you read HACKING?
- Possibly we could have some template function utilities instead of
unsafe macros.
Do we need these macros to work with different types? If not, "inline is already declared in a portable manner in the GLib headers and can be used normally."
See FALLBACK in tagmanager. Matt doesn't like it though. I don't expect we need to replace many macros, more that some template utility functions will be useful in C++ code. I can give an example if you like.
I don't know if this can be enforced by g++, but I suggest we disallow these keywords:
class
There isn't, that's THE most basic feature of C++. And you can write classes with struct and union.
exactly.
dynamic_cast
-fno-rtti
ok.
friend
No classes -> no usage for friends.
...
virtual
No classes -> no virtual methods.
*cough* structs *cough*
throw
-fno-exceptions
nice
Thoughts?
Sorry, but IMHO, that seems even more pointless than using C99.
RAII != pointless
On Wed, 28 Aug 2013 15:52:17 +0100 Nick Treleaven nick.treleaven@btinternet.com wrote:
- 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.
Hmmm?..
Time spent for contributors who don't know C++ to learn the parts we use. What's the question?
What's the assumption - that harder contribution will actually be beneficial? Maybe we should throw some C# then, it's modern and somewhat supported under Linux, and there may be people who want to learn it. :)
Assuming we're comparing the same design in C vs templated C++ code, the C++ code would normally have an advantage because more code can be inlined. It might be at a disadvantage because of code bloat though, but the inlining may outweigh that. Are you sure you tested the C++ code with full compiler optimization?
With -O2 for gcc, and the standard "Optimize for speed" profile in the compiler used by our company. If you mean something like -O99, no, I haven't. The difference insignificant (<= 0.5%), only annoying. A probable reason is that STL doesn't use realloc(), and has no slice allocator (though I haven't tested slices explicitly).
Note that gcc has a non-standard extension for RAII, which works with the base C types. And Geany compiles with gcc only.
Really? Have you read HACKING?
The non-existent part which lists the supported compilers? :) (I know, I know: use standard C code only).
--
So it would be something with pointers-and-references, gchar-and-[S]String, STL-and-GArray/GList (sometimes required by GLib/GTK), GObjects-and-classes (or no classes? or library classes only?..), and some words banned... It'll indeed be challenging to contribute.
About RAII, how can I convice you that the automatic destructors for global/static and auto objects *only* are not that useful? Perhaps by the fact that the later languages, Java and C#, use a different model, more similar to GLib?
As for our own C++ reference counting for pointers - please... One should not include new essences unless required. Sorry if my english is unclear, I think Lex will understand and say it better.
If we are to switch, let's at least stick to what scintilla/gtk/* does, instead of inventing our own "standards" and wheels. And by that, I mean gradually rewriting Geany with classes. C++ with functions is like perl with glob() expressions. It'll still be ugly though, with all the x'-and-x"-s listed above.
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@btinternet.comwrote:
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_**Initializationhttp://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@lists.geany.org https://lists.geany.org/cgi-**bin/mailman/listinfo/develhttps://lists.geany.org/cgi-bin/mailman/listinfo/devel
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_**Initializationhttp://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 ;-)
On 13-08-26 08:07 AM, Nick Treleaven 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).
Reasons:
- No build problems for Long Term Support distros that don't support C99
(but clearly do compile scintilla's C++98).
- 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
References can be useful in making code more readable vs pointers.
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.
Possibly we might use some STL containers internally.
Possibly we could use a GObject wrapper for safe reference counting. I
don't want to add any dependencies on C++ libraries though.
- Possibly we could have some template function utilities instead of
unsafe macros. Although I think most header files should be kept C90 compatible.
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:)
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 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.
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:
-fno-rtti (disable runtime info for object inheritance)
There ought to be a way to disable mixed code and declarations, but maybe not.
I don't know if this can be enforced by g++, but I suggest we disallow these keywords:
class dynamic_cast friend mutable operator throw virtual
That could be enforced with a 'make check' build target.
Thoughts?
I was waiting for Colomban to respond before piping up, but whatever. I'll just respond to the general topics in the thread in my typical TL;DR fashion (skip to Conclusion section if you like :)
Style and Ease of Contribution ------------------------------
Personally, I think it'd be great to use C++ in Geany, and it would more than likely actually make it *easier* for people to contribute since outside of a sampling of GTK+-using desktop/GUI software (and obviously embedded, kernel, drivers, and similar), C is considered "dead" and the majority uses >= C++ (more likely Java, C#, Python ... many people also consider C++ outdated and dead for desktop GUI apps - not me BTW :). C++ allows modern programming techniques but still retains much (or more) of the performance and "light-weightedness" that Geany strives for.
If we were to use C++, I think it'd be pointless to limit it to CFront/CwithClasses-style 1980's C++. We should use common/standard stuff like standard library containers, inheritance (maybe not multipl-inheritance), the class keyword, templates (where it makes sense), exceptions, etc. The issues/limits being discussed in this thread are issues long since considered "resolved" or "non-issues" for a long time for desktop software (and since a *long* time even before Geany's first line of code was written :). The style of code I read on the net and in talks and books and stuff is modern (ie. >= C++98) style C++ and I'd expect that's what the bulk of C++-using contributors would be used to using.
I'd say the limit on what should be used in Geany should reflect modern techniques and practices (ie. since 1998), perhaps following the style/limits used by Qt (excepting their MOC which extends C++ and not implementing standard strings and containers ourselves, which Qt does because they weren't standard when Qt started). Another good example of a high-quality maintainable C++ (IMO) is LLVM, which as I read in a quote somewhere that it "uses a 'tasteful' subset of C++" and is described to some extent in their coding/style guides and elsewhere on the net. Of course being a *massive* hunk of code in a high-speed optimizing compiler framework imposes different limitations on C++'s use, some of which might not apply to Geany.
<semi-off-topic-legacy-rant> I would even go so far as to say it's silly to not use C++11 since it's such a major improvement over previous C++ versions, in both performance and readability/coder-friendliness and it's well supported on current compilers and platforms.
I've said it before that I think coding *new code* for *future release* using *outdated libraries/language versions* is silly, like using deprecated GTK+2 APIs, C89, etc, in *new code*, and I think the same applies to C++11. We're talking about *new code* for *future releases* not *old code* in *old releases*, which remain usable by users not using the "latest greatest" (anywhere from 2 to 20+ years ago depending on the topic), and in which many cases are being supported/patched/fixed by the distro vendor, often for money I would presume. Keeping in mind none of us gets paid to write the *new code*, it's harsh having to pretend it's 2 to 20+ years ago (in some cases), for free, for little to no gain, much pain, going against current best practices evolved since the bad old days and often at the expense of readability, maintainability and sometimes even performance.
IMO, so long as Geany can **RUN** on the current supported versions of major operating systems, that is enough to strive for. Note that I said **RUN** and not **COMPILE** and that I'm talking about *new code* for *new releases* not for the old code in already working and released versions supported by previously released long-term support distros. </semi-off-topic-legacy-rant>
Where to use it ---------------
In my personal opinion, it doesn't make a whole lot of sense to use C++ in the src/ directory, at least not just for the sake of compiling with g++ instead gcc. As mentioned, it'd be awkward interfacing G* stuff with C++ stuff, and would likely have very little benefit unless doing majour changes/re-writing of the existing code. If one wanted to make serious modifications to one the modules in src/, like re-writing it in en masse or majour improvements, then it'd definitively make sense to use C++ in src/ dir.
Another place it'd make good sense to use C++ is in some "non-core" module, say something like TagManager, MIO, Scintilla, or even as above, re-working an existing "core" module out into "non-core" land, say something like Stash library, that can stand alone. If such stuff was being re-written, replaced, or overhauled, then it'd be cool to be not stuck with plain C for ease of coding and improving maintainability.
<digression-from-C++> Since we're talking about better languages, there's also Vala which has most of the benefits discussed here about C++, already uses the same libraries and type-system as our existing G* code, is API compatible with C (in the sense that it generates idiomatic G*-style C code, mostly) and would be an easier transition for the vast quantity of C# programmers out there who might want to contribute, since the languages are so similar. Not sure it's a point since most of them use Mono and C#-strong IDEs, but still, in general there's probably substantially more developers out there who know C# better than C or C++.
One of the down-sides with Vala is that there the language specification is incomplete, constantly moving, and overall the project lacks any really good documentation. However, the wiki, the "Vala for ___ Language Programmers" guides, Valadoc (which gradually improves), and tons of tutorials and example code out on the web somewhat make up for it. The other obvious flaw is that it's a young programming language and not widely tested or supported like C/C++ - ie. has more bugs in its implementation.
I'm not actually saying we should use Vala, just that it makes at least as much sense as C++ for Geany. </digression-from-C++>
Why not to use it -----------------
Above being said, the biggest reason not to use or allow any C++ outside of Scintilla is that Geany's maintainer, largest contributor in the last quite a while - most reviews, merges, patches, fixes, etc. - dislikes C++ (and quite vehemently, last we talked about it) . I also disliked C++ before I started learning it in earnest at which point I could see many of the great benefits over C (and also some new stinkers :). I bet Colomban would experience the same change of opinion about it, to some extent, if he used it more and started using some of the since-CwithClasses stuff more, BUT ... I'm not sure it's fair to "push" that onto him.
While it's a community project, and in general I think the popular opinion should ultimately prevail or at least that not one person (barring maybe a BDL) solely controls the direction of the project's momentum, it's somewhat harsh to make the current maintainer who does an excellent job and devotes a lot of time already to working on Geany stuff, to learn a whole different, non-trivial language, one he dislikes, and to become "more proficient than average" in order to be able to continue doing code reviews, merging PRs and stuff.
Note that I obviously don't speak for Colomban, it's just my feeling, and that I tried to wait until after he responded on his own behalf about C++ hate :)
Conclusion ----------
I'm all for using modern C++ in strategic (or new) places and I'm totally against using ancient 1980/90's CFront-style C++ or that which is restricted so much that it's basically C. Ultimately though, I would go along with whatever Colomban wants (except stick to C89 instead of C99 :)
Maybe rather than bikeshed about it too much, we can wait until someone wants to add a new module, or replace an existing module (I'm looking at you TM!), or some actual use case, at which point we could discuss whether it makes sense to use C++ for it, and since we already use C++ for Scintilla, it's not a huge change to use it in another new C++ module with respect to the build systems and stuff.
P.S. As usual, sorry for such a long message :)
Cheers, Matthew Brush
Nick, Matthew, Dimitar,
To keep it short, a few comments:
@Nick,
Thinking back on previous conversions from C to C++, those that went smoothest were the ones that first changed to compiling with the C++ compiler, with minimal changes to the C code. This means that you are not having to be unreasonably careful about non-C compatible features like exceptions. That also allows smart pointers for resource management (where an object is needed outside its creation scope) and other useful features.
On the topic of exceptions, remember many STL operations and "new" can throw. Of course only throwing on uncorrectable errors like out of memory is fine, it just exits the application. Thats what will happen to a throw from Scintilla in current Geany, its not something that will be introduced. But as resource management moves to RAII, exceptions can be caught and produce a more user friendly exit such as dumping buffers first.
After Geany compiles with C++, then parts that can benefit from/need more C++ features can be changed as someone wants/needs to, its not that everything has to go to multiple inherited virtual templates tomorrow :).
On using gtkmm, personally I think it is *way* better than the C interface to GTK, but I don't know if it can be mixed with C GTK easily, and changing *everything at once* would be a big job.
Not sure why the RTTI affects the ABI, things visible in the ABI must be POD to maintain C compatibility, there are much stricter limitations to maintaining POD, like no non-trivial constructors etc.
@Dimitar,
IIUC many C++ implementations (and even some C ones) use the same algorithm as gslice for small objects already, and of course it can't be used for strings since they are not fixed size.
The global/static/auto version of RAII is fine if you use smart pointers to objects that have longer lifetimes, the local RAII ensures that the object is deleted any time it is still owned by a smart pointer declared in the scope being exited. If the object is to live on, it will have been passed to another smart pointer outside the scope.
@Matthew,
The resource engineering points are IMHO the main ones preventing this happening. Geany just doesn't have enough resources to do major changes. Subtract those who don't like C++ (its a free world, I don't like Vala :) and the resources are slimmer still. Irrespective of whether the changes are made "one file at a time" or "all C to C++ with minimal changes" there is a significant first step, coding and testing and testing and testing. Most of us are very time constrained, unless we find a significant pool of available resources it is not gonna happen.
We need to organise the resources first, doing things "to attract more contributors" have so far failed, I wouldn't bet a change like this on attracting more support (at least in the time the change is happening).
Nick has offered that C++ "might" attract him to contribute more, I "might" have time at the end of my current contract, unless I get another quickly, I guess Colomban is out, Matthew? anybody else?
Cheers Lex
On 29/08/2013 06:47, Lex Trotman wrote:
On the topic of exceptions, remember many STL operations and "new" can throw. Of course only throwing on uncorrectable errors like out of memory is fine, it just exits the application. Thats what will happen to a throw from Scintilla in current Geany, its not something that will be introduced. But as resource management moves to RAII, exceptions can be caught and produce a more user friendly exit such as dumping buffers first.
OK. We might not want to use -fno-exceptions then, but maybe still avoid throwing ourselves.
On using gtkmm, personally I think it is *way* better than the C interface to GTK, but I don't know if it can be mixed with C GTK easily, and changing *everything at once* would be a big job.
I don't know either, but gtkmm is much better than GObject boilerplate. Although I don't think we need custom objects that often.
Not sure why the RTTI affects the ABI, things visible in the ABI must be POD to maintain C compatibility, there are much stricter limitations to maintaining POD, like no non-trivial constructors etc.
OK, so a struct declaration in extern C would be compatible with the C ABI.
We need to organise the resources first, doing things "to attract more contributors" have so far failed, I wouldn't bet a change like this on attracting more support (at least in the time the change is happening).
I think moving to C99 may at least avoid /deterring/ further contributions because of minor issues like C++-style comments and variable declaration after code (or at least in a for statement). I don't know if it makes a big difference, but the fewer unnecessary hurdles we make them jump through the better.
Nick has offered that C++ "might" attract him to contribute more, I "might" have time at the end of my current contract, unless I get another quickly, I guess Colomban is out, Matthew? anybody else?
I'm happy to manage/co-ordinate the transition to C++ (at a slowish pace), should we decide we want that.
On 1 September 2013 00:05, Nick Treleaven nick.treleaven@btinternet.comwrote:
On 29/08/2013 06:47, Lex Trotman wrote:
On the topic of exceptions, remember many STL operations and "new" can throw. Of course only throwing on uncorrectable errors like out of memory is fine, it just exits the application. Thats what will happen to a throw from Scintilla in current Geany, its not something that will be introduced. But as resource management moves to RAII, exceptions can be caught and produce a more user friendly exit such as dumping buffers first.
OK. We might not want to use -fno-exceptions then, but maybe still avoid throwing ourselves.
I've never used -fno-exceptions, but reading the docs it doesn't sound like it actually stops code throwing, just it doesn't create the data tables for stack unwinding. I presume therefore throws go direct to terminate(), do not pass try, do not catch $200 (apologies to Monopoly :)
On using gtkmm, personally I think it is *way* better than the C interface
to GTK, but I don't know if it can be mixed with C GTK easily, and changing *everything at once* would be a big job.
I don't know either, but gtkmm is much better than GObject boilerplate. Although I don't think we need custom objects that often.
Funnily enough, since subclassing widgets is trivial with gtkmm, they start to be used more often in my experience :)
Not sure why the RTTI affects the ABI, things visible in the ABI must be
POD to maintain C compatibility, there are much stricter limitations to maintaining POD, like no non-trivial constructors etc.
OK, so a struct declaration in extern C would be compatible with the C ABI.
Yes, a pure struct, no constructors, destructors, no virtual member functions etc is required by the standard to be the same layout as C. The extern "C" just stops the names being mangled so it will link with C.
We need to organise the resources first, doing things "to attract more
contributors" have so far failed, I wouldn't bet a change like this on attracting more support (at least in the time the change is happening).
I think moving to C99 may at least avoid /deterring/ further contributions because of minor issues like C++-style comments and variable declaration after code (or at least in a for statement). I don't know if it makes a big difference, but the fewer unnecessary hurdles we make them jump through the better.
Yes, if those things are allowed.
Nick has offered that C++ "might" attract him to contribute more, I
"might" have time at the end of my current contract, unless I get another quickly, I guess Colomban is out, Matthew? anybody else?
I'm happy to manage/co-ordinate the transition to C++ (at a slowish pace), should we decide we want that.
Cheers Lex
______________________________**_________________ Devel mailing list Devel@lists.geany.org https://lists.geany.org/cgi-**bin/mailman/listinfo/develhttps://lists.geany.org/cgi-bin/mailman/listinfo/devel
On 13-08-31 04:37 PM, Lex Trotman wrote:
On 1 September 2013 00:05, Nick Treleaven nick.treleaven@btinternet.comwrote:
On 29/08/2013 06:47, Lex Trotman wrote:
[...]
On using gtkmm, personally I think it is *way* better than the C interface
to GTK, but I don't know if it can be mixed with C GTK easily, and changing *everything at once* would be a big job.
I don't know either, but gtkmm is much better than GObject boilerplate. Although I don't think we need custom objects that often.
Funnily enough, since subclassing widgets is trivial with gtkmm, they start to be used more often in my experience :)
Yeah, there's lots of cases for Geany; geany::MainWindow, geany::Toolbar, geany::PrefsDialog, geany::Scintilla, geany::StatusBar, geany::SymbolsView, geany::EditorMenu, and even the existing GObject subclasses, not to mention geany::Filetype or geany::Document and friends.
Anywhere you want to extend/customize the behaviour of another class or widget or such.
Cheers, Matthew Brush
On 13-08-31 07:05 AM, Nick Treleaven wrote:
On 29/08/2013 06:47, Lex Trotman wrote:
[...]
Nick has offered that C++ "might" attract him to contribute more, I "might" have time at the end of my current contract, unless I get another quickly, I guess Colomban is out, Matthew? anybody else?
I'm happy to manage/co-ordinate the transition to C++ (at a slowish pace), should we decide we want that.
IMO, step #1 is to create a separate branch for this topic. I'm sure Colomban won't mind a separate branch if it's not affecting master and it would provide a hacking playground for everyone interested. If it proves fruitful, we could eventually look to merge/replace Geany code from this branch, even if we have to maintain separate branches for some time.
I think starting with a core plugin is a good idea. The "Class Builder" plugin has lots of gnarly C string copying/formatting/etc, it might be a good candidate for hackage, as per your suggestion.
Cheers, Matthew Brush
On 29/08/2013 02:39, Matthew Brush wrote:
Personally, I think it'd be great to use C++ in Geany, and it would more than likely actually make it *easier* for people to contribute since outside of a sampling of GTK+-using desktop/GUI software (and obviously embedded, kernel, drivers, and similar), C is considered "dead" and the majority uses >= C++ (more likely Java, C#, Python ... many people also consider C++ outdated and dead for desktop GUI apps - not me BTW :). C++ allows modern programming techniques but still retains much (or more) of the performance and "light-weightedness" that Geany strives for.
Yeah, templates make it much easier for libraries to have extra flexibility in performance.
If we were to use C++, I think it'd be pointless to limit it to CFront/CwithClasses-style 1980's C++. We should use common/standard stuff like standard library containers, inheritance (maybe not multipl-inheritance), the class keyword, templates (where it makes sense), exceptions, etc. The issues/limits being discussed in this thread are issues long since considered "resolved" or "non-issues" for a long time for desktop software (and since a *long* time even before Geany's first line of code was written :). The style of code I read on the net and in talks and books and stuff is modern (ie. >= C++98) style C++ and I'd expect that's what the bulk of C++-using contributors would be used to using.
Idiomatic C++ takes a *lot* of learning and experience to get right for someone coming from C.
I would even go so far as to say it's silly to not use C++11 since it's such a major improvement over previous C++ versions, in both performance
I'm curious, why does it perform better?
and readability/coder-friendliness and it's well supported on current compilers and platforms.
Is it? I hadn't heard that, maybe. But I bet it will cause problems for some distro maintainers/builders on LTS distros.
Readability is definitely better in C++11 when avoiding iterators and using lambdas, but I was kind of hoping we could avoid those ugly cases. I wasn't thinking of using the STL heavily, just a few containers like string, and perhaps others for any specialized use cases.
Variadic templates are very cool also. (Die, stream << operators!)
Since we're talking about better languages, there's also Vala which has most of the benefits discussed here about C++, already uses the same libraries and type-system as our existing G* code, is API compatible with C (in the sense that it generates idiomatic G*-style C code, mostly) and would be an easier transition for the vast quantity of C# programmers out there who might want to contribute, since the languages are so similar. Not sure it's a point since most of them use Mono and C#-strong IDEs, but still, in general there's probably substantially more developers out there who know C# better than C or C++.
I'm happy to consider using Vala, but I think it would probably be a lot less work to use C++ if we want to convert existing code.
While it's a community project, and in general I think the popular opinion should ultimately prevail or at least that not one person (barring maybe a BDL) solely controls the direction of the project's momentum, it's somewhat harsh to make the current maintainer who does an excellent job and devotes a lot of time already to working on Geany stuff, to learn a whole different, non-trivial language, one he dislikes, and to become "more proficient than average" in order to be able to continue doing code reviews, merging PRs and stuff.
+1. Although I would definitely be keener to contribute using restricted C++, I don't want to be maintainer again. Thanks for all the great work Colomban (and others) ;-)
I'm all for using modern C++ in strategic (or new) places and I'm totally against using ancient 1980/90's CFront-style C++ or that which is restricted so much that it's basically C.
totally against :-O
RAII is a powerful feature that standard C has no hope of competing with. It basically allows a string type with automatic memory management. Ditto for templates, but I can live without defining our own templates if that helps contributor understanding & maintainability.
I proposed banning OOP, operator overloading and exceptions in src to make it (much?) easier to understand & maintain the code vs idiomatic C++, with all its unintuitive bug-prone corner cases (which are still in C++11), see my reply to Lex for more info.
Maybe rather than bikeshed about it too much, we can wait until someone wants to add a new module, or replace an existing module (I'm looking at you TM!), or some actual use case, at which point we could discuss whether it makes sense to use C++ for it, and since we already use C++ for Scintilla, it's not a huge change to use it in another new C++ module with respect to the build systems and stuff.
Yes, or maybe convert a core plugin that uses strings a lot, so we get the benefit of RAII. I might look into it unless Colomban is against that (even for a core plugin).
P.S. As usual, sorry for such a long message :)
No problem, it was an interesting read.
Hi Nick,
[...]
I would even go so far as to say it's silly to not use C++11 since it's
such a major improvement over previous C++ versions, in both performance
I'm curious, why does it perform better?
I'm putting words in Matthews mouth here, but things like move semantics can reduce the need for allocations and copying, but like all such "performance improvements" it needs to be used a zillion times before it matters, and well, Geany does few things a zillion times (except inside Scintilla's rendering code).
and readability/coder-friendliness and it's well supported on current
compilers and platforms.
Is it? I hadn't heard that, maybe. But I bet it will cause problems for some distro maintainers/builders on LTS distros.
Many of the simpler but useful parts of C++11 seem to have been implemented in many compilers a while ago, and most compilers now seem to be at, or close to, standards compliance, but as you say LTS systems are not going to support C++11 for a while yet. For example gcc 4.6 (the oldest supported version) does some stuff under the banner of C++0x and I'm happily using C++11 with gcc 4.7 without problems, a bit behind the 4.9 latest development version.
Readability is definitely better in C++11 when avoiding iterators and using lambdas, but I was kind of hoping we could avoid those ugly cases. I wasn't thinking of using the STL heavily, just a few containers like string, and perhaps others for any specialized use cases.
Sadly, containers means iterators, inevitably, and yes C++03 syntax is ugly, but you get used to it, and just type it automatically. Pity "auto" and "for( a: container )" is C++11, oh well.
[...]
I proposed banning OOP, operator overloading and exceptions in src to make
it (much?) easier to understand & maintain the code vs idiomatic C++, with all its unintuitive bug-prone corner cases (which are still in C++11), see my reply to Lex for more info.
Looking at it again, I'm not sure we mean the same thing by OOP, its a much abused and overloaded term, could you perhaps explain your meaning? Depending on what you mean, banning it is either sensible, or the silliest idea ever :)
Maybe rather than bikeshed about it too much, we can wait until someone
wants to add a new module, or replace an existing module (I'm looking at you TM!), or some actual use case, at which point we could discuss whether it makes sense to use C++ for it, and since we already use C++ for Scintilla, it's not a huge change to use it in another new C++ module with respect to the build systems and stuff.
Yes, or maybe convert a core plugin that uses strings a lot, so we get the benefit of RAII. I might look into it unless Colomban is against that (even for a core plugin).
Good idea, plugins can be written in C++ now, without any changes to Geany being needed. Just make sure you don't leak exceptions (unless you mean to) since they currently mean terminate().
Cheers Lex
On 29/08/2013 13:52, Lex Trotman wrote:
I would even go so far as to say it's silly to not use C++11 since it's
such a major improvement over previous C++ versions, in both performance
I'm curious, why does it perform better?
I'm putting words in Matthews mouth here, but things like move semantics can reduce the need for allocations and copying, but like all such "performance improvements" it needs to be used a zillion times before it matters, and well, Geany does few things a zillion times (except inside Scintilla's rendering code).
OK.
Readability is definitely better in C++11 when avoiding iterators and using lambdas, but I was kind of hoping we could avoid those ugly cases. I wasn't thinking of using the STL heavily, just a few containers like string, and perhaps others for any specialized use cases.
Sadly, containers means iterators, inevitably, and yes C++03 syntax is ugly, but you get used to it, and just type it automatically. Pity "auto" and "for( a: container )" is C++11, oh well.
Yes. Unless we use a foreach macro ;-P I'm not sure iterators are needed often for string though, but it's been a while since I looked at code using it.
I proposed banning OOP, operator overloading and exceptions in src to make
it (much?) easier to understand & maintain the code vs idiomatic C++, with all its unintuitive bug-prone corner cases (which are still in C++11), see my reply to Lex for more info.
Looking at it again, I'm not sure we mean the same thing by OOP, its a much abused and overloaded term, could you perhaps explain your meaning? Depending on what you mean, banning it is either sensible, or the silliest idea ever :)
I mean inheritance and virtual functions. I don't think they would pull their weight in src, unless we were going to use gtkmm for custom widgets.
Yes, or maybe convert a core plugin that uses strings a lot, so we get the benefit of RAII. I might look into it unless Colomban is against that (even for a core plugin).
Good idea, plugins can be written in C++ now, without any changes to Geany being needed. Just make sure you don't leak exceptions (unless you mean to) since they currently mean terminate().
OK.
Regards, Nick
[...]
Readability is definitely better in C++11 when avoiding iterators and
using lambdas, but I was kind of hoping we could avoid those ugly cases. I wasn't thinking of using the STL heavily, just a few containers like string, and perhaps others for any specialized use cases.
Sadly, containers means iterators, inevitably, and yes C++03 syntax is ugly, but you get used to it, and just type it automatically. Pity "auto" and "for( a: container )" is C++11, oh well.
Yes. Unless we use a foreach macro ;-P
m-m-m-m-m-macro?
There seems to be a typo here, I assume you mean the std::for_each template :)
And of course requiring the use of a function object declared immediately before the for_each, not a function declared some distance away.
I'm not sure iterators are needed often for string though, but it's been a while since I looked at code using it.
Ahh, I may have been misunderstanding you again.
Strictly strings are not containers, so I havn't considered them whenever you said container, I was thinking vector, list, etc.
I find iterators are rarely used on strings because it has operator[] and most of the operations return an index, not an iterator.
I proposed banning OOP, operator overloading and exceptions in src to make
it (much?) easier to understand & maintain the code vs idiomatic C++, with all its unintuitive bug-prone corner cases (which are still in C++11), see my reply to Lex for more info.
Looking at it again, I'm not sure we mean the same thing by OOP, its a
much abused and overloaded term, could you perhaps explain your meaning? Depending on what you mean, banning it is either sensible, or the silliest idea ever :)
I mean inheritance and virtual functions. I don't think they would pull their weight in src, unless we were going to use gtkmm for custom widgets.
Agree I can't immediately think of places where inheritance is likely to be useful at high level, but thats no reason to ban it.
Mind you, the concepts of document and filetype could be combined by deriving a filetype specific document type from the base Document class, allowing filetype specific overriding of functions like indenting :)
class Perl_document::Document { etc };
Which brings me to the point that some *design* and planning might be useful before we start hacking.
[...]
Cheers Lex
On 01/09/2013 01:08, Lex Trotman wrote:
I mean inheritance and virtual functions. I don't think they would pull
their weight in src, unless we were going to use gtkmm for custom widgets.
Agree I can't immediately think of places where inheritance is likely to be useful at high level, but thats no reason to ban it.
That's not the reason. The reason is maintainability and ease of contribution.
On 13-08-29 05:08 AM, Nick Treleaven wrote:
On 29/08/2013 02:39, Matthew Brush wrote:
[...]
If we were to use C++, I think it'd be pointless to limit it to CFront/CwithClasses-style 1980's C++. We should use common/standard stuff like standard library containers, inheritance (maybe not multipl-inheritance), the class keyword, templates (where it makes sense), exceptions, etc. The issues/limits being discussed in this thread are issues long since considered "resolved" or "non-issues" for a long time for desktop software (and since a *long* time even before Geany's first line of code was written :). The style of code I read on the net and in talks and books and stuff is modern (ie. >= C++98) style C++ and I'd expect that's what the bulk of C++-using contributors would be used to using.
Idiomatic C++ takes a *lot* of learning and experience to get right for someone coming from C.
Do you think there's more C-only programmers out there contributing to desktop application projects than C++ programmers? I honestly don't know but my instinct says there isn't.
I would even go so far as to say it's silly to not use C++11 since it's [...]
Just for fun I wrote some theoretical code that could be used in a program like Geany to compare styles between various C's and C++'s (note: none of it tested).
http://pastebin.geany.org/gYFMO/
Cheers, Matthew Brush
[...]
Just for fun I wrote some theoretical code that could be used in a program like Geany to compare styles between various C's and C++'s (note: none of it tested).
http://pastebin.geany.org/**gYFMO/ http://pastebin.geany.org/gYFMO/
As discussed on IRC here's another way of doing the C++98/03, marked with +es. http://pastebin.geany.org/AzbMV/
This is the method I alluded to in my response to Nick.
For the micro-optimisers among us, its very likely to generate the same code as the first version since the operator() call is inlined :)
Cheers Lex
Cheers, Matthew Brush
______________________________**_________________ Devel mailing list Devel@lists.geany.org https://lists.geany.org/cgi-**bin/mailman/listinfo/develhttps://lists.geany.org/cgi-bin/mailman/listinfo/devel
On 13-08-31 07:42 PM, Lex Trotman wrote:
[...]
Just for fun I wrote some theoretical code that could be used in a program like Geany to compare styles between various C's and C++'s (note: none of it tested).
http://pastebin.geany.org/**gYFMO/ http://pastebin.geany.org/gYFMO/
As discussed on IRC here's another way of doing the C++98/03, marked with +es. http://pastebin.geany.org/AzbMV/
Or alternatively in c++11 :)
for_each(begin(App::instance().windows()), end(App::instance().windows()), [] (Window &win) { for_each(begin(win.documents()), end(win.documents(), [] (Document &doc) { // do stuff with each document } ); } );
Cheers, Matthew Brush
On 01/09/2013 03:53, Matthew Brush wrote:
On 13-08-31 07:42 PM, Lex Trotman wrote:
Just for fun I wrote some theoretical code that could be used in a program like Geany to compare styles between various C's and C++'s (note: none of it tested).
http://pastebin.geany.org/**gYFMO/ http://pastebin.geany.org/gYFMO/
As discussed on IRC here's another way of doing the C++98/03, marked with +es. http://pastebin.geany.org/AzbMV/
Or alternatively in c++11 :)
for_each(begin(App::instance().windows()), end(App::instance().windows()), [] (Window &win) { for_each(begin(win.documents()), end(win.documents(), [] (Document &doc) { // do stuff with each document } ); } );
Still somewhat noisy IMO. How about this, C++98 (I think):
#include <boost/foreach.hpp> #define FOREACH BOOST_FOREACH
FOREACH(Document &doc, win.documents()) { // do stuff with each document }
See: http://www.boost.org/doc/libs/1_54_0/doc/html/foreach.html
"BOOST_FOREACH is designed for ease-of-use and efficiency. It does no dynamic allocations, makes no virtual function calls or calls through function pointers, and makes no calls that are not transparent to the compiler's optimizer. This results in near-optimal code generation; the performance of BOOST_FOREACH is usually within a few percent of the equivalent hand-coded loop. And although BOOST_FOREACH is a macro, it is a remarkably well-behaved one. It evaluates its arguments exactly once, leading to no nasty surprises."
[...]
Hi Nick,
Still somewhat noisy IMO. How about this, C++98 (I think):
#include <boost/foreach.hpp> #define FOREACH BOOST_FOREACH
FOREACH(Document &doc, win.documents()) { // do stuff with each document }
Frankly if you want to limit the parts of standard C++ that are used, the last thing you want to do is to introduce a whole second language, that of the Boost library. :)
Also you previously worried about compilation times, well boost is a big hairball of headers that include each other, efficient for its developers, but its notorious for slowing compilations to a crawl.
I guess I was wrong when I said we disagreed on details, I think after reviewing the thread, we disagree at a very fundamental level on limiting parts of the language.
To me limiting language features removes many benefits of the language by throwing away the standard idioms and solutions that use them. The design problems for Geany are not unusual, and there are a set of well known and documented solutions to many of them. These solutions are known to work, and known to work well, and known to be safe, and by removing specific language features many of these standard solutions become no longer available.
Using a project specific subset of features is not likely to make it easier for C programmers to learn and contribute because they can't follow the standard advice in books and on the web any more. It also is not likely to attract any existing C++ programmers, they are unlikely to want to discount their knowledge capital by being limited to a subset of their known solutions. Moving away from the documented standard language just adds more barriers to contribution.
And doing things like writing project specific macros like "foreach_document" doesn't help, in either C or C++. :)
This does not mean that there should be a free-for-all on how C++ features are used. They should be used where that feature would normally be expected to be used, rather than a sub-optimal C-like solution, or a solution that uses features for features sake. I can only defer to the expert on the subject http://www.stroustrup.com/bs_faq2.html#coding-standard and please note the JSF standards are *not* applicable to Geany. Geany isn't an over budget, over schedule, critical real-time, billion dollar weapons platform :) The key idea is to have a set of standards appropriate to the project.
Ignoring style advice, since we have our own, something much more appropriate is the GCC coding conventions http://gcc.gnu.org/codingconventions.html. The C++ section starts:
"C++ is a complex language, and we strive to use it in a manner that is not surprising. So, the primary rule is to be reasonable. Use a language feature in known good ways. If you need to use a feature in an unusual way, or a way that violates the "should" rules below, seek guidance, review and feedback from the wider community."
This is also a project moving from C to C++ (and as of recently has achieved the milestone of compiling fully with C++) and the rules anticipate changes, such as the desire to move to RAII style exception safety. This may then permit the use of exceptions. These changes can happen progressively throughout the code base, and gcc is a "little" bigger than Geany :)
Cheers Lex
[...]
On 05/09/2013 12:26, Lex Trotman wrote:
[...]
Hi Nick,
Still somewhat noisy IMO. How about this, C++98 (I think):
#include <boost/foreach.hpp> #define FOREACH BOOST_FOREACH
FOREACH(Document &doc, win.documents()) { // do stuff with each document }
Frankly if you want to limit the parts of standard C++ that are used, the last thing you want to do is to introduce a whole second language, that of the Boost library. :)
That macro is very similar to C++11 range for. A whole second language it is not.
Also you previously worried about compilation times, well boost is a big hairball of headers that include each other, efficient for its developers, but its notorious for slowing compilations to a crawl.
I haven't used it, but it says it's supposed to be modular. It may well be possible to use BOOST_FOREACH without adding more than a few headers to the project. What don't you like about it? Surely you can see it is much cleaner than std::for_each?
I guess I was wrong when I said we disagreed on details, I think after reviewing the thread, we disagree at a very fundamental level on limiting parts of the language.
To me limiting language features removes many benefits of the language by throwing away the standard idioms and solutions that use them. The design problems for Geany are not unusual, and there are a set of well known and documented solutions to many of them. These solutions are known to work, and known to work well, and known to be safe, and by removing specific language features many of these standard solutions become no longer available.
Using a project specific subset of features is not likely to make it easier for C programmers to learn and contribute because they can't follow the standard advice in books and on the web any more. It also is not likely to
They don't need to learn it. We could even limit RAII to just using the string type. Dynamic strings are well understood by programmers, even GLib has GString. Strings are fundamental to Geany.
The problem is if we don't agree to just use the most useful C++ features, there is no way the project will move to it. C++ is controversial.
attract any existing C++ programmers, they are unlikely to want to discount their knowledge capital by being limited to a subset of their known solutions. Moving away from the documented standard language just adds more barriers to contribution.
And doing things like writing project specific macros like "foreach_document" doesn't help, in either C or C++. :)
I'm happy to consider a better solution, Matt's foreach_doc is much better, once we move away from C90. If you have a better idea, please start a new thread. It must somehow deal with doc->is_valid transparently though.
If we could accept BOOST_FOREACH, we could make a documents() function that works with it.
This does not mean that there should be a free-for-all on how C++ features are used. They should be used where that feature would normally be expected to be used, rather than a sub-optimal C-like solution, or a solution that uses features for features sake. I can only defer to the expert on the subject http://www.stroustrup.com/bs_faq2.html#coding-standard and please note the JSF standards are *not* applicable to Geany. Geany isn't an over budget, over schedule, critical real-time, billion dollar weapons platform :) The key idea is to have a set of standards appropriate to the project.
Ignoring style advice, since we have our own, something much more appropriate is the GCC coding conventions http://gcc.gnu.org/codingconventions.html. The C++ section starts:
"C++ is a complex language, and we strive to use it in a manner that is not surprising. So, the primary rule is to be reasonable. Use a language feature in known good ways. If you need to use a feature in an unusual way, or a way that violates the "should" rules below, seek guidance, review and feedback from the wider community."
This is also a project moving from C to C++ (and as of recently has achieved the milestone of compiling fully with C++) and the rules anticipate changes, such as the desire to move to RAII style exception safety. This may then permit the use of exceptions. These changes can happen progressively throughout the code base, and gcc is a "little" bigger than Geany :)
We have very few resources (and possibly expertise too) to rewrite the Geany API in C++, and it would be a big distraction and likely cause many arguments (as it already has).
We could instead decide to be pragmatic instead of idealistic and accept that only using the most useful features of C++ that apply for Geany is a workable, maintainable, easy to understand solution that is still better than just C99.
I won't continue to push for this unless anyone else shares my view. We can probably give up on any C++ in Geany's core.
[...]
We have very few resources (and possibly expertise too) to rewrite the Geany API in C++, and it would be a big distraction and likely cause many arguments (as it already has).
I said nothing about re-writing the API, in fact I said it needed to remain POD to be C compatible.
As for the arguments about future use of the C++ language, well we've got lots of time, since whichever way we go, the first step is to get a minimally changed Geany to re-compile in C++. Things like RAII or forall_documents() and any other changes only apply after that.
We could instead decide to be pragmatic instead of idealistic and accept that only using the most useful features of C++ that apply for Geany is a workable, maintainable, easy to understand solution that is still better than just C99.
Well, C written in C++ is not a workable maintainable easy to understand solution IMHO, but as I said the first step is to in fact get to that point, then things can be changed as and when people have time and inclination.
I won't continue to push for this unless anyone else shares my view. We can probably give up on any C++ in Geany's core.
Don't let the fact that we disagree on something that is in the future turn you off, I have already said I don't have much contributory time in the short term at least, so you havn't lost much :). But yes, being realistic you can't do it on your own in anything like a reasonable time frame, and it will require support of the rest of the community to accept it into the project.
Perhaps a way forward would be if you provided a more concrete plan for the process you see being used, such as actual changes to headers and code that are needed to turn Geany into C++. I'm sure it won't be as simple as changing .c to .cxx (but it would be great if it was :). This way others have some way to gauge what they can contribute and you might attract some other helpers.
Cheers Lex
______________________________**_________________ Devel mailing list Devel@lists.geany.org https://lists.geany.org/cgi-**bin/mailman/listinfo/develhttps://lists.geany.org/cgi-bin/mailman/listinfo/devel
On 01/09/2013 02:36, Matthew Brush wrote:
I would even go so far as to say it's silly to not use C++11 since it's [...]
Just for fun I wrote some theoretical code that could be used in a program like Geany to compare styles between various C's and C++'s (note: none of it tested).
My C89 & C++ version:
guint i; foreach_document(i) { GeanyDocument *doc = documents[i]; // do stuff with every valid doc }
I don't think we should rewrite Geany's API in C++, or maintain a C++ wrapper for the C one, except for any cases which are particularly bug-prone.
On 13-09-04 09:20 AM, Nick Treleaven wrote:
On 01/09/2013 02:36, Matthew Brush wrote:
I would even go so far as to say it's silly to not use C++11 since it's [...]
Just for fun I wrote some theoretical code that could be used in a program like Geany to compare styles between various C's and C++'s (note: none of it tested).
My C89 & C++ version:
guint i; foreach_document(i) { GeanyDocument *doc = documents[i]; // do stuff with every valid doc }
While this code is short, it's actually sort of nuts too (and also not very C++-ish).
1. You should include the definition of the custom macro used and the definitions of the two other non-obvious macros used inside the first macro for a fair comparison, since none of them are standard or even well-known like the pasted examples.
2. The code does not loop over the windows like the pasted code, so you'd need another outer loop which would likely have a 2nd style of iteration wrapped around the existing loop.
3. It's somewhat unclear what type should be passed in looking at the macro without the doc comments (I always forget and have to RTFM each time I see it since we often use gint where we mean guint).
4. The argument is not only assigned to but also evaluated multiple times (what if you pass `--i` or something weird as argument). I guess assigning might be good here since the compiler would catch it rather than flying off the end of the array when it hits `(guint)-1` (UINT_MAX) on underflow.
5. It's fairly tricky to debug misuses of the macro (better with Clang).
6. The implicit check in the loop (failure first) indexes into a macro wrapper around a whole other type using a hard cast from the result of another function-like macro cast thing off in another file, and is dereferenced without any NULL check (although probably safe in this case, unless a plugin or something re-assigns the global variable or redefines any macro aliases of it).
7. It forces you to define an indexing variable outside of the loop into the wrong scope (C89-style, even if used in > C99 plugin code).
8. Even though slightly dirtier, it would be more useful to iterate over document pointers than document indexes (what are those? tab pages? order of opening? arbitrary array indices?), for example (untested, C99 or GNU89 probably):
#define foreach_doc(doc) \ for (unsigned z_=0; z_ < documents_array->len; z_++) \ if ( !((doc) = documents_array->pdata[z_]) || \ !(doc)->is_valid ) { continue; } else ... GeanyDocument *doc; foreach_doc(doc) { // every valid doc }
9. I personally find it annoying to use API's that have all their own versions of things that are really common and not that hard anyway; it's difficult to learn them all, and also all the stuff mentioned above when they are macros. Consider this slightly longer example that uses no macro madness and common C looping idiom:
guint i; for (i = 0; i < documents_array->len; i++) { GeanyDocument *doc = documents_array->pdata[i]; // do stuff with every *should be* (but isn't) valid doc }
Assuming the API didn't have the weirdness about documents being invalid but still sticking around for whatever reason, it's the same number of lines as the macro version and no magic.
10. The macro should be named `foreach_document_index()`.
</macro-hate>
I don't think we should rewrite Geany's API in C++, or maintain a C++ wrapper for the C one, except for any cases which are particularly bug-prone.
An idiomatic C++ binding would be quite useful for a plugin written in normal C++. In my current C++ plugin I'm working on, I'm actually wrapping up a few parts of Geany's API it uses to avoid scattering the weird C code containing lots of raw pointers, miscellaneous allocators, different string/collection types, and so on, throughout the normal C++ code.
Cheers, Matthew Brush
On 05/09/2013 09:41, Matthew Brush wrote:
On 13-09-04 09:20 AM, Nick Treleaven wrote:
My C89 & C++ version:
guint i; foreach_document(i) { GeanyDocument *doc = documents[i]; // do stuff with every valid doc }
While this code is short, it's actually sort of nuts too (and also not very C++-ish).
- You should include the definition of the custom macro used and the
definitions of the two other non-obvious macros used inside the first macro for a fair comparison, since none of them are standard or even well-known like the pasted examples.
Most files already include document.h.
- The code does not loop over the windows like the pasted code, so
you'd need another outer loop which would likely have a 2nd style of iteration wrapped around the existing loop.
We don't support accessing multiple windows IIUC.
BTW I was just providing code for that specific case, not necessarily for all iteration.
- It's somewhat unclear what type should be passed in looking at the
macro without the doc comments (I always forget and have to RTFM each time I see it since we often use gint where we mean guint).
- The argument is not only assigned to but also evaluated multiple
times (what if you pass `--i` or something weird as argument). I guess assigning might be good here since the compiler would catch it rather than flying off the end of the array when it hits `(guint)-1` (UINT_MAX) on underflow.
It's fairly tricky to debug misuses of the macro (better with Clang).
The implicit check in the loop (failure first) indexes into a macro
wrapper around a whole other type using a hard cast from the result of another function-like macro cast thing off in another file, and is dereferenced without any NULL check (although probably safe in this case, unless a plugin or something re-assigns the global variable or redefines any macro aliases of it).
- It forces you to define an indexing variable outside of the loop into
the wrong scope (C89-style, even if used in > C99 plugin code).
- Even though slightly dirtier, it would be more useful to iterate over
document pointers than document indexes (what are those? tab pages? order of opening? arbitrary array indices?), for example (untested, C99 or GNU89 probably):
#define foreach_doc(doc) \ for (unsigned z_=0; z_ < documents_array->len; z_++) \ if ( !((doc) = documents_array->pdata[z_]) || \ !(doc)->is_valid ) { continue; } else ... GeanyDocument *doc; foreach_doc(doc) { // every valid doc }
Yes, that is much better if we have C99/C++. That also solves most of the points above.
- I personally find it annoying to use API's that have all their own
versions of things that are really common and not that hard anyway; it's difficult to learn them all, and also all the stuff mentioned above when they are macros. Consider this slightly longer example that uses no macro madness and common C looping idiom:
guint i; for (i = 0; i < documents_array->len; i++) { GeanyDocument *doc = documents_array->pdata[i]; // do stuff with every *should be* (but isn't) valid doc }
Assuming the API didn't have the weirdness about documents being invalid but still sticking around for whatever reason, it's the same number of lines as the macro version and no magic.
Yes. Although sometimes bugs do slip through, even in incrementing for loops. Suppose someone used <= instead of <, or forgot to initialize i.
- The macro should be named `foreach_document_index()`.
OK.
I don't think we should rewrite Geany's API in C++, or maintain a C++ wrapper for the C one, except for any cases which are particularly bug-prone.
An idiomatic C++ binding would be quite useful for a plugin written in normal C++. In my current C++ plugin I'm working on, I'm actually wrapping up a few parts of Geany's API it uses to avoid scattering the weird C code containing lots of raw pointers, miscellaneous allocators, different string/collection types, and so on, throughout the normal C++ code.
It would be useful, but also a distraction for the core project.
On 01/09/2013 02:36, Matthew Brush wrote:
On 13-08-29 05:08 AM, Nick Treleaven wrote:
On 29/08/2013 02:39, Matthew Brush wrote:
[...]
If we were to use C++, I think it'd be pointless to limit it to CFront/CwithClasses-style 1980's C++. We should use common/standard stuff like standard library containers, inheritance (maybe not multipl-inheritance), the class keyword, templates (where it makes sense), exceptions, etc. The issues/limits being discussed in this thread are issues long since considered "resolved" or "non-issues" for a long time for desktop software (and since a *long* time even before Geany's first line of code was written :). The style of code I read on the net and in talks and books and stuff is modern (ie. >= C++98) style C++ and I'd expect that's what the bulk of C++-using contributors would be used to using.
Idiomatic C++ takes a *lot* of learning and experience to get right for someone coming from C.
Do you think there's more C-only programmers out there contributing to desktop application projects than C++ programmers? I honestly don't know but my instinct says there isn't.
If you mean open source projects, then yes. Somewhat difficult to measure, but some (possibly flawed) stats:
Here C has at least twice the share of C++: http://lang-index.sourceforge.net/
In terms of noise on the web, here C also has approaching twice that of C++: http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
Also even if there were more C++ programmers, it would still be much easier for a C++ programmer to write C than vice versa.
P.S. Sorry for the late replies, also to Lex ;-) Been AFK a lot lately.
On 05/09/2013 10:26, Nick Treleaven wrote:
Also even if there were more C++ programmers, it would still be much easier for a C++ programmer to write C than vice versa.
Here I meant *idiomatic* (STL-heavy) C++. Some features e.g. references are well known to programmers of other languages and IMO simple to learn and understand. I think using a dynamic string type is also well understood by modern programmers. Even if we just used those two things, I think it would be worth starting to use some C++.
On 13-09-05 02:26 AM, Nick Treleaven wrote:
On 01/09/2013 02:36, Matthew Brush wrote:
On 13-08-29 05:08 AM, Nick Treleaven wrote:
On 29/08/2013 02:39, Matthew Brush wrote:
[...]
If we were to use C++, I think it'd be pointless to limit it to CFront/CwithClasses-style 1980's C++. We should use common/standard stuff like standard library containers, inheritance (maybe not multipl-inheritance), the class keyword, templates (where it makes sense), exceptions, etc. The issues/limits being discussed in this thread are issues long since considered "resolved" or "non-issues" for a long time for desktop software (and since a *long* time even before Geany's first line of code was written :). The style of code I read on the net and in talks and books and stuff is modern (ie. >= C++98) style C++ and I'd expect that's what the bulk of C++-using contributors would be used to using.
Idiomatic C++ takes a *lot* of learning and experience to get right for someone coming from C.
Do you think there's more C-only programmers out there contributing to desktop application projects than C++ programmers? I honestly don't know but my instinct says there isn't.
If you mean open source projects, then yes. Somewhat difficult to measure, but some (possibly flawed) stats:
Here C has at least twice the share of C++: http://lang-index.sourceforge.net/
In terms of noise on the web, here C also has approaching twice that of C++: http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
It would be better (but even harder to measure) to compare desktop applications, as I mentioned, like Geany since this is an area where C++ makes a lot of more sense compared to C, and there's a lot of excellent C++ GUI toolkits like Qt, WxWidgets, FLTK, FOX, GTKmm, WTL, etc. Compared to C, where GTK+ is about the only actually good toolkit I've ever come across.
Also even if there were more C++ programmers, it would still be much easier for a C++ programmer to write C than vice versa.
Yeah maybe, although if you learned C++ first, using C is fairly foreign and weird I'm sure. Also all of the other languages that support modern/more programming paradigms would probably make an easier transition to C++ than C.
Cheers, Matthew Brush
On 05/09/2013 10:48, Matthew Brush wrote:
On 13-09-05 02:26 AM, Nick Treleaven wrote:
On 01/09/2013 02:36, Matthew Brush wrote:
On 13-08-29 05:08 AM, Nick Treleaven wrote:
On 29/08/2013 02:39, Matthew Brush wrote:
[...]
If we were to use C++, I think it'd be pointless to limit it to CFront/CwithClasses-style 1980's C++. We should use common/standard stuff like standard library containers, inheritance (maybe not multipl-inheritance), the class keyword, templates (where it makes sense), exceptions, etc. The issues/limits being discussed in this thread are issues long since considered "resolved" or "non-issues" for a long time for desktop software (and since a *long* time even before Geany's first line of code was written :). The style of code I read on the net and in talks and books and stuff is modern (ie. >= C++98) style C++ and I'd expect that's what the bulk of C++-using contributors would be used to using.
Idiomatic C++ takes a *lot* of learning and experience to get right for someone coming from C.
Do you think there's more C-only programmers out there contributing to desktop application projects than C++ programmers? I honestly don't know but my instinct says there isn't.
If you mean open source projects, then yes. Somewhat difficult to measure, but some (possibly flawed) stats:
Here C has at least twice the share of C++: http://lang-index.sourceforge.net/
In terms of noise on the web, here C also has approaching twice that of C++: http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
It would be better (but even harder to measure) to compare desktop applications, as I mentioned, like Geany since this is an area where C++ makes a lot of more sense compared to C, and there's a lot of excellent C++ GUI toolkits like Qt, WxWidgets, FLTK, FOX, GTKmm, WTL, etc. Compared to C, where GTK+ is about the only actually good toolkit I've ever come across.
You don't need to be a GUI programmer to make good contributions to Geany.
Also even if there were more C++ programmers, it would still be much easier for a C++ programmer to write C than vice versa.
Yeah maybe, although if you learned C++ first, using C is fairly foreign and weird I'm sure. Also all of the other languages that support modern/more programming paradigms would probably make an easier transition to C++ than C.
The STL is almost unique. Only D has something similar. Also C++-style RAII is not commonly found in popular languages.