On 20/01/2012, at 2:07 AM, Chuck Remes wrote: >> >> Of course I *could* return it. But it seems wrong. > > Why is it wrong to bubble up an error code to the caller? You are going to > have the same issue with nearly every other zmq_*() function that returns an > error code, right?
Not quite. Consider C++ instead of Felix: zmq_msg_init is a default constructor. Constructors cannot return values. Additionally default constructors, are not called by the user, they're called by the system. So no, you cannot bubble up the error code to the caller. This applies to destructors in C++ too. The situation there is very nasty, since throwing an exception is extremely bad. It's even worse in Ocaml, where the destructor has to be called by the garbage collector, asynchronously. In Felix, initialisation is not enforced by the language, but I want to enforce it anyhow. Beats debugging core dumps and memory corruptions :) In Felix, uncopyable objects are not permitted. zmq_msg_t is uncopyable so I cannot put it into Felix directly. Instead, it is heap allocated, and Felix manipulates a pointer (which is copyable). The allocation is done in by calling "new zmq_msg_t" (C++ code!). So .. there's no way to return an error code. "new" returns a pointer. [In Felix it cannot be null] So that's roughly why I suggest changing the interface and semantics. your point about the implementation changing down the track is right on the mark: I want to ensure that it cannot be changed in such a way that an error code might have to be returned. I want to prevent that, because that constraint is necessary to use the function in a default constructor. FYI: Felix is a C++ code generator. Also, Felix does not support exceptions. So if a default constructor throws an exception it will terminate the program. In C++ you might suggest throwing an exception, because it can be caught and managed before your online 0MQ based network crashes: in Felix that's not an option. Sure .. I can wrap the constructor in a function that catches the exception .. but then what do I do with it? Back where we started. The only solution is that there be an initialiser that can't fail, that's called every time. Which also means the other initialisers (size, data) have to be permitted to initialise a default initialised object, otherwise you'd have to call close first, before applying them. -- john skaller [email protected] _______________________________________________ zeromq-dev mailing list [email protected] http://lists.zeromq.org/mailman/listinfo/zeromq-dev
