Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I like the idea of Haiku OS, but from what I've heard, for binary-compatibility reasons (kernel drivers? All applications? I'm not sure) it still ships with GCC 2.95.

Requiring a compiler over a decade old for a modern OS doesn't seem like a good long-term strategy.



Haiku can be built with/for GCC 2 or GCC 4 and ship with libraries for the other. Some time after R1, the gcc2-hybrid releases will probably be flipped to gcc4-hybrid, and the gcc2 libs kept around for backwards-compatibility purposes only.

The current setup is really only used to the benefit of applications - the kernel interface is not ABI- or API-compatible, for the most part, with that of BeOS R5.


Haiku now uses a hybrid system so that it can support GCC 2 applications while using GCC 4.

http://www.haiku-os.org/news/2008-05-18/steady_progress_towa...


IIRC one of the reasons Apple passed on BeOS was that the lack of a stable C++ ABI made app dependencies on the OS classes very fragile. For example, API classes had to be padded out with dummy members to make room for later non-breaking additions to apps.

Is this still a problem? Isn't this why just about every other OS exposes it's lowest level APIs as C apis?


If the Apple story is indeed true, there's a certain irony to it: device drivers in the OS X/iOS kernel are written against a C++ API called I/O Kit. For forward-compatibility with newer kernel versions, all the public classes contain a significant number of dummy virtual functions, and many also have a pointer member variable called "reserved" so they can later add new fields if they need to without changing the class size.

E.g.: http://www.opensource.apple.com/source/xnu/xnu-1699.24.23/io... - note the

  ExpansionData * reserved;
member variable and the block of

  private:
    OSMetaClassDeclareReservedUsed(IOMemoryDescriptor, 0);
  #ifdef __LP64__
    OSMetaClassDeclareReservedUnused(IOMemoryDescriptor, 1);
    OSMetaClassDeclareReservedUnused(IOMemoryDescriptor, 2);
    OSMetaClassDeclareReservedUnused(IOMemoryDescriptor, 3);
    OSMetaClassDeclareReservedUnused(IOMemoryDescriptor, 4);
    OSMetaClassDeclareReservedUnused(IOMemoryDescriptor, 5);
    OSMetaClassDeclareReservedUnused(IOMemoryDescriptor, 6);
    OSMetaClassDeclareReservedUnused(IOMemoryDescriptor, 7);
  #else /* !__LP64__ */
    OSMetaClassDeclareReservedUsed(IOMemoryDescriptor, 1);
    OSMetaClassDeclareReservedUsed(IOMemoryDescriptor, 2);
    OSMetaClassDeclareReservedUsed(IOMemoryDescriptor, 3);
    OSMetaClassDeclareReservedUsed(IOMemoryDescriptor, 4);
    OSMetaClassDeclareReservedUsed(IOMemoryDescriptor, 5);
    OSMetaClassDeclareReservedUsed(IOMemoryDescriptor, 6);
    OSMetaClassDeclareReservedUsed(IOMemoryDescriptor, 7);
  #endif /* !__LP64__ */
    OSMetaClassDeclareReservedUnused(IOMemoryDescriptor, 8);
    OSMetaClassDeclareReservedUnused(IOMemoryDescriptor, 9);
    OSMetaClassDeclareReservedUnused(IOMemoryDescriptor, 10);
    OSMetaClassDeclareReservedUnused(IOMemoryDescriptor, 11);
    OSMetaClassDeclareReservedUnused(IOMemoryDescriptor, 12);
    OSMetaClassDeclareReservedUnused(IOMemoryDescriptor, 13);
    OSMetaClassDeclareReservedUnused(IOMemoryDescriptor, 14);
    OSMetaClassDeclareReservedUnused(IOMemoryDescriptor, 15);
dummy methods.

There is also a system in place for the linker to patch the vtables of dynamically loaded classes (i.e. third-party drivers). They've also built an Objective-C-like Class/metaclass system in C++ via macros for I/O Kit, for some very basic reflection (mainly to keep track of whether instances of a class exist, and if not, unloading the kernel module).


I never heard this story before.

Mac OS X drivers are written in C++.

Symbian is fully written in C++.

The new WinRT API for Windows 8 is C++ based along as the user space driver framework.

There is no reason why Apple could not have defined a standard C++ ABI in BeOS, if that was the reason.

The decision to take NeXT instead of BeOS, surely did not have anything to do with technical merits of the underlying systems.


I think it's not so much the problem of an ABI but the fact that changing base classes in C++ forces client code to be recompiled because offsets of members and vtable entries change:

http://haiku-os.org/legacy-docs/benewsletter/Issue2-25.html

Apparently Apple gets around this the usual way by padding out their API classes with extra unused members. I wonder what the solution is in Windows 8 & Symbian.


WinRT gets around it because it doesn't really export C++ the way you're thinking. What it exports are basically COM objects with a bunch of extra CLR-style metadata.

COM avoids the C++ issue because it only allows you to consume interfaces, and, for all Windows compilers when COM was invented (and obviously since), vtables are always in a set location. So the trick is:

  1.  Never change existing interfaces
  2.  Always add new interfaces to the end of the vtables
When you want a COM object, you instantiate it, but you don't work with it directly; you ask for the interface you want to use to talk to the object. As long as the object vendor maintains the old virtual methods, the worst that happens is you ask for the old interface and everything works as normal. This works very well with only a minor speed hit.

I think right after //build, I could tell you how they used CLR metadata to extend the system out to supporting subclassing, but I just honestly don't remember. Similar general idea, though; they still avoid the problem by not actually hitting it.


Yeah, I left that a bit in the air.

One can see COM as a kind of operating system OO ABI.

OS/2 SOM was better, but never got much following.


The problem is not C++ specific.

Any OO language with native code generation suffers the same problem.

It is one of the consequences of the fragile base class problem in OO.


Objective-C 64bit ABI doesn't have fragile base classes; there's an extra layer of indirection to access any data member of an object.

And it actually has private data members! Isn't that nice.

(Private meaning they aren't declared in the public headers, not meaning it uses the useless 'private' attribute.)


Yes it does, as any OO language does.

This is not only about data member access. It also applies to adding methods on the base class that change the behavior of existing methods in already declared subclasses.

Take a cup of coffee and read this famous paper about the issue,

http://www.cas.mcmaster.ca/~emil/Publications_files/Mikhajlo...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: