From: William S F. <ws...@fu...> - 2010-11-25 19:30:04
|
David Nadlinger wrote: > I committed the code to SVN trunk a few hours ago. To (hopefully) not > break the test-suite at any time, I put the renaming and special-casing > changes first; I hope this doesn't cause too much confusion. > > As requested, the changes from regenerating the manual index are not > included – should I also commit them, or do you want to wait until the > next release, William? > Not to worry, I'll do that sometime soon. > > On 11/10/10 10:05 PM, William S Fulton wrote: >> - In namespace_class.i, something seems wrong in the library interface >> files if you have had to add: %warnfilter(SWIGWARN_IGNORE_OPERATOR_LT); > The warning suppresses by that comes having »%ignoreoperator(LT) > operator<;« in the lib files, because comparison operators are not > implemented for D1 yet (there is a single »opCmp« for all the order > relations, I'll have yet to come up with a solution to elegantly map it > to the C++ operators). How do I avoid that the ignoring %rename and the > one from the test-case conflict? > Not sure. Hopefully there is something in one of the other languages that you can copy. >> - This won't compile under all C++ compilers (it is best to keep with >> what is used elsewhere in the source): >> for (unsigned int i = 0; …; i++) { > I am not sure about this one because I always thought that declaring > variables in the initializer was specified legal C++ syntax – is this > really not supported by some C++ compilers? Were you referring to > something different? In any case, I would appreciate it if you could fix > issues like this, since I have hardly any experience in dealing with > non-spec-compliant compilers. > VC++6 is the culprit here, although to be honest, I've stopped testing with it now. >> - There are a couple of calls to Printf(stderr, ... which don't error >> out... they should be calling Swig_error() instead to provide a >> conformant file/line error message, as controlled by the -F command line >> options. > Fixed, at least if I correctly understood the way it should be. > >> Consistency observations: >> - Why dnativeconst and not dconst? > You are right, »dnativeconst« would not be any better than just > »dconst«, because it's just as unclear as »dconst«, with the > disadvantage of being inconsistent with the other languages. > > The thing is that one of the signature parts of D (well, D2) is its > const system, similar to const correctness in C++, but much more > sophisticated. The term »const« is heavily linked to a read-only view on > data, not to manifest constants, which is what the feature is obviously > about (manifest constants are declared with the »enum« keyword in D2). > > Thus, I renamed the feature to »dmanifestconst«, which better describes > what it is actually about and avoids ambiguities. > Okay. >> - cwtype, dwtype, dptype […] 'intermediary' […] 'd wrapper' […] ddispose > While working on the D module, I was quite annoyed by having to remember > what all the terms actually meant (I was still using all the names with > »cs« in it from the C# module at that time), so I decided to create a > clear naming scheme which mirrors the actual organization of the > generated D code. Here is what I came up with: > > The generated code basically consists of two parts, the wrapper part, > which is the C layer around the C++ library, and the proxy part, which, > well, proxies the calls through the C layer. Thus, there are two types > in the generated code for a given C/C++ type: the type used in the > wrapper layer, and the type exposed in the proxy layer (thus, calling > the C wrapper function is done via $w[rapper]call, and so on). > > Please note that there is nothing like a »D wrapper« – there is just a D > module, called »<modulename>_wrap« by default, which is basically just a > C header file in D syntax. Incidentally, this module (i.e. file in D > parlance) also contains a few other helper functions, but that's just > because I have not found a better place for it. There isn't something > like an »intermediary« layer, you could actually link the D proxy layer > and the C wrapper layer together statically (the C wrapper code could > even be inlined into the proxy functions and classes with an LTO-capable > linker, that's one of the reasons why I intend to add a static linking > mode). > > If I didn't know SWIG, and would see the term »intermediary« in the > context of the D module, I would probably think of the > wrapper/generated/glue/… C code, since this is what is actually in > between the D proxy interface and the C++ library. > > Thus, I chose the names »cwtype« and »dwtype« to hint at the fact that > they are in fact the very same type, just with slightly different syntax > in some cases. »dptype« could really be called just »ptype«, I suppose, > but I found that explicitly including the language in the type name > makes things clearer. > > As for »ddispose«: This one is a bit of a misnormer. A shortcoming in > the current D object lifetime model is that destruction is completely > non-deterministic and you cannot rely e.g. on objects referenced by > member variables still being in a valid state. Even though D supports > e..g the »scope« statement, which provides RAII-style handling of > reference types, similar to e.g. »using« in C#, and thus deterministic > destruction, there is no way to differentiate between the two different > circumstances in the destructor. > > Thus, a reserved-name method called »dispose()« was added to Tango (the > de-facto standard library for D1) which would be called when the object > would be destructed in a deterministic fashion. Unfortunately, this > never made it into the official language specification, so calling this > typemap »ddestruct« would be confusing – the »destructor« in D is > something different, even if it is equivalent to the notion of a > »finalizer« in C#. > > But, as for all the topics discussed here, it's not like I would have > deep feelings for my code or something, so if you think that another > naming scheme would be a better fit with regard to inter-language > consistency, please feel free to go ahead and fire up sed to apply it. > Barring the ddispose, I would prefer to have this consistent with the other languages, but don't have the inclination to edit this in. As a 2nd choice, given that it breaks with the Java/C# naming in quite a big way, I'd like to see your logic/naming convention that you have described above documented if we keep the naming as it is, especially, as it differs with the C#/Java docs which the D module refers to. >> - Why have example_wrap.foo() instead of just example.foo() - adding >> '_wrap' seem unnecessary to me. Also other languages will expect to >> shared object called libexample.so not libexample_wrap.so by default. > The »<modulename>_wrap« suffix is needed because just »<modulename>« is > already taken by the user visible proxy module (in split proxy mode, it > just contains free functions, global (manifest) constants, and the likes. > > As for the dynamic library name, appending a »_wrap« suffix frankly just > made sense to me: Suppose you are using SWIG to generate bindings for a > library called »foo«, which will probably reside in a shared object > called »libfoo.so« or similar. You will probably want to name the SWIG > module »foo« as well, because this is the name which is used in the D > proxy layer. Now, it seemed pretty straightforward to use > »<modulename>_wrap« as the default shared library name, since just > »modulename« is already taken by the C++ library, »libfoo.so«, and the > »_wrap« suffix hints at the fact that it contains the C wrapper code, > linked to by the D module also called »<modulename>_wrap«. > > Sorry if this might sound ignorant, but as I have not really used SWIG > before starting work on the D module: How do other languages handle this? > <modulenname>_wrap is only used for the C/C++ layer. The other languages take a variety of approaches for the native language layer, but none of them use '_wrap'. For example, Java uses <modulename>JNI.java for the intermediary layer (contains the Java side for the JNI code) and C# uses <modulename>PINVOKE.cs for the intermediary layer (contains the unmanaged function declaratons for PInvoke) and <modulename>.java and <modulename>.cs for globals. Python uses <modulename>.py for the proxy classes, php uses <modulename>.php for the proxy classes, Perl generates <modulename>.pl for proxy/blessed classes, Ruby does not generate any ruby code, likewise for Lua, Tcl and Octave. Thanks for explaining/addressing all the various other points. I'm yet to run the test-suite from trunk to try it out with a working copy of D, but will let you know how this goes. William |