[gdal-dev] Minimum supported C and C++ standards
Even Rouault
even.rouault at spatialys.com
Sat May 7 08:27:19 PDT 2016
Le vendredi 06 mai 2016 23:07:26, Kurt Schwehr a écrit :
> There has been lively discussion on if/when GDAL moves to require compilers
> with newer C and C++ standard versions. This email is meant to fork the
> this discussion away from the local stack + memset -> std::vector
> discussion. I'm trying to draft a proposal based on the discussion, but it
> is a lot hardered.
>
> I suggest folks think about starting off with an empty (or nearly empty)
> white list of features and give a look at documents like:
>
> https://chromium-cpp.appspot.com/.
My personal issue is that most of the stuff mentionned in there is alien to me.
At best only a rough theoretical understanding with no practical use. Perhaps
I should find some time to educate myself on C++11/14 but reading pages like
http://en.cppreference.com/w/cpp/utility/forward doesn't give a strong
incentive to do so ;-)
>
> GDAL is very different than Chromium, but I think it is great that they
> have a place for contributors to get a summary of what is considered okay
> and what is blacklisted.
I'll try to give my perspective over those choices of language features.
As Mateusz righly wrote, GDAL is a mix of C (not that much if you exclude the
external libraries that are internalized), C++ consisting of C with classes
(and avoiding the over use of classes that is typical in a bunch of Java
projects), a few uses of templates for methods working on different data types
in performance sensitive places.
C++03 already offers so many things to master that I can guess that C++11 and
C++14 have added again more "interesting" stuff on top of the old ways (since
hardly nothing prevents you from using a shiny C++ feature next to/together
with a C72 one. Which is porbably one of the main issue of the evolution of
C++). Those new features certainly solve problems, but I'm pretty sure they
also add new potential problems... I recommend having a look at
http://horstmann.com/cpp/pitfalls.html and looking at the date. Now imagine
what a later edition ~20 years later could be with all new C++ features.
Actually look at the snippet in appendix for a good candidate (actually
derived from a tutorial explaing rvalue reference)
Remembering a number of submitted patches, I'm pretty sure some occasional (or
not so occasional) contributors to GDAL are not software engineers as their
first qualification, which is OK since some parts of GDAL are really domain
specific. And even those who are in the software business are not necessarily
familiar with all C++ features, or on the contrary are familiar enough to know
they don't want to use them, or worse, others can believe that they are
familiar with them, but misuse them in subtle ways (never seen an
enthusiastic fresh graduate wanting to apply blindly in your project the nice
stuff seen in books?). IMHO we should try to focus to attract developers that
are more interested by geospatial stuff than by C++ subtelties. GDAL purpose is
not to be a showcase for C++ features, but to solve real-world problems.
Hopefully everybody agrees with that.
If we move to a later C++ standard, or even use features of C++98 we currently
don't use, I'd advocate for using things that are obviously making the code
better / more readable. Honestly who finds that
"std::unique_ptr<int *, std::function<void(char *)>> Vals(CPLCalloc(256, 0),
CPLFree);" is obviously more readable, efficient and less error prone than
"std::vector Vals(256,0)" ?
In my opinion the features of the language you use (of course, once you've
understood and mastered them to the point where they are familiar to you
without needing to open a programming book) play only a minor role in the
maintenance and extensibility of the code (at least, they shouldn't !). The
real challenges are to understand the overall design, the details of the
algorithms, the formats, the interactions between different parts of the code,
what is performance sensitive and what is not, the history ... So definitely
one of the best investment (and less risky) for maintenance is to add comments
where they are needed.
Perhaps rather than thinking to which C++ features we wish, we should
concentrate on the problems we want to solve. The reasoning should be "We have
this problem/need, we currently use solution X to address it, but this has the
following defects and I think that feature Y is the best way to solve it".
And if that's about existing code, we must keep in mind that every change has
the potential to break working things, so the ratio benefit / risk must be >> 1
(>> meaning here "significantly greater than", and not the right bitshift
operator, or the closing of 2 levels of templates, or the input stream
operator, or an overloaded operator with a semantics left to the good will of
the programmer)
The scope of changes should be also defined : restricted to internal
implementation details or impacting the API ?
Tihs is a more trivial consideration, but code churn does make backporting
harder (patches no longer apply cleanly). Although it's an inconvenience that
is acceptable if it makes the future (significantly) better.
Cheers,
Even
(*) The following code compiles warning free with -std=c++11 -Wall -Wextra -
pedantic with GCC 5.2.0 but asserts at runtime. Find why. OK, you may find it
easily since I mentionned this would assert. Now imagine this is a code
contribution that you review. Would you figure out the error ?
Of course, with C or C with classes, the language already offers room for bugs.
But the more language features, the more bug opportunities you add.
#include <string>
#include <cassert>
class Base
{
protected:
std::string x;
public:
Base(const std::string& xin) : x(xin) {}
Base(Base const & rhs) : x(rhs.x) { }
Base(Base&& rhs) { x = rhs.x; rhs.x = "moved"; }
};
class Derived: public Base
{
protected:
std::string y;
public:
Derived(const std::string& xin) : Base(xin), y(xin) { }
Derived(Derived const & rhs) : Base(rhs), y(rhs.y) { }
Derived(Derived&& rhs) : Base(rhs) { y = rhs.y; rhs.y = "moved"; }
~Derived() { assert(y == x); }
};
Derived foo(Derived d)
{
return d;
}
int main()
{
foo(Derived("x"));
return 0;
}
--
Spatialys - Geospatial professional services
http://www.spatialys.com
More information about the gdal-dev
mailing list