[Xcb] Hello xcblist.

Thomas Heller thom.heller at googlemail.com
Tue Feb 9 00:02:32 PST 2010


On Tue, Feb 9, 2010 at 6:37 AM, Jamey Sharp <jamey at minilop.net> wrote:
> Thanks for the explanation, Thomas! I have some follow-up questions.
>
> On Thu, Feb 4, 2010 at 10:53 PM, Thomas Heller
> <thom.heller at googlemail.com> wrote:
>> On Thu, Feb 4, 2010 at 10:15 PM, Barton C Massey <bart at cs.pdx.edu> wrote:
>>> What motivated you to write C++ bindings for XCB---what did
>>> you find deficient in the existing C binding?
>>
>> After browsing a little more through xcbs code I disliked several
>> things:
>>  - all the casting of pointers from one type to another type. I
>>    understand that this is common C practice but i believe
>>    such things don't belong into a modern C++ Application
>
> Do you have an example of what bothered you? I see these cases:
>
> - Some external API, like struct sockaddr, forces us to cast pointers.
>  Nothing to be done about it, or at least C++ doesn't help.

I fully agree, C++ doesn't help here. Unfortunately the socket API
is broken with respect to the C++ standard. And one has to depend on
compiler extensions (currently it is not a problem with gcc). See my
explanation below why this is broken.


> - Internally, we access buffers through pointers of different sizes at
>  different times. Using the same pointer type in all cases would
>  complicate the code considerably, making it less efficient and harder
>  to understand and maintain. Again, I think C++ doesn't help.

That is exactly what i meant. I am fully aware that this is the only way in
C to handle such things. Unfortunately in C++, these casts are a little bit
problematic and not guaranteed to work. C++ has stricter requirements on
layout compatible types for this kind of casts than C does. This is
the reason why
the socket API is broken for C++. And this is the reason why i dislike
these casts.
I am fully aware that this sounds a little bit nitpicking as it does
not have a real impact
on existing libraries/programs.

> - Response types can't be distinguished at compile time, so we cast once
>  we've discovered the correct run-time type to use. I agree that this
>  is unfortunate, and worse, it leaks into the public API a bit. But I
>  don't see a way to fix this using C++ that both is efficient and
>  doesn't limit the binding's support for extensions.

Same as above. However I think i found a reasonable solution for this
kind of problem.

>
>>  - through your naming scheme inside of libxcb you implicitly
>>    introduce namespaces (with all the prefixes),
>
> Yes, that's the C idiom corresponding to C++'s namespace feature. Why
> is that a problem?

It is not a real problem. It is just a matter of taste. For example, with C++
namespaces i can type less by using a namespace in a specific code region.

>>  - you work with lists and iterators.
>> ... the lists and the iterators come for free by using the stdlib.
>
> I'm skeptical that you'll get much "for free". :-) The visible API
> presents iterators; the internal implementation, in unrelated places,
> uses linked lists.
>
> Iterating over the variable-length structures of the X protocol is a
> little bit tricky in any language. Certainly you'll get useful
> algorithms and such that you can use with the iterators, once you've
> wrapped them up in C++-style, but I don't see that the standard library
> will help you at all in constructing iterators in the first place.

In my current approach, the variable-length structures are in a std::vector
which provides a iterator over its elements basically for free.
Again, I think this is just a matter of taste, the public XCB provides almost
the same interface.

> Yes, the internal implementation of XCB uses linked lists heavily, and
> C++ templates mean you can have an inefficient but type-safe generic
> list that would abstract away a little bit of XCB's code. Is that what
> you meant? I'd rather have the purpose-built list implementations.

Yes that is more or less what i mean. However I doubt that the list
implementation in the C++ standard library is less efficient than your
implementation. Templates have no impact on runtime.

[snip]

>> Nevertheless I believe by providing a completely native language
>> binding (not just a wrapper) you can use the specific features of your
>> language (which you believe are superior to C, otherwise you wouldn't
>> program in that language ;)) and don't have to care about the legacy
>> code you try to wrap.
>
> It seems to me that any language binding should enable use of that
> language's features even if it is wrapping code written in another
> language. Sometimes that means improving XCB, as in the recent
> discussion about adding xcb_discard_reply for the benefit of
> garbage-collected languages, among other reasons.
>
> More importantly: as Bart wrote, wrapping XCB's C API "is generally
> preferred; it allows target-language applications to freely mix FFI
> calls to libraries that indirectly talk to XCB with direct XCB calls."
> Put another way, anyone wanting to use your pure C++ library has to
> completely re-write their program and any X-related libraries it uses,
> such as Xlib, cairo, Gtk+, Qt...

Sure, a rewrite would be necessary. However, it would also be necessary
if I provide a C++ wrapper. I would like to target new written libraries.
I would like to reconsider the topic about wrapping the libxcb code vs writing
a new language binding from scratch:
The first things that come to my mind is certainly that the new
language binding does
not have to consider all the infrastructure code which takes care of
correctly sending
and receiving all the protocol related data. This is, in my opinion,
the biggest advantage.
All the other stuff like wrapping all the data structures into
something which can be used
in a way it is considered best practice in that new target language
has yet to be done.
And i believe that when wrapping a C library you have certain
constraints on how you implement
your wrapper so you don't have too much impact on performance and/or
usability. So this would
mean you can not take full advantage of all your neat language
features (as the example with the
garbage-collected languages shows).

So I believe by writing a new language binding you have to consider two facts:
 1) Is it worth writing all the infrastructure once again?
 2) Can i take full potential of all my neat language by "just"
writing a wrapper

In my case: I have answered 1) with yes since there exists a library
which takes care of asynchronous
reads and writes to a socket in a very neat way, which i believe was
the main effort behind libxcb.
Correct me if i am wrong.
Regarding point 2): It does not make a real difference if i write a
wrapper or not.

> Frankly, I suspect that would be a death sentence for any C++ binding.
> Programmers in some other languages are used to doing that kind of
> rewrite all the time, but C++ programmers expect to be able to drop any
> existing C library into their projects.

I don't have an opinion on that ...

>> On advantage my parsers has over the python generator: It can detect
>> an error if the given xml doesn't fulfill the "xcb language" defined
>> in xcb.xsd.
>
> I like schema validation. Which is why the 'make check' target in
> xcb-proto validates everything there. Validating in each consumer isn't
> a bad idea at all, but isn't really necessary either.
>
> Good luck on your exams!
Thanks!

As a last point: My motivation for writing these bindings was to get in contact
with X. I am currently not very experienced with all this stuff so the
possibilities are
very high that i totally missed everything important :)

Thomas


More information about the Xcb mailing list