Discussion:
Following up on C++11 standard support
David Oswald
2012-09-17 20:57:32 UTC
Permalink
Some additional testing has provided additional successes and failures
on what parts of C++11 are supported by Inline::CPP

There's a pretty thorough explanation in the POD, in the latest
version on Github in the master branch. But a quick summary (in case
anyone has any thoughts on what might be worth getting to work on):

All constructs that I know of that take place inside of a function or
method are OK. The innards are a black-box to Inline::CPP, and it
doesn't care what you do inside a function, so feel free to use
lambdas, the new 'for( auto it: x ) {...}' syntax, and so on.

The trouble areas are with external bindings of new features. In some
cases, it wouldn't even make sense to bind to Perl. Here's the list
that I know about:

Rvalue references:

int x = 100;
int && getRvalueInt() { return std::move(x) }

Inline::CPP's grammar doesn't recognize "&&", and will just skip that
function. Conceptually, I'm not convinced that there's even a
reasonable and consistent mapping that could take place. How exactly
should an rvalue reference map to Perl? Nevertheless, it does seem
like one syntax that probably could be bound by Inline::CPP. I think
it would lead to some nasty bugs from Perl's perspective, though.

constexpr int multiply ( int x, int y ) { return x * y; }

C++ will expand this at compiletime, and thus, needs to know what
values 'x' and 'y' represent *at compile-time*. I don't see any way
that it could make sense to attempt to bind a constexpr function to
Perl. In fact, though I haven't found documentation on the topic, I
doubt that constexpr functions can even have external linkage.

auto add ( int x, int y ) -> int { return x + y; }

This is known as the "late return type" syntax. Conceptually there's
no reason why Inline::CPP shouldn't be upgraded to support it.
Practically, it's probably only going to find widespread use in
simplifying the design of templates (which themselves can't be bound
directly to Perl), or in lambdas (which take place inside of
functions, and are invisible to Perl). So the two most common
use-cases are irrelevant to Perl. Nevertheless, it is valid syntax
and could be supported with some work.

enum class Color { RED, GREEN, BLUE };

We're already ignoring enums (I think). Scoped enums, added in C++11
are a little more problematic. What would a legitimate binding be?
"Readonly $Color::RED = 0;"? (because that's essentially what it
means). It's probably best to just ignore it and document that it's
fine to use within C++ code, but that it doesn't bind to Perl.

Ok, that's the list I've come up with. Everything else (I think)
should be supported by Inline::CPP implicitly, to the extent that the
C++ compiler supports the new standards. In the POD, I did add an
example to the CCFLAGS setting on how to specify to the compiler that
it should enable C++11 syntax (again, that's in the github repo, and
will end up in the next version of Inline::CPP, which is in no hurry
to be released. ;)


Old issues:

Templates: Templates are resolved at compile time. The compiler has
to know what data types are being used to invoke a template-based
class or function. Templates are a static-language's answer to
generic programming. Perl's answer to generic programming is much
more dynamic. The result is that the C++ compiler cannot deduce how
Perl intends to call a function, and consequently, cannot generate
template instantiations. Templates will probably never be first-class
citizens in Inline::CPP. They are just fine to use behind the scenes,
but will never be able to bind to Perl directly. Wrappers must be
used.

Multiple inheritance: There's a bug in Inline::CPP's handling of
multiple inheritance. The old unit tests failed to detect the
problem. The updated unit tests have a TODO section in the
multiple-inheritance test. The tests in that section currently fail.
I have no idea how to fix it.

Multi-dimensional member arrays: This is a low-priority issue. Who
in their right mind would be using multi-dimensional arrays as member
data when the STL provides vectors, and as of C++11, even the
bounds-checked std::array (which *does* work as a multidimentional
member data entity)? But it is valid C++ syntax, and the Inline::CPP
grammar doesn't handle it properly.

Exception specifiers: "int add ( int x, int y ) throw() { return x, y;
} // A contract: this function believes it will never throw an
exception"

C++ exception specifiers have never been understood by Inline::CPP.
And we were way ahead of the curve on that one; in C++11 they're
deprecated. When they were introduced in C++03 most people almost
immediately considered them to be a really "bad idea" anyway, and I
don't think they ever found their way into mainstream use.
Inline::CPP's refusal to bind functions that use exception specifiers
can now be seen as a "feature." ;)

Dave
--
David Oswald
daoswald-***@public.gmane.org
David Oswald
2012-09-20 01:47:27 UTC
Permalink
Dave,
What's your current view on Inline::CPP support for C++11 tuples ??
Tuples are really just a new STL container that take advantage of the
fact that C++11 implements variadic templates. So essentially the
same rule applies to tuples as to any other C++ object: All data types
need to be represented with a typemap.

The default typemap understands POD types (Plain Old Data): int, long,
short, char, double, float, etc. The one aggregate container that
Perl's default typemaps handle is the null-terminated array of chars
(C-Strings).

When you use a more complex object type, Perl needs a type map for
that type that tells Perl how to put values into it, and how to
extract values from it. This is done by adding your own typemaps.
This is why we usually don't see Inline::CPP functions passing vectors
back and forth, for example; there's no "vector" typemap. No
"multi-map" typemap, etc. There certainly could be. But there's one
other problem. Those containers can hold any data type. So you would
also need to deal with the genericity (is that a word?) of the STL
containers within your type map. ...a bunch of meta-programming that
keeps track of whether it's a vector<char> or a vector<pair<char,int>
, or what. Way too much work.
The easiest approach is to create accessors for your classes that
shield Perl from the details about the container type. Don't return a
vector. Return an iterator, or return a value, or return a list, or a
Perl container.

So the short answer is feel free to use Tuples internally, and expose
to Perl either Perl containers or plain old data types, just as you
would do with vectors, maps, etc.

I hope this helps.

Dave
--
David Oswald
daoswald-***@public.gmane.org
Loading...