User: Password:
|
|
Subscribe / Log in / New account

Clasen: Introducing GtkInspector

Clasen: Introducing GtkInspector

Posted May 18, 2014 13:15 UTC (Sun) by rleigh (guest, #14622)
In reply to: Clasen: Introducing GtkInspector by Seegras
Parent article: Clasen: Introducing GtkInspector

That's a mistaken assumption though. GTK+ is not really "C", it's "GObject-based C", which is fundamentally different. The problem with this is that even if you're an expert C programmer, GTK+ is still a worse choice than Qt. It will take less time and effort to learn and master C++ and Qt than it will to learn and master GTK+, and your code will be of higher quality to boot.

The thing is, if you're writing anything other than a trivial example, using GTK+ requires using GObject/GType, and this means that you will be:

- doing RTTI in C
- constructing virtual call tables by hand
- writing constructors and destructors by hand (not just the easy bits either, but all the extra stuff C++ does for you, plus you have to handle the multi-phase construction and destruction GObject performs, which is vastly more complex than C++)
- you'll be forced to use construction properties which are not efficient
- writing all the type initialisation and registration code to register your classes with GType
- generating all the cast macros
- doing all the refcounting by hand
- you'll need to know more about C++ implementation details than most C++ programmers in order to understand and use it

This "works", don't get me wrong. But... the level of expertise and proficiency required to do this is beyond silly. It requires the user to replicate, by hand, in C, complex implementation details which would be automatically generated by the C++ compiler, like vtables and typeinfos and marshalling. And all the RTTI stuff. At this point, you really have to question whether the "benefits of C/GObject" are worth the cost:

- It's more complex than C++
- It's more fragile than C++
- It's more difficult to maintain and refactor than C++
- It's slower
- Type bugs are often not found by the compiler because you cast away the type information; this is worked around by runtime checks but even these can fail to work properly, and have a cost since they are done for every method call.
- Memory leaks are common because you're doing all the refcounting by hand

If you wanted to start a new project and had to make the choice between C++ (which is well understood by many) or GObject/GType (which is not, and for good reason because it's awful) there isn't really a choice here at all. I used to be a C zealot who went through the pain of using GObject for OO-C even for non-GTK stuff; but I was deluding myself. C is not the best tool for every job, and it's not good at OO even if it's "technically possible". It's not the best tool for the job, not by a long shot. I ported it all to C++ years back, and found bugs while doing so which hadn't been picked up while using GObject. That is to say, converting it to conventional C++ code improved its quality significantly, and the bugs that I fixed would would not have been found while I continued to use GObject--they were hidden. And once converted to C++, refactoring and adding new functionality became simple; it was a significant burden with C/GObject and it was too easy to introduce subtle bugs since the compiler won't pick up the bugs for you.

Now, the harsh reality is that vala, the language bindings etc. are all various attempts to paper over these unfortunate fundamental shortcomings, while failing to actually address them. Some of them get close, but ultimately it's still built on the same very poor foundations. And you always run into bugs in the bindings, so if you want to do stuff properly you still have to do it in C.

Imagine a commercial project where you need to pitch this to your management for a new project. It's unlikely that GTK+/GObject could be chosen over C++--it would be a risky and irrational choice to make in the face of its many serious shortcomings. (I have done this in the past, before Qt was fully free; we went with GTKmm and still ran into many problems. Lately when evaluating cross-platform toolkits for new projects, Qt and PyQt are at the top of the list and GTK+ isn't even on the list, I'm sad to say.) Hiring or training staff to work on it would be difficult as well; the pool of C++ programmers who already know or could easily pick up Qt is vastly greater than the small number of masochists willing inflict GObject upon themselves (as I once did). It's not like it's even well documented, it's an exercise in pain and frustration. In comparison, the Qt documentation is pretty good.

GTK+ is, and was, driven primarily by "C zealots" (as I once was) who are prepared to use C for everything, come what may. Unfortunately, the reality for the rest of the world is that this is an unsuitable foundation for serious projects. Using GObject requires sacrificing code quality, maintainability and performance, and for most that's not acceptable since it doesn't provide any benefit, other than avoiding C++. It's not benefiting the project themselves.

Regards,
Roger


(Log in to post comments)

Clasen: Introducing GtkInspector

Posted May 18, 2014 16:56 UTC (Sun) by nybble41 (subscriber, #55106) [Link]

As I see it, the problem isn't so much wanting to write programs in C as wanting to to write them in other languages which have good foreign-function interface bindings to C, but not to C++, because *nothing* has good FFI bindings to C++. Calling C functions from Ruby, Java, Haskell, or just about any other language with an FFI is trivial. Binding to C++, with its overloading, templates, etc., is not. Accessing C++ libraries like Qt generally comes down to duplicating the entire public API in C and hoping that you can get by without templates or subclassing.

Exposing a C API for your library isn't just about letting people code in C, it's about letting them code in the language of their choice, most of which (including C++) have C FFIs. If your API is in C++ then using it from any other language will be far more difficult.

Clasen: Introducing GtkInspector

Posted May 18, 2014 19:23 UTC (Sun) by boudewijn (subscriber, #14185) [Link]

In practice, all the perpetual claims how it's so much nicer to create bindings to a C library than it's to a C++ are moot.

In the real world, PyQt and Pyside are perfectly fine to build huge, complicated and succesful applications with.

And that's what counts.

All the rest is bunk.

Clasen: Introducing GtkInspector

Posted May 18, 2014 20:33 UTC (Sun) by rleigh (guest, #14622) [Link]

Technologies like sip (PyQt) and Boost.Python seem quite capable of generating perfectly usable C++ bindings for Python, for example. In fact, with Boost.Python you can write a Qt application that uses python internally which can itself use PyQt to embed in the main UI. (This is currently on my TODO list to trial.)

The number of language bindings has long been touted as a good reason for sticking with C. However, while this might be true in theory, in practice how many of the GTK+ bindings are currently complete and usable? Last time I looked, a number were unmaintained/outdated/incomplete, and a number were only available for GTK+ 2.x and not 3.x. I've not looked recently, but this has been true for most of the life of GTK+, so I wouldn't expect it to have changed dramatically. I've tried a few of the bindings (primarily PyGTK), and I'm afraid to say I always ran into defects (unwrapped functionality or buggy wrappers) which required me to eventually go back to C. So I'm not sure what the number of fully functional bindings is, but I wouldn't be surprised if it's just one or two in practice.

Clasen: Introducing GtkInspector

Posted May 18, 2014 21:46 UTC (Sun) by HelloWorld (guest, #56129) [Link]

GObject has become much better in that regard through GObject Introspection. In fact my impression is that Qt (and QObject-based libraries in general) could really use something like that.

Clasen: Introducing GtkInspector

Posted May 19, 2014 0:48 UTC (Mon) by sandsmark (subscriber, #62172) [Link]

I'm not sure exactly what you're referring to, but are you familiar with QMetaObject?

Clasen: Introducing GtkInspector

Posted May 19, 2014 4:03 UTC (Mon) by tetromino (subscriber, #33846) [Link]

> I'm not sure exactly what you're referring to

GObject introspection generates a description of a GObject-based API from C code comments. The result is output in the form of XML (for ease of parsing) or a binary format (for speed) and is used for automatic language bindings - currently, the main users are vala, python, and javascript. It's much more powerful than the typical ffi setup because it provides not just the C function signature but a vast amount of semantic information. The function's signature would only tell you that argument 1 is a pointer to struct foo, so is the return value, parameter 2 is an integer, and parameter 3 is a function pointer. But GObject introspection would inform you that parameter 1 is an out-parameter in the form of an array of struct foos which must be allocated by the caller (with the number of elements supplied in argument 2) and is filled in by the called function; that parameters 1 and 3 are optional and you can safely pass in NULL if you don't want them; that the return value must not be deallocated by the caller; that parameter 3 is a callback which will be called asynchronously, but only once (at which point resources associated with the callback can be freed); that the function was introduced in library version 1.2, was considered to be unstable API, had been deprecated since 1.16, and in languages which support function overloading, it makes sense to rename it to bar().

Does Qt have some equivalent of this?

Clasen: Introducing GtkInspector

Posted May 19, 2014 8:54 UTC (Mon) by jospoortvliet (subscriber, #33164) [Link]

This has been in Qt forever, from what I understand. See google:
http://stackoverflow.com/questions/19931082/implementing-...
http://woboq.com/blog/how-qt-signals-slots-work.html

And of course, the SMOKE bindings allow writing a GTK hello world app in Qt:
https://blogs.kde.org/2011/07/14/gtk-hello-world-qt-c

;-)

Clasen: Introducing GtkInspector

Posted May 19, 2014 13:19 UTC (Mon) by kigurai (subscriber, #85475) [Link]

But is there anything in place so that this information can actually be used in an automated fashion?

Currently I can start a Python shell and do

>>> from gi.repository import GtkSource

and now I can natively make calls to the GtkSourceView library using a Pythonic interface.
And the same would go for JS, or any language for which a GObject introspection functionality exists.

When I've looked at programming with Qt, I've gotten the impression that all the Python interfaces are "handcrafted" in some sense. But maybe I'm wrong on this.

Still GIR is a really nice concept that I wish was more common.

Clasen: Introducing GtkInspector

Posted May 19, 2014 13:27 UTC (Mon) by sandsmark (subscriber, #62172) [Link]

Language bindings for KDE libraries (and some other libraries, though it was made by KDE and is therefore most popular there) are made by SMOKE/smokegen automatically. It has been around for a while now. It doesn't require you to do anything at runtime though, as it seems like the GObject introspections does?

http://techbase.kde.org/Development/Languages/Smoke

Clasen: Introducing GtkInspector

Posted May 19, 2014 13:59 UTC (Mon) by kigurai (subscriber, #85475) [Link]

Hmm, I could not really make sense of the documentation of that page.
But, to met still seemed like you
1) Have to write a lot of SMOKE specific code, and
2) have to do this for every language binding?

But, as I said, the documentation was not really clear to me.

With GIR, the introspection file is created once for each library, and the GIR mechanism is created once per runtime (Python, JS, ...).
And yes, it means doing things at runtime, but I have not noticed any overhead when using the Python GIR module.
For compiled languages I am guessing you would simply call into the C-library anyway?

C more complex than C++?

Posted May 18, 2014 17:15 UTC (Sun) by riccieri (guest, #94794) [Link]

I always thought that it should be harder to make language bindings for Qt, given that it is C++, and as such it has many more features to be accounted for.

Does all that complexity around GObject/GTK tip the scale in favor of Qt?

Clasen: Introducing GtkInspector

Posted May 18, 2014 18:41 UTC (Sun) by djcb (guest, #41542) [Link]

I use both C and C++.

For the typical API-user, I've found the GLib/Gobject-based libraries of high quality (think GLib itself, GStreamer, json-glib, soup, GDBus), esp. with respect to the ease of using some of the G-niceties such as signals, watching properties for changes (or even binding them).

A hurdle comes when writing your own GObjects; that indeed requires a bit of practice - but it's not /so/ hard either -- not harder than some of the magic in 'modern' C++. There are some niceties in C++ that I miss in C sometimes -- such as some simplified memory management, and the ability to create small helper classes; perhaps lambdas. But overall, I like the clarity, simplicity of C, and I find that it's the most natural way to use the aforementioned libraries. Don't call me a 'zealot' for that!

Anyway, when we go beyond C, I hope one of the next-gen languages becomes a feasible choice (such a D or rust).

Clasen: Introducing GtkInspector

Posted May 18, 2014 21:17 UTC (Sun) by rleigh (guest, #14622) [Link]

I don't disagree with your point that these are high quality libraries. But I would qualify that with "high quality for C". When you compare their quality with C++ equivalents they are sorely lacking. Taking signals for example, the GObject-based signals are quite crude and type-unsafe. If you compare them with libsigc++ or Boost.Signals they aren't even on the same playing field. Likewise for Qt signals, though these are not quite as good due to doing method signature-checking at runtime rather than at compile-time with templates as the others do. And these libraries also allow adapters to add/remove/reorder the signal parameters and return type, so are also much more flexible as well as much more robust. Stuff like g_closure_invoke/g_cclosure_* and all the generated C marshallers are the stuff of nightmares in comparison. Today in C++ you can do stuff like using lambdas for signal handlers; it's a totally different level. (You can use libsigc++ on top of GObject with GLibmm of course, but it's still built on top of the gobject house of cards if you do that.)

Likewise, while for some writing your own GObjects might not be considered "hard", I have to disagree--it's non-obvious and fragile, and isn't properly documented. I wrote a tutorial after figuring it out which was, at the time, only the second source of information on how to do it since it was completely undocumented (http://www.codelibre.net/~rleigh/gtk/ogcalc.pdf). But the "hardness" isn't the only issue. For most people, it's robustness and maintainability. It's also not just about whether *you* can do it, it's whether all the other people on the development team get it as well, plus any future maintainers and potential collaborators. If you can do it, great, but we need to realise that this requires skills beyond what most C and even C++ programmers have--these are not learned language features, but esoteric special stuff which isn't obvious until you invest significant time to figure it all out. To get to that point you need to learn and understand C++, and this does lead to questioning why we aren't just using C++ since by this point the user is perfectly capable of using C++, while they still need to learn the arcane bits of GObject on top of that to start using it, and it will only ever be inferior to doing the same thing in C++. Most potential contributors will find the barrier to entry much lower if using C++ since it's so much more simple and obvious.

class MyWidget : public Widget { … };

is easy; it's C++ 101, right out of the book. But doing the same with GObject is complex and fragile--several pages of boilerplate. Any typos or mistakes and it's broken, leading to crashes or misbehaviour. And keeping the vtables and all the macros up to date with code changes is a manual process; with C++ it's all done and checked for you by the compiler. Think about how much work is needed to refactor the inheritance hierarchy. It's maybe a 1-2 line change in C++, but with GObject you have to change it in numerous places, with nothing to catch any mistakes. In no way is this robust or maintainable! For most teams, doing this is simply not tenable; C++ does all this with compile-time checking, so giving it up for a more complex and fragile solution makes no sense.

By zealot, I really meant it as referring to people who are so single-minded and blinkered about C that they are not prepared to acknowledge that it has any deficiencies or limitations, and that there are situations where other languages serve better. That's been an attitude prevalent in the Linux community since forever, and I don't think it's always healthy (and I admit I was one of these people up until around 2005). GTK+ was kind-of understandable back in 1998 when we were stuck with GCC 2.95 which was still poor for C++ work pre-Standard; since GCC 3.x this hasn't really been true, and today it (and clang++) are absolutely top-notch. If you get to the point in C where you start to think, "hmm, maybe I should use GObject", IMO that's the point where you should be thinking about using C++ instead because that's the point where you're moving outside C's capabilities and sticking with C will lead to a much less robust and maintainable result than C++ (or even Python).

Clasen: Introducing GtkInspector

Posted May 19, 2014 2:29 UTC (Mon) by djcb (guest, #41542) [Link]

Thanks for your insights.

Sure, learning any tool requires a bit of practice (with the exception
of the nipple, I suppose), this is true when writing your own GObjects
just like using, say, std::bind. But nothing that spectacularly
difficult, I think.

I like the C/GObject idiom for the concise and readable client-code it
allows, but I'll happily write C++ when that's a better fit for
the problem I try to solve (even if there's a bit more 'magic'). I
understand personal preferences differ, but you really don't have to
be some irrational reactionary to enjoy writing C code...

I understand that people want to use languages that are a bit more
expressive, but C++ doesn't really fit the bill, I think... looking
forward to some language that can replace both.

Clasen: Introducing GtkInspector

Posted May 20, 2014 0:29 UTC (Tue) by Trelane (subscriber, #56877) [Link]

So you like gtkmm, i take it?

Clasen: Introducing GtkInspector

Posted May 20, 2014 19:56 UTC (Tue) by rleigh (guest, #14622) [Link]

I did like GTKmm. It's clean, well written and documented, and a pleasure to use. It's really what GTK should have been; had this API been the base rather than C, it would have been properly type-safe and robust. And the libsigc++ signals (were) nicer and safer than Qt signals. Probably the nicest C++ language binding I've used.

That said, I ran into minor issues with unwrapped new functionality, and the very occasional bug. Not blockers, just temporary annoyances. But underlying bugs which are still unfixed were rather more serious, like Glade UIs losing all their accelerators when you reparent them into a new window (https://bugzilla.gnome.org/show_bug.cgi?id=129846). Quite a common thing to do if you want all your main UIs as embeddable custom widgets constructed from data rather than code. May be fixed by GTKbuilder, but I haven't tried that; it was still missing some required functionality last time I looked so I stuck with libglademm. These unfixed fairly fundamental things ultimately led to GTK being dropped. Today, there isn't even an upgrade path from .glade to .builder; it was stripped out of glade so you can't even open them. The code will remain using GTK2 GTKmm/libglademm indefinitely; it's not currently worth the expense of a port to GTK3 (it provides zero benefit); it would be less effort to convert from GTKmm directly to Qt should moving from GTK2 be required.

Clasen: Introducing GtkInspector

Posted May 18, 2014 21:27 UTC (Sun) by HelloWorld (guest, #56129) [Link]

> I like the clarity, simplicity of C
C is neither simple nor clear. How many people understand that you need to explicitly cast a pointer to void* when printing it with printf and %p? Who can keep all those silly implicit conversions in their head? How many know what the type of 'a' is? How many C programmers *actually* understand C declaration syntax? Or the silly operator precedences? How many understand what undefined behaviour actually means?

And let's not forget about the gratuitous complexity in user code that is ultimately caused by C's lack of basic features, such as generics or strings, or by its useless and confusing conflation of arrays and pointers, or its lack of orthogonality (it's been known at least since Algol that the distinction between statements and expressions is useless and harmful), or by antifeatures like the preprocessor.

So please, stop spreading this “clarity” and “simplicity” nonsense. By now, we must call C what it is: a really lame, 70ies-era technology that should never have been used outside the kernel in the first place. It should have been shot in the head 25 years ago, and not lauded as an example for clarity and simplicity in 2014.

Clasen: Introducing GtkInspector

Posted May 18, 2014 22:14 UTC (Sun) by brouhaha (subscriber, #1698) [Link]

C combines the power and flexibility of assembly language with the ease of use, reliability, and maintainability of assembly language.

C was a mostly reasonable language for systems programming on a PDP-11 in the 1970s. It's not a reasonable language for much of anything today.

That said, most of my income is from writing C code. :-(

C vs C++

Posted May 19, 2014 8:30 UTC (Mon) by rvfh (subscriber, #31018) [Link]

Ditto. I must use C at work (and then find memory leaks, understand poorly written code, deal with lack of architecture), but I use only C++ at home.

C++ (as most OO languages I suppose) allows a better representation of the problem, and I find that nice C code usually looks like:

blah_init()
void* handle = blah_create()
int rc = blah_do_something(handle, some data)
blah_destroy(handle)

IOW, people have tried to write OO code with a non-OO language. The Linux kernel is full of this kind of things, not even mentioning structures containing function pointers.

So if what people want is to write OO code, I find it easier to do it with a OO language!

C vs C++

Posted May 19, 2014 9:53 UTC (Mon) by ehiggs (subscriber, #90713) [Link]

I'm not sure that everyone agrees that using opaque pointers constitutes an attempt to write OO code in C. There's no polymorphism, or inheritance, or other features more commonly known as making up OO. I think you've just given an example of modular programming and I think we can all agree that this is a good approach for a lot of code.

As far as C++ providing a better representation of the problem, it certainly can. However, in your example writing C code in the manner you've shown has less boiler plate than trying to use the pimpl pattern in C++. In the pimpl pattern class definitions are basically doubled, functions have to jump through a proxy.

C vs C++

Posted May 19, 2014 16:27 UTC (Mon) by zlynx (subscriber, #2285) [Link]

Not necessarily. If you are happy having your functions reference data through the pImpl pointer you just have one set of functions and the private data is in the impl struct. You do always need duplicate constructors though, which is annoying.

C vs C++

Posted May 19, 2014 20:28 UTC (Mon) by MrWim (subscriber, #47432) [Link]

I usually prefer to use abstract base classes for data hiding. There is a runtime cost but that is rarely significant. It cuts down on the duplication you usually incur with pImpl and you often want an abstract base class anyway to enable mocking.

Obviously this doesn't apply to value types, but nor does pImpl usually either.

C vs C++

Posted May 20, 2014 7:59 UTC (Tue) by rvfh (subscriber, #31018) [Link]

How do abstract classes solve the issue of 'I want all my private stuff in the cpp file', hidden from view?

C vs C++

Posted May 20, 2014 11:14 UTC (Tue) by MrWim (subscriber, #47432) [Link]

Like this:

Foo.h:
class Foo : boost::noncopyable
{
public:
    virtual ~Foo();
    virtual void frob() = 0;
    virtual void frell() = 0;
};

std::shared_ptr<Foo> makeFoo(int some, const std::string& args);

Foo.cpp:

#include "Foo.h"

// Force RTTI information out here so it's not spammed all over the place
Foo::~Foo()
{
}

namespace { // Anon namespace, all symbols confined to this translation unit

struct ConcreteFoo : public Foo
{
    ConcreteFoo() {}
    virtual void frob() {
        printf("frob!\n");
    };
    virtual void frell() {
        printf("frell!\n");
    }
};

std::shared_ptr<Foo> makeFoo(int some, const std::string& args)
{
    return std::make_shared<ConcreteFoo>();
}

It's nice because there is the same number of repetitions of method names as if you were just following the usual pattern of declaration in header file, implementation in cpp file. Also, because it's not a value type, you are likely to be holding it by pointer anyway. If Foo were a pImpl instead you would be dealing with a pointer to a pImpl class which is essentially a pointer anyway.

You can also do things like force management by shared_ptr by changing the factory function. You don't need to faf around with making make_shared a friend or having friend factory functions or anything like that.

Another nice aspect is that you don't need to use private: anywhere. The fact that all the code is in the cpp file offers stronger encapsulation than private:.

The one down-side I'm aware of is that it makes it a little tricker to write white-box tests of the implementation details of the class. The solution I've used in the past is to just #include "Foo.cpp" into my tests. Mostly I prefer black-box testing anyway though so it's not a big deal.

C vs C++

Posted May 20, 2014 14:26 UTC (Tue) by mathstuf (subscriber, #69389) [Link]

How do you deal with friend classes in this case? "private: friend ...;"? My example is a "pool" being able to have extra access to the objects in it basically to tell the objects information only it could know.

My problem with it is that now you force shared_ptr on it. What if I want a unique_ptr?

C vs C++

Posted May 20, 2014 18:24 UTC (Tue) by MrWim (subscriber, #47432) [Link]

How do you deal with friend classes in this case? "private: friend ...;"? My example is a "pool" being able to have extra access to the objects in it basically to tell the objects information only it could know.
I'm not sure I understand what you're describing, but one way would be to define the pool and the objects in the same cpp file where they can be aware of each other. No friends required ;). Ultimately this technique isn't a panacea and you can apply it where it works and don't where it doesn't. It just seems to me that it's superior to pImpl for most use-cases but seems to be under-used as a technique (unlike pImpl).
My problem with it is that now you force shared_ptr on it. What if I want a unique_ptr?
That was just an example of something that is convenient to do with this approach. Of course if you want a unique_ptr then return a unique_ptr.

C vs C++

Posted May 20, 2014 18:30 UTC (Tue) by mathstuf (subscriber, #69389) [Link]

> I'm not sure I understand what you're describing, but one way would be to define the pool and the objects in the same cpp file where they can be aware of each other.

These are the two largest source files in the repo already :) . There are actually a few things in that class[1] that break pImpl cleanliness anyways: templates which call a private method.

Basically, only the 'pipeline' class knows what the "core frequency" is, so it is locked down to be private and not exported from the library to protect it.

[1]https://github.com/Kitware/sprokit/blob/master/src/sproki...

C vs C++

Posted May 20, 2014 16:53 UTC (Tue) by ehiggs (subscriber, #90713) [Link]

Thanks for sharing this. It's not too bad but I am surprised we would want to have makeFoo return a shared pointer. Why not make it return a raw pointer so the user can determine how to package it? Is this a common practice you see in C++ was just this part of a throwaway example?

Thanks

C vs C++

Posted May 20, 2014 17:49 UTC (Tue) by mathstuf (subscriber, #69389) [Link]

Depends on how opinionated the library is. Ownership tracking of pointers is still a pain in C++ (which Rust finally addresses). Forcing shared_ptr avoids ownership problems at the cost of a reference count (not the worst thing). I just think that unique_ptr should also be an option here at least.

C vs C++

Posted May 20, 2014 17:55 UTC (Tue) by MrWim (subscriber, #47432) [Link]

It's just an example of something that is hard(er) to do otherwise as it can require faffing about with friend classes/functions. As you say, when there's no reason to return a shared_ptr don't. A unique_ptr or an auto_ptr would be just as good in this example, or if you have an aversion to them a raw pointer would also work.

You could even expose a size variable and a placement new factory function for ultimate flexibility, allowing even stack allocation of these objects, but this would almost certainly be over the top.

C vs C++

Posted May 20, 2014 19:22 UTC (Tue) by JGR (subscriber, #93631) [Link]

auto_ptr has nasty and unhelpful copy behaviour which led to it being deprecated, it should be avoided if at all possible IMO.

unique_ptr is generally the most convenient choice; constructing one has zero cost over just returning a pointer to an allocation with new. It's trivial to then move it to a different smart pointer/whatever as necessary, which is much more of a pain with a shared_pointer. Destructing a shared_ptr also uses atomic operations, which is surprisingly expensive.

If you need that level of allocation flexibility and always return a fixed number of (non-polymorphic) object(s), it's usually simpler to just require that the caller pass in a non-const reference to an existing object to fill in.
For the case of 1 object, you could also use a member function or constructor.

C vs C++

Posted May 21, 2014 14:58 UTC (Wed) by mathstuf (subscriber, #69389) [Link]

Well, the problem with unique_ptr is that you need move constructors for it to be fully useful. And that requires C++11 or using boost::move explicitly. Unfortunately, the list of platforms I need to support limit me to shared_ptr since decorating everything with boost::move would likely cause more bugs when it is forgotten.

C vs C++

Posted May 21, 2014 21:07 UTC (Wed) by jwakely (guest, #60262) [Link]

Returning a unique_ptr is better than a raw pointer - it's safe-by-default and also explicit that there is ownership transfer going on. Returning a raw pointer has no advantage over unique_ptr.

If you want to take ownership from a unique_ptr and get a raw pointer that you own it's easy, call release(). You can't do that with a shared_ptr as there could be other owners and there's no way to force them to release their reference.

Clasen: Introducing GtkInspector

Posted May 19, 2014 12:16 UTC (Mon) by etienne (guest, #25256) [Link]

> C combines the power and flexibility of assembly language

Sometimes I wish we had a language at a lower level than C, something generic enough it does not define the number of bits of different types (nor their name), do not intrinsically define if a variable has a pointer to its type description, do not define what is a function or how to call them, do not define operator priority, do not define reserved names, but has the syntax to build that "sugar" by writing the source code for it - something a lot more like an interface to the assembler.

So that you could, at compile time, do:
#include <c++11.h> to write in that language, or:
#include <opencl.h> to write in that other language, or even:
#include <ada.h> or #include <java.h> at the beginning of the file.

Supporting without hacks common languages would be the first step, then you could extend it to support your own needs: multiple types of address pointers, functions which parameter types depends on parameter values, functions only visible on some conditions, your own memory allocation strategy, pre/post conditions...

That should also simplify inter-language calls.

Unfortunately I am not a good enough "computer language grammar" specialist to begin to describe it...

Clasen: Introducing GtkInspector

Posted May 19, 2014 14:03 UTC (Mon) by mathstuf (subscriber, #69389) [Link]

Ick. Could we at least kill the #include monstrosities (and the preprocessor in general). Modules have clearly been shown to be better by this time, haven't they?

Also, what you ask for sounds like lisp without parentheses…maybe indentation-aware like Python?

Sounds like what PL/1 was intended to be ...

Posted May 19, 2014 21:31 UTC (Mon) by Wol (guest, #4433) [Link]

In other words, Lisp with even more parentheses :-)

PL/1 is notorious for misplaced parentheses causing subtle bugs - the resulting code usually compiles but means something completely different from what was intended.

But it had a bunch of useful features like integer declarations typically declared the number of bits (and if you were nasty you could declare INT*10(3) which would declare three ten bit integers (and fit them into a 32-bit word, causing the run-time absolute conniptions as it tried to sort out the mess!! :-) Adding the key word ALIGNED iirc would then force them onto word boundaries, so it would probably - too long ago I can't remember - fit each INT*10 into a 16- or 32-bit word.

It was extremely useful in some respects, because you could - EASILY - choose between forcing the data layout how you wanted it, or letting the compiler decide what it wanted. Great for creating data files that could be passed between different computer architectures (until of course you hit big/little endian - things like the ICL 36-bit word were childs play :-)

Cheers,
Wol


Copyright © 2017, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds