v

Advantages of C over C++

It has been claimed that C++ is a better C them C. this is being taken to mean that when switching to C++ you can continue to code more or less as she did in C and use a little extra C++ functionality for convenience. The problem with that is that a lot of things which are perfectly safe to do and see are not safe to do while using C++.

So here is my list of issues not found in C. You can avoid many of these issues in C++ by limiting what features you use. But you never have any guarantees. You can't pick up random C++ code, look at it and be certain whether it is doing something safe or not when e.g. statically initializing a variable.


  • Static initialize is safe in C but not in C++, because in C++ static initialization can cause code to run, which depends on other variables having been statically initialized. It can also cause cleanup code to run at shutdown which you can't control sequence of (destructors).


  • C gives you better control over what happens when your code is executed. When reading seek out it is fairly straightforward to decipher one code is getting executed and when memory is just restart or primitive operations are performed.
    In C++ on the other hand your have to deal with several potential problems:

    • A simple variable definition can cause code to run (constructors and instructors)

    • Implicitly generated and called functions. If you didn't define constructors, destructors and operator= you will get them generated for you.


    See hidden cost of C++ or Defective C++


  • C supports variable sized arrays on the stack. Which is much faster to allocate than on the heap. (C99 feature)


  • No name mangling. If you intend to read generated assembly code, this makes that much easier. It can be useful when trying to optimize code.


  • De facto standard application binary interface (ABI). Code produced by different compilers can easily be combined.


  • Much easier to interface with other languages. A lot of languages will let you call C functions directly. Binding to a C++ library is usually a much more elaborate job.


  • Compiling C programs is faster than compiling C++ programs, because parsing C is much easier than parsing C++.


  • Varargs cannot safely be used in C++. They're not entirely safe in in C either. However they're much more so in the C++, to the point that they are prohibited in the C++ coding standards (Sutter, Alexandrescu).


  • C requires less runtime support. Makes it more suitable for low-level environments such as embedded systems or OS components.


  • Standard way in C to do encapsulation is to forward declare a struct and only allow access to its data through functions. This method also creates compile time encapsulation. Compile time encapsulation allows us to change the data structures members without recompilation of client code (other code using our interface). The standard way of doing encapsulation C++ on the other hand (using classes) requires recompilation of client code when adding or removing private member variables.



Disliking C++ is not a fringe thing. It does not mean that one is not capable of understanding complex languages. Quite a lot of respect computer science people and language designers aren't fond of C++. See C++ coders

Grand Central Dispatch versus Qt Concurrent

Lately we have been provided with several different solutions to how we can utilize multicore CPUs. Previously we had few other options besides creating multithreaded applications explicitly. By explicitly I mean the developer had to create and manage threats manually.



Both Grand Central dispatch and Qt Concurrent is based on the idea that the developer submits chunks of work to a library which will distribute the chunks of work onto several different threads which can be running on several different cores.



Below is a code example showing Qt's approach to distributing chunks of work to different threads. To use the right terminology each chunk of work is called a task. The code below shows how a strain is split by running the splitting method in a separate thread.


// call 'QStringList QString::split(const QString &sep,

//                                  SplitBehavior behavior,

//                                  Qt::CaseSensitivity cs) const'

// in a separate thread

QString str = "comma, separated, text";

QFuture<QStringList> future = QtConcurrent::run(str,

                                               &QString::split,

                                               QString(", "),

                                               QString::KeepEmptyParts,

                                               Qt::CaseSensitive);

// Do some more processing

cout << "str may or may not have been split at this point" << endl;

QStringList result = future.result();



// Output split elements on new lines

foreach (QString s, result)

  cout << s << endl;

Future objects


Run, is an asynchronous call. It will hand over its task to a separate thread, return and continue execution of the main thread. Qt uses the concept of a future object to store results from asynchronous method calls. The QFuture object won't actually contain the results of this split method until it's queried for the results. It's a separate thread has finished processing one the future objects is queried it simply returns the results. If it hasn't, the main thread will be blocked until separate thread finishes.



The next piece of code shows Grand Central's approach to the same problem. Instead of using future objects, to synchronize between different threads, Grand Central uses so called dispatch queues. the developer submits tasks to different queues, then Grand Central will dequeue the tasks and place them on to different threads. Tasks in different queues always run concurrently with respect to each other. However task within the same queue might or might not run concurrently with each other, depending on the type of queue. There are two types of cues: serial cues and concurrent queues. In a serial queue a task is not performed until the previously enqueued task has been performed. In the code below we create a serial queue.



// Creates a serial queue for tasks, where the next

// task is performed when the previous  is finished

dispatch_queue_t my_queue;

my_queue = dispatch_queue_create("my queue", NULL);



QString str = "comma, separated, text";

__block QStringList result;

dispatch_async(my_queue, ^{

  result = str.split(", ", QString::KeepEmptyParts, Qt::CaseSensitive);

});

  



// Do some more processing

cout << "str may or may not have been split at this point" << endl;



dispatch_sync(my_queue, ^{

  // Output split elements on new lines

  foreach (QString s, result)

    cout << s << endl;

});

Code blocks


In Grand Central dispatch a task is represented by a code block. Code blocks is an extension by Apple to the C-language and C++. In languages like Ruby and Python code blocks are referred to as closures. Essentially they let you define a function within another function. This function has access to all variables defined outside its scope and any variable referred to in the code block will continue to live even after the outer scope no longer exists. But only as read-only variables. If you want to write to a variable outside the scope of the block, then you have to prefix variable with __block.



Asynchronous dispatch



dispatch_async() is similar to the run method in Qt. The provided code block is passed on to a separate thread amber function call returns immediately to the main thread. The code splitting the string will run in parallel to all the code it follows after the asynchronous dispatch. But since we don't have a future object, how can we safely read the results variable in the main thread? Normally one would have solved for these kind of thread issues with semaphores.



Synchronous dispatch



There are two ways to read the result variable safely. One can dispatch a task either asynchronous or synchronous to the same queue, which reads the result variable. Since the queue we have created is a serial queue, the reading task would not be executed until all previously and queued tasks have been finished. In this case we have chosen to call dispatch_sync(). It will block the main thread until a submitted task has been executed. Thus, in this case we know that after the dispatch_sync() call the only running thread is the main thread.



Conclusions



The metaphor used by queue might seem simpler to understand and deal with, but it trades and simplicity for flexibility. The biggest problem is that there is no obvious way to control access to shared resources without using semaphores. With Grand Central's approach one can take code that used to be in a critical section, plays in a code block and do a dispatch to a queue. Instead of protecting the access in to share resource with the same semaphore, one can protect the access by submitting tasks to the same serial queue. This will make sure that all code that accesses a share resource does so in strict sequence. This is a clear benefit over using semaphores, because with semaphores one does not know in which sequence the threads access a shared resource.

C++ is a horrible language

Over the years my dislike of C++ has increased. It seems like the more I know about language the more I dislike it. I believe that Linus Torvalds summed it up pretty well when he said:




IOW, C++ is in that inconvenient spot where it doesn’t help make things

simple enough to be truly usable for prototyping or simple GUI

programming, and yet isn’t the lean system programming language that C is

that actively encourags you to use simple and direct constructs




This comment is from the now infamous git mailing list, where Linus Torvalds details why you think C++ is a horrible language. I think the problem for most people dispute this point is that they don’t get what latest means when he says that C++ is a horrible language. For creating higher-level abstractions and large programs C++ is obviously better. But that is a silly way to compare the two languages. For what C. has been designed for does his job very well. It allows you to write low-level and high-performance code. C++ on the other hand is a jack of all trades and master of none.



The classic rebuttal of this from C++ fans, is that C++ can do everything that C. can do, so there’s no need to use C. But this is simply not true. A C programmer can read a statement and know fairly well how many objects are allocated on the heap or on the stack and know how many function calls are performed. This is almost impossible in C++. Due to the existence of constructors, descriptors and operator overloading a wise things can happen in the simplest statements.



In theory you can write C++ code which has higher performance than corresponding C code. However since C++ gives you less control over what happens in each statement, there is a higher chance that you doing something which kills performance then in C.



The other classic statement from C++ fans is that:




you can just use the subset of the language which you are comfortable with.




However even a small subset of C++ requires that you understand quirky attributes of the language. For instance, I would argue that using statically initialized variables is nothing fancy. You can do this easily in C. However in C++ this require a lot more care. Unlike C declaring static variables in C++ can cause code to run during initialization. Typically this will be the code for the constructors of the objects statically initialized. You cannot control in which sequence this code is executed. This can cause very hard to find bugs.



This is just one of many examples. You can just read Scott Meyers book Effective C++ to find a long list of stuff you have to be aware of C++ to not shoot yourself in the foot. There are loads of books like this for C++. I do not know of any comparable books for the C-language.



The C-language is in no way perfect, but I simply don’t get why the deficiencies of C, should be remedied by using C++. If you need higher level abstractions or a more type safe language why not use other languages like OCaml, Haskell, LISP or Python? Say you select Python. It is not as high performance as C++, but in the places where you need performance she could implement the functionality in C-language. There is no need to use C++, because you’re not writing a large program where you need to be able to build abstractions. You are building a simple module, where advanced abstractions are not needed.



People will point to libraries like Qt as proof that you can write easy to understand code in C++. I however think it’s proof of the opposite. Not because I think Qt is bad. Quite the contrary is one of the better GUI toolkits out there. However that is not because C++ is a great language but because they essentially invented their own language by adding a preprocessor. It’s not that different from how Objective-C was originally made by adding a preprocessor to the C-language. In C++ was such a versatile and flexible language as some claim, there would never have been a need for the moc preprocessor.



I am not saying this as C developer who has just started dabbling in C++. I’ve been doing C++ all my professional life. I never used C very much at all. The realizations have just dawned upon me while working several years on large software projects in C++. Very little of our time is spent on writing performance critical code. In fact most of it is some sort of glue code. Code to make different components talk to each other and tell each other about changes that have just happened to them. All stuff that a script language like Python would have done much better.

On old and new in the Computer Science

I remember several years ago in undergrad listening to my old professor. He would always jabber on about LISP. Back then I remember thinking, gee give it a break man, the language is what? 50 years old? Isn't it time to move on?



These last weeks I have finally been able to play around with a dialect of LISP called PLT Scheme. It got triggered by reading the so called Wizard book: "Structure and Interpretation of Computer Programs"



I must say I am very impressed with Scheme. I am still not sure if I could ever be fully comfortable with the language because of all the annoying parenthesis. But the power and flexibility of the language is mind-boggling. And there is something beautiful about that ultra simple syntax. Everything is just words separated by spaces and enclosed by parenthesis. That is all there is to it!



Compare that to the extremely complicated syntax in C++.



I have realized that thinking that new is always better than old is the dumbest belief I ever had. Sometimes new stuff is old already at the instance it is made, while old stuff is modern 20 years later.



An example of this is the code base of our program at work. A lot of the code is crap and badly thought out. At first I assumed it was the old code that was bad. Then I realized that in fact the old stuff is what was fairly good and the crap was mostly new stuff.



The stuff is a maintenance nightmare because nothing is commented. I talked to a guy who talked about a system he worked on that was from the 50s or 60s or something. The New York subway system I believe. I asked if that wasn't hard to do given that the original makers were probably not around anymore. But it wasn't because as he explained for each source code file there was a corresponding document file explaining that source code file in detail. It was all very well documented.



I wonder how could they get software design right 50 years ago and we manage to screw it up today?



Same with LISP, mainstream languages are only now starting to get some of the more important LISP features. How could they get it right that long time ago, and we mange to screw it up today with languages such as C++ and Java?



I increasingly realize that languages like C++, Java , C# etc seldom offer anything new. They are just the same shit in new wrapping. New wrapping in this case means new syntax.



But perhaps the biggest eye opener with respect to the value of old stuff, is when I read Adam Smiths the Wealth of Nations. It is something like 250 years old. I had read other new books about economic history and theories for this and that about the historical economic development of China, Africa etc. Surprisingly I found Smith treatment of the same much clearer, well reasoned and thought out. In short he offered a much better explanation than these newer books. But this isn't the first time. People like Ricardo and other economist have come after Smith and presumable proved him wrong only to have later economist discover that Smith was right all along.



Perhaps talking of old and new as if it corresponded to bad and good is about as stupid as saying that derivation and integration is bad because now we have newer mathematical methods. A good idea is a good idea no matter how old it gets.

Why Objective-C is cool

I've been asked to do an intro about Cocoa. So I thought about what would I tell people about Cocoa if I had some time. Sure I could throw up a quick tutorial on how to code a Cocoa app showing a bare minimum of how Objective-C works. But there are a million of tutorials like that and it doesn't really do the Cocoa justice. I want to give people an idea of why Cocoa or perhaps more specifically Objective-C is cool.

I think anybody who has played computer games to some extent know how the game Doom (1993) from id software revolutionized gaming on the PC platform. What few people know was the the game was actually not developed at the PC platform at all.

At the time Doom was developed in 1992, Windows 95 didn't exist yet and software development on PC's looked like this:



Not very impressive. Instead it was developed on computers from NextStep, the company founded by Steven Jobs after he was kicked out of Apple. As id developer John Romero says:
Why do I care so much about NeXT computers? Because we at id Software developed the groundbreaking titles DOOM and Quake on the NeXTSTEP 3.3 OS running on a variety of hardware for about 4 years. I still remember the wonderful time I had coding DoomEd and QuakeEd in Objective-C; there was nothing like it before and there still is no environment quite like it even today.


To get an impression of how far ahead of its time Objective-C and what is now known as Cocoa was ahead of its time, consider this:
In fact, with the superpower of NeXTSTEP, one of the earliest incarnations of DoomEd had Carmack in his office, me in my office, DoomEd running on both our computers and both of us editing one map together at the same time. I could see John moving entities around on my screen as I drew new walls. Shared memory spaces and distributed objects. Pure magic.



Consider how long time ago that was, CORBA didn't support C++ for remote method invokation until 1996. At the time id did this it was just in its infant stage. Not to mention this was long long before Java RMI made remote objects populare and mainstream. It isn't even common to do this kind of thing today, and yet this was something that was quite trivial to do in Objective-C and Cocoa back in 1992.

Introducing Objective-C


Every time someone introduce you to Objective-C they will tell you about what a small and simple language it is. How easy it is to learn etc. But that was not my impression when I first tried to learn it. At the time I knew C++. When I saw an example of how to declare a class:

@interface MyClass : NSObject

{

  int         mSomeNumber;

  NSString*   mSomeString;

}



- (int)someNumber;

- (void)setSomeNumber:(int)aNum;

@end


I didn't think it looked easy or simple at all. Especially when I saw some code examples:

- (void)drawRect:(NSRect)frameRect

{

  // Fill whole background with white

  [[NSColor whiteColor] set];

  [NSBezierPath fillRect:frameRect];



  // Construct rows of lines

  NSBezierPath *gridLines = [[NSBezierPath alloc] init];

  for (unsigned row = 0; row <= mNoRows; ++row) {

      [gridLines moveToPoint: rowLeft];        

      [gridLines lineToPoint: rowRight];

      rowLeft.y  += rowHeight;

      rowRight.y += rowHeight;            

  }        



  // Set style to draw line in

  [[NSColor blackColor] set];

  [gridLines setLineCapStyle:NSSquareLineCapStyle];

  

  float pattern[2]  = {2.0f, 5.0f};

  [gridLines setLineDash:pattern count:2 phase:0.0f];



  // Draw specified lines in given style

  [gridLines stroke];

  [gridLines release];    

}



The code below is just to give an idea of what Objective-C syntax is like. What the code does is not important. It has been simplified a bit to understand better. It basically draws several rows with black lines on a white background. When I first saw this kind of code I didn't think it looked easy at all. And I thought whoever said that Objective-C was a much simpler language than C++ must have been smoking something that wasn't good for them.

The problem was that I was too caught up in the syntax. The syntax is indeed very unusual, but if one looks beyond that, the structure of the syntax is actually quite simple.

Perhaps the best way to understand the syntax is to understand, why it looks so strange.

Background


Unlike C++, Objective-C wasn't really a new language at all originally. There was no Objective-C compiler. Instead Objective-C was just plain old C, with an added preprocessor. As any C/C++ developer worth his/her salt should know all statements starting with # specifies a preprocessor directive in C/C++. E.g. #define and #include. The preprocessor runs before the compiler and replaces the directives with actual C/C++ code.

What the makers of Objective-C did was to add another preprocessor, but instead of marking the directives with #, they marked them with @. That way their special preprocessor could find all the new directives easily.

While this does make Objective-C look like some alien entity inside C, it does make it trivial to distinguish between pure C code and the add-ons from Objective-C. Unlike C++, where what is C and what is C++ is blurred. Actually C++ isn't a strict superset of C like Objective-C although it usually compiles C code. The reason being among other things that C++ reinterprets a lot of regular C code into new C++ concepts. E.g. a struct isn't just a struct anymore but actually a class in C++.

Syntax inspiration from smalltalk


The second stumble block in order to understand Objective-C syntax is to realize it is derived from Smalltalk, while C/C++ syntax is derived from Algol. Algol based languages separate arguments with comma, while smalltalk separates with name of argument and colon. Below is a code snippet that demonstrates setting the position and dimension of a rectangle object.

// Smalltalk

rectangle setX: 10 y: 10 width: 20 height: 20



// Objective-C

[rectangle setX: 10 y: 10 width: 20 height: 20];

[rectangle setX1: 10 y1: 10 x2: 20 y2: 20];



// C++

rectangle->set(10, 10, 20, 20);


The Smalltalk/Objective-C syntax improves readability of code. When specifying a rectangle some libraries use the start and end coordinates while others use start coordinates and size. With Smalltalk/Objective-C it is made quite clear what is done. While with C++ it is not clear whether the first or the second line of Objective-C code is used. Unlike Smalltalk Objective-C methods are called by enclosing call with []. This was originally to aid the preprocessor in extracting what was regular C code and what was Objective-C specific code.

A small and simple language


What do we exactly mean by saying that Objective-C is a small an simple language. C++ looks simpler syntax wise for the novice. However as said before syntax in deceiving. C++ add a host of new features to the C language: classes, virtual methods, non-virtual methods, constness, templates, friend classes, multiple inheritance, pure virtual functions, operator overloading, function overloading, private, public and protected members, constructors etc.

Objective-C on the other hand add very little, it is just classes, methods, categories and protocols. There is only one way to create classes and to inherit form them. You can specify whether inheritance is public or private e.g. There is only one kind of methods. There is no distinction between virtual and non-virtual. They can't be const or not const. The concept of constructors and destructors don't exist. Instead these are just normal methods.

As mentioned Objective-C is so simple they didn't even need to create a new compiler. A preprocessor was enough. This can make Objective-C seem overly simple. How can you do much with a language like that? The answer is the Objective-C runtime. The runtime is in fact what makes most of the Objective-C magic happen. Most of Objective-Cs features is provided at runtime and not done at compile time.

Methods and Selectors


Objective-C differs from C++ in that one distinguish between methods and selectors. To call a method on an Objective-C method you send a message. The method is not called directly. Instead Objective-C determines based on the selector which method to call.

Conceptually one can think of a message (selector) as simply a string with a list of arguments. The code below e.g. send the message setX:y:width:height: to object rectangle. This will invoke a method on rectangle if it understands the message.

[rectangle setX: 10 y: 10 width: 20 height: 20];



If we think of Objective-C as just a preprocessor as it originally was, all message sending is replaced with a call to a C function:
id objc_msgSend(id theReceiver, SEL theSelector, ...)


So when the preprocessor encounters our rectangle message it is translated into something like this:
objc_msgSend(rectangle, "setX:y:width:height:", 10, 10, 20, 20);


objc_msgSend queries rectangle for its class and then queries the class for methods it contains. Then it finds out which method corresponds to the given selector. The method is nothing but a function pointer of the form:

id (*IMP)(id, SEL, ...)


Of course this is a simplified explanation. In reality every selector is registered. Meaning we don't pass newly created strings to objc_msgSend each time we invoke a method but a pointer to a string. This pointer has to be unique. So we can't pass any string pointer.

So if we got � string we can find the unique pointer to this string by using the function:

sel_registerName(const char *str)


Which returns the pointer if it exist or registers the selector as a unique string pointer if it doesn't exist. The benefit of this is that selectors can be looked up quickly and compared quickly by just comparing their pointer addresses rather than comparing each character of the string.

Unique dynamic features of Objective-C


I don't intend to go into every minor of the Objective-C runtime library but the example above should give an idea of how the dynamic features of Objective-C works.

Classes


In C++ classes don't exist passed compile time. Or at least in modern C++ compilers which support runtime type identification classes exist in a watered down sense in that one can query if two classes have a relationship.

In Objective-C it is almost opposite. Classes don't exist at compile time but rather are runtime entities. Classes are registered at runtime with function:
void objc_addClass(Class myClass);

Likewise methods and selectors are registered at runtime. So classes can in fact be modified at runtime. Of course users don't call objc_addClass. These methods along with the ones that registers methods are generated by the preprocessor from the class definition provided by the programmer.

But it is this fact that classes and methods exist as structures in memory at runtime that allows the programmer at runtime to query classes about their member variables and functions and whether they respond to a selector or not.

In fact an Objective-C developer could create an application which could let user specify classes to call and functions to call. User could just type in the name of a class. Then developer could use C function NSClassFromString() to get corresponding class. NSSelectorFromString() could be used to retrieve the selector. With this one could query class further about arguments existing for selector etc.

To learn more about Objective-C look at wikipedia

The right tool for the job: C++ vs Objective-C

I read Alexei's blog entry about C++ vs Objective-C. I agree fully with his statement that:


The argument (which you can go and read yourself) boils down to �C++ can do everything Objective-C can� versus �sure it can, but not easily, usably or understandibly.� The usual argument comes down to object models: With Objective-C, you can send any object any message, and if it understands it, it will respond. C++ is restricted by its compile-time type system, so that even if you have arbitrary objects that all implement the member function foo, there is no way to call that method on a set of them unless they all inherit from the same base class. Except that you can, as exemplified boost::any and boost::variant.

Actually I pretty much agrees with everything Alexei says and the comments put forth by different people. C++ templates is a wonderful thing while often complicated to understand and use. My major issue with them is that they can't be extended into runtime.


So anyway what I want to emphasis is that templates is not substitute for Objective-C's dynamic features. I work daily on a C++ application with +4 million lines of code. The application have a natural fit with OO design because it has a number of data objects which can be inspected, manipulated and visualized in many different sorts of views at the same time. E.g. one view can show the object in 3D while another can show an intersection in 2D. So Model-View-Controller is a natural fit for it.


The more I work on it the clearer Greenspuns Tenth Rule of programming becomes to me:

Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.

Bottom line is that the kind of structure a large application like this would typically have is what Objective-C was designed for. And thus when I look at the app, all we do in C++ is making a bug-ridden slow implementation of Objective-C.


Creation of views for data objects has to be abstracted because we might create new views we never thought about when the data objects were designed. Thus construction of views has to be abstracted. In Objective-C this is easy. Classes can be passed around like objects and instantiated. C++ on the other hand provides no abstraction of object creation so we ended up making this elaborate scheme with Class ids and factory classes.


We created reference counting, a system for sending messages between object for notifications etc. All stuff that Objective-C was designed for. We end up with huge amount of code for the overall architecture. And it is not even working that well.


But we are not the only ones. Every time I look at a large C++ framework or toolkit I realize that they are just re-implementing Objective-C features in a non standard and buggy way. When I say non-standard I mean that every toolkit has those features but they are done differently in each one and thus not compatible.


E.g. VTK (Visual Toolkit) has reference counting, message passing and abstraction of object creation. Open Inventor has their own reference counting etc. The Qt GUI toolkit has basically gone around the limitations of the C++ language for dynamic behavior and essentially created a library that allows for object introspection and runtime and dynamic dispatch. Essentially they have reimplemented Objective-C in C++. While they have don't quite a good job and I love the Qt toolkit it is still a kludge and non-standard.


So what exactly is my point? My point is that while people can argue from a theoretical foundation that C++ really is the better language due to all its features the power of templates etc, reality speaks for itself. In practice C++ very frequently fails as a language. It seems quite plain to me that when any large C++ toolkit seem to make a half bad implementation of Objective-C then something is wrong with the language.


Does this mean that I think Objective-C is a better language? No, far from it. I just think that one should use the best tool for the job. Frequently it seems like Objective-C would have been the best tool but C++ was selected instead. While C++ has an obvious advantage in implementing algorithms and high performance code, it doesn't seem like the mistake has been done as frequently at the Objective-C camp.


My speculation would be that this is because Objective-C's deficiencies are so obvious. While C++ deficiencies are not as clear. One can more easily kid oneself into thinking C++ will solve the problem without any hassle. And not at least because C++ is better known, a Objective-C developer will more likely consider using C++ for specific parts of the program than the other way around.


C++ and Objective-C complements each other very well in my opinion and they have different enough syntax from each other that it should be easy to keep the two apart in a program. But too often people think C++ is the silver bullet that can be used equally well for any task.

Wrapping C++ classes in Lua

Lua is a script language frequently used in game development. Typically the game engine is written in C/C++ and the game itself is defined in Lua. Meaning setting up behaviour, placement of objects like powerups, doors, enemies etc is done in Lua. That way the game can be quickly tweaked without having to go through a time consuming re-compile.



But I am not going to go in depth about the different usage of Lua, nor explain the language itself. An online book at the Lua web page does that very well already. I will here assume you already have some basic knowledge about Lua.



However finding any documentation on how to wrap a C++ class so that it can be used in Lua is difficult. One could of course use one of the ready made bridges. But here we are going to look at how to do it yourself.



The tricky part is deciding on how to do it. Because Lua is such a flexible language there is really a lot of ways you could achieve it.



The naive approach


First lets look at several options, what works and doesn't. My first approach was to light user data to store a pointer to my C++ class. I will use a Sprite class and related classes as examples here as that was the type of classes I was wrapping.



static int newSprite(lua_State *L)

{

    int n = lua_gettop(L);  // Number of arguments

    if (n != 4)

        return luaL_error(L, "Got %d arguments expected 4", n);

  

    double x = luaL_checknumber (L, 1);      

    double y = luaL_checknumber (L, 2);

    double dir = luaL_checknumber (L, 3);      

    double speed = luaL_checknumber (L, 4);



    Sprite *s = new Sprite(Point2(x, y), dir, speed);

    

    lua_pushlightuserdata(L, s);



  return 1;

}


The code snippet above shows a naive implementation of this approach. Unfortunately it doesn't work. The problem is that a light user data is just a simple pointer. Lua does not store any information with it. For instance a metatable which we could use to define the methods the class supports.



An approach with limited functionality


The next approach would be to use user data. Unlike light user data it can store a reference to a metatable.



static int newSprite(lua_State *L)

{

    int n = lua_gettop(L);  // Number of arguments

    if (n != 4)

        return luaL_error(L, "Got %d arguments expected 4", n);

  

    // Allocate memory for a pointer to to object

    Sprite **s = (Sprite **)lua_newuserdata(L, sizeof(Sprite *));  



    double x = luaL_checknumber (L, 1);      

    double y = luaL_checknumber (L, 2);

    double dir = luaL_checknumber (L, 3);      

    double speed = luaL_checknumber (L, 4);



    *s = new Sprite(Point2(x, y), dir, speed);

    

    lua_getglobal(L, "Sprite"); // Use global table 'Sprite' as metatable

    lua_setmetatable(L, -2);       

    

  return 1;

}


For us to be able to use sprite like this we need to register class first. Basically we need to create a table Sprite which contains all the methods that our user data should support.


// Show registration of class

static const luaL_Reg gSpriteFuncs[] = {

  // Creation

  {"new", newSprite},

  {"position", position},

  {"nextPosition", nextPosition},    

  {"setPosition", setPosition},  

  {"render", render},      

  {"update", update},          

  {"collision", collision},   

  {"move", move},    

  {"accelerate", accelerate},      

  {"rotate", rotate},  

  {NULL, NULL}

};



void registerSprite(lua_State *L)

{

  luaL_register(L, "Sprite", gSpriteFuncs);  

  lua_pushvalue(L,-1);

  lua_setfield(L, -2, "__index");    

}


This will allow us to create instances of Sprite and call methods on it in Lua like this:


-- Create an instance of sprite an call some methods

local sprite = Sprite.new(x, y, dir, speed)

sprite:setPosition(x,y)

sprite:render()



The final approach


In most cases this approach is sufficient but it has one major limitation. It does not support inheritance. You can change the methods of Sprite in Lua but that will change the behavior of all instances of Sprite. What you would want to do is to be able to change method on just the instance and then use that instance as a prototype for new Sprite instances, effectively creating a class inheritance system.


To do this we need to change the instance into being a table. How do we access our C++ object then? Simple, we just store the pointer to it as user data in one of the field of the table. You might think that this time light user data will be sufficient. However the problem is that only user data is informed of garbage collection, not tables or light user data. So if you want to delete the C++ object when corresponding lua table is garbage collected you need to use user data.


So we then arrive at our final solution. We will store a pointer to our C++ object as user data on the key __self in the table that represents our instance. __self is an arbitrary selected name. It could be anything. We will not register Sprite as as the metatable for our instance but instead register the first argument to the new function as it. This will allow us to support inheritance. Further the garbage collection function will be register on a separate table which will be used as metatable only for the user data. This is to allow it to be garbage collected.


static int newSprite(lua_State *L)

{

    int n = lua_gettop(L);  // Number of arguments

    if (n != 5)

        return luaL_error(L, "Got %d arguments expected 5 (class, x, y, dir, speed)", n);

    // First argument is now a table that represent the class to instantiate        

    luaL_checktype(L, 1, LUA_TTABLE);   

    

    lua_newtable(L);      // Create table to represent instance



    // Set first argument of new to metatable of instance

    lua_pushvalue(L,1);       

    lua_setmetatable(L, -2);



    // Do function lookups in metatable

    lua_pushvalue(L,1);

    lua_setfield(L, 1, "__index");  



    // Allocate memory for a pointer to to object

    Sprite **s = (Sprite **)lua_newuserdata(L, sizeof(Sprite *));  



    double x = luaL_checknumber (L, 2);      

    double y = luaL_checknumber (L, 3);

    double dir = luaL_checknumber (L, 4);      

    double speed = luaL_checknumber (L, 5);



    *s = new Sprite(Point2(x, y), dir, speed);

    

    // Get metatable 'Lusion.Sprite' store in the registry

    luaL_getmetatable(L, "Lusion.Sprite");



    // Set user data for Sprite to use this metatable

    lua_setmetatable(L, -2);       

    

    // Set field '__self' of instance table to the sprite user data

    lua_setfield(L, -2, "__self");  

    

  return 1;

}


We can now work with sprite instances in Lua like this:


-- Instantiate from Sprite class

local sprite = Sprite:new(x, y, dir, speed)

sprite:setPosition(x,y)

sprite:render()



-- Add method to instance as use it as class

function sprite:doSomething()

  print("do something")

end



local derived = sprite:new(x, y, dir, speed)

derived:render()

derived:doSomething() -- This is now a legal operation

There are still a couple of loose ends. We haven't showed how the methods are registered with this new solution nor how we access C++ object pointer in methods. But this is fairly straight forward as I will show.


void registerSprite(lua_State *L)

{  

  // Register metatable for user data in registry

  luaL_newmetatable(L, "Lusion.Sprite");

  luaL_register(L, 0, gDestroySpriteFuncs);      

  luaL_register(L, 0, gSpriteFuncs);      

  lua_pushvalue(L,-1);

  lua_setfield(L,-2, "__index");  

  

  // Register the base class for instances of Sprite

  luaL_register(L, "Sprite", gSpriteFuncs);  

}


We can then implement a method of Sprite like this


static int setSpeed(lua_State *L)

{

  int n = lua_gettop(L);  // Number of arguments

  

  if (n == 2) {

    Sprite* sprite = checkSprite(L);

    assert(sprite != 0);

    real speed = luaL_checknumber (L, 2);

    sprite->setSpeed(speed);

  }

  else

    luaL_error(L, "Got %d arguments expected 2 (self, speed)", n);

  

  return 0;

}


To extract the pointer to the C++ object and make sure it is of the correct type we use the following code:


Sprite* checkSprite(lua_State* L, int index)

{

  void* ud = 0;

  luaL_checktype(L, index, LUA_TTABLE);

  lua_getfield(L, index, "__self");

  ud = luaL_checkudata(L, index, "Lusion.Sprite");

  luaL_argcheck(L, ud != 0, "`Lusion.Sprite' expected");  

  

  return *((Sprite**)ud);      

}


The only thing left is dealing with garbage collection but I leave that as an exercise. You should already have the basic idea of how to deal with it. Please note that I have not tested the exact same code as written here so why the principles are correct there might be minor errors in the code. In my own code I have separated more of the code into separate functions since the code for creating an instance is almost identical for any class, as well as the code for extracting the __self pointer.



Conclusion


While using a bridge might be better for bigger projects I think it is good to know for yourself exactly what goes on under the hood and when you do it yourself you can more easily fine tune what you export and not and in which way. Typically you would want the Lua interface to be simpler and more limited than the C++ interface to your classes.

Intersection test assertion failure in CGAL

I have just started using the CGAL library. It is a library for doing computational geometry. It contains classes and functions for different geometric data structures like triangles, line segments, polygons and functions for testing for intersection, calculating convex hull and a lot more.

This week I fell into the first trap of computational geometry. I stored polygons in Polygon_2 classes and then performed an intersection test with the do_intersect function. Unfortunately that too often lead to the program crashing with the assertion failure:


CGAL error: precondition violation!
Expr: Segment_assertions::_assert_is_point_on (p, cv, Has_exact_division()) && compare_xy(cv.left(), p) == SMALLER && compare_xy(cv.right(), p) == LARGER
File: /Users/Shared/CGAL-3.2.1/include/CGAL/Arr_segment_traits_2.h
Line: 730


or


CGAL error: assertion violation!
Expr: *slIter == curve
File: /Users/Shared/CGAL-3.2.1/include/CGAL/Basic_sweep_line_2.h
Line: 591


Eventually I narrowed it down to discover that it happened in specific degenerate cases. For instance when a corner of a polygon intersected an edge of another polygon. Which means two line segments are intersecting another line segment in the exact same spot. Now I know this would normally be a problem for line sweep algorithms but I also know that any computational geometry library with respect for itself should handle such degeneracies. So I could not understand why CGAL should fail.

Well it turns out that I didn't read this part of the CGAL manual:

If it is crucial for you that the computation is reliable, the right choice is probably a number type that guarantees
exact computation. The Filtered kernel provides a way to apply filtering techniques [BBP01] to achieve a
kernel with exact and efficient predicates. Still other people will prefer the built-in type double, because they
need speed and can live with approximate results, or even algorithms that, from time to time, crash or compute
incorrect results due to accumulated rounding errors.


I had expected this kind of problem. So I thought it was because I used float. I changed to double and got the same problem. It turns out I should have used CGAL::Exact_predicates_exact_constructions_kernel.