C++ on iPhone: Part 1

Tue, Oct 21

Much is made of the Objective C programming language when discussing iPhone development. It’s the language of choice, many of the iPhone frameworks are written in Obj-C, etc, etc.

Coming from a background of mobile development on other platforms, I was curious about how well C++ is supported on the iPhone. BREW, Symbian and Windows Mobile all have C++ support in one shape or another, and certainly there is a ton of C++ code out there, so my thought was this: will legacy C++ code from other platforms run on iPhone?

The first thing to realize is that under the Xcode hood, Apple is using GCC (the GNU Compiler Collection) compiler for the Obj-C compilation. This is important because the GCC Obj-C compiler is in a manner of speaking also the GCC C++ compiler, with a few different command line switches. So, it seems promising – perhaps C++ support will work. But, what about run time library support? The other major platforms using the GCC tools (BREW, Symbian) have various horrible (and arguably pointless given today’s hardware) restrictions on what you can do, with various C++ “language features” simply being dropped (with various justifications). Here’s a short list of the things you typically don’t get with other mobile C++ tool chains:

1. Global static objects. Static C++ objects are regarded as a no-no for various reasons on other platforms. Both BREW and Symbian want you to reference all global application data through a pointer to allocated application heap. You’ll typically see some sort of “Applet” structure, in which the developer can embed pointers to objects that must be allocated by the application at init time. Then, there is a process of passing the pointer to ths “applet” struct around to any object that needs it, or else there will be a method provided in the platform API which will return the address of the applet struct. There’s good and bad with C++ objects defined at global scope, ordering issues, and so on; however, they can be useful, for example with smart pointers, which have the advantage of cleaning up after themselves when defined @ global scope (whereas a regular pointer would not have its destructor called as we’ll see later). Will iPhone support this?

2. Exception handling. Citing code bloat, this feature is often not supported. You can make it work on BREW w/GCC if you are prepared to do runtime lib hacking, and Symbian (last I checked) has their own non-standard variant, but the standard C++ exception handling is typically missing. Does the iPhone support this? We’re not so worried about the code size on the iPhone – the 10MB OTA AppStore limit gives plenty of room for manuever.

3. RTTI – run time type identification. This is typically not supported, the reasons given being code bloat and lack of exception support (what to do if a cast fails?). Again, does iPhone support this?

It is also important to understand how C++ code interacts with other code written in C and Obj-C. After all, having C++ support is all well and good, but it has to be practically useful, calling back and forth, etc. That said, I am going leave that aspect for a future article, and focus here on pure C++ global static objects – does the iPhone support them at all? The short answer is that, yes, it does.

Note: typically you would not really have a bunch of “loose” global static objects like this – you’d probably want to make them static class members; however, for the purposes of this article I’m simply going to define some objects at file scope, for clarity.

Here’s what I did. I started with the generic iPhone “Window Based Application” Xcode template project. To this, I then started adding C++ classes.

1. CTRL-click on Other Sources, and select Add -> New File
2. In the Mac OSX category, click on C and C++ and then select the C++ File template.
3. I gave my class the name GlobalStatic.cpp and selected ‘also create GlobalStatic.h’

This gives us empty C++ header and implementation files, the contents of which I will detail below.

Next, I followed the same three steps and made myself another C++ class called Tests (Tests.cpp/h).

OK, so the GlobalStatic class looks like this:

1
2
3
4
5
6
7
8
9
10
11
// GlobalStatic.h
 
class GlobalStatic
{
public:
    GlobalStatic();
    GlobalStatic(int integerValue);
    ~GlobalStatic();
private:
    int integerValue;
};

This is a simple class with 2 constructor overloads, a destructor and an int instance var.

The implementation looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// GlobalStatic.cpp
 
#include <stdio.h>
#include "GlobalStatic.h"
 
// default constructor
GlobalStatic::GlobalStatic() : integerValue(0)
{
    printf("GlobalStatic()\n");
}
 
GlobalStatic::GlobalStatic(int integerValue)
{
    printf("GlobalStatic(%d)\n", integerValue);
    this->integerValue=integerValue;
}
 
// destructor
GlobalStatic::~GlobalStatic()
{
    printf("~GlobalStatic(%d)\n", integerValue);
}

I include the C runtime stdio.h file so I can call printf(), which outputs text to the debug console (in this case). Other than that, this is a very basic class who’s main raison d’etre is to call printf() to let us know when the ctor and dtor are called. OK, so far so good.

Note: the difference between #import and #include is basically that #import has “include guards” built in, whereas #include does not. Simply put, using #import will ensure that a header file is not included twice. I’ve used #import for Objective-C headers and #include for the C++ headers, but I’ve omitted include guards in the actual headers to keep things simple.

Now, for the purposes of this exercise the file Test.h remains empty. In Tests.cpp, I define a few global static objects, as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Tests.cpp
 
#include "Tests.h"
#include "GlobalStatic.h";
 
// define a global static object with default constructor
GlobalStatic gs1;
 
// define spme global static objects with inieger constructor
GlobalStatic gs2(1);
GlobalStatic gs3(2);
 
// this object will be intialized but the dtor will not be called
GlobalStatic* gsp = new GlobalStatic(3);

Then, I added two lines of code to the main.m file:

#include <stdio.h> // add this right below the #import <UIKit/UIKit.h>

And then right at the top of the main() method I added:

printf("main()\n");

And that’s it. No compiler settings, nothing special, just adding the code to the project (though note that a fuller interaction between Obj-C and C++ will take a little more effort). So, what happens when you build and run this? Basically, the objects gs1, gs2 and gs3 and the pointer gsp will be created/allocated by the C++ runtime lib, and this will happen *before* the main entry to the program is called. In the debugger console (Run -> Console) you will see the following output:

GlobalStatic()
GlobalStatic(1)
GlobalStatic(2)
GlobalStatic(3)
main()

When you close down the application, the destructors for the objects gs1, gs2, and gs3 will be called, and you’ll see the following output on the console:

~GlobalStatic(2)
~GlobalStatic(1)
~GlobalStatic(0)

Note! The destructor for the object pointed at by gsp is not called! This is expected, and this could potentially be a resource leak (though, in this case the runtime wil likely clean up the memory at least). It’s important to remember this though – if the GlobalStatic class had been expected to set some state in its destructor (in a database, for example), then that would never happen for that object.

There are actually many subtle (and potentially disasterous) side effects associated with the use of C++ global statics. There are ordering issues that can occur if one such object refers to another and on and on. Refer the C++ FAQ lite for details of some of the horrors (http://www.parashift.com/c++-faq-lite/ctors.html ). So, I am not holding up this technique as a panacea or even something that is highly recommended – you need to know what you are doing and even then tread very carefully. However, as s benchmark for the level of C++ support in the runtime, this is pretty good.

I will cover exceptions, RTTI and more in future articles (time permitting!). What this article has hopefully shown is that there are viable alternatives to using Obj-C on the iPhone and that if you are familiar with using C++ on pretty much any other mobile platform, it may be that the iPhone will pleasantly surprise you with what it does do, rather than by what it does not .

7 comments

Looks promising! Cmon, show us some gui (button) with c++!

by Alexei Sergeev on Oct 25, 2008. #

alexei: I guess you would call the iphone sdk’s functions the same way you would in obj c

by an00b on Nov 3, 2008. #

Hello, i’m a noob. I’ve classdumped UIKit.framework and copied these header files and main code from this page. how do i compile on the iphone? thanks

by Kyle on Nov 14, 2008. #

I’m a C++ neophyte (for years). Working with C++ for me at least, is about as pleasurable as pulling my teeth out.

Still, there’s a lot of Open-Source C++ out there so I can’t avoid it.
I’ve been working with “Objective-C++”, which is what you just introduced.

Your intro article is greatly appreciated, at least from an ObjC point of view.
If there’s a book devoted toward ‘Objective-C++’, I’ll buy it.

I need to know more about C++ and its use with iPhone/Mac.
Particularly I would like to see a C++ version of the standard ObjC application and compare the two.

by Frederick C. Lee on May 6, 2009. #

Great stuff!

Where is part 3?

by Bob DeAnna on May 13, 2009. #

I’ve created a nasty little guide for my CSCI class on doing this…. It’s not as bad as you’d think. I am able to create Views on iPhone who’s classes reference c++ code :)

http://blog.psychopup.net/post/2009/09/21/Using-C2b2b-Classes-Code-in-XCode-for-OSX-and-Iphone-applications.aspx

by Richard Jesus Dominguez on Sep 22, 2009. #

hey, thanx for this information yr…..

by swapnil on Aug 12, 2011. #