Tag Archives: programming

VBScript/Classic ASP Function Parameters

I know that VBScript passes parameters by reference, but I seldom take advantage of that feature. So when I need it, I am always able to convince myself that I’m misremembering. So here are the results of a recent test to remind me:

function Three(N)
	N = 3
	Three = 0
end function

dim x
x = 1
Response.Write "<p>x = " & x & "; Three(x) = " & Three(x) & "; x = " & x & "</p>" & vbCrLf

Output:

x = 1; Three(x) = 0; x = 3

Advancing Technology by Lying to Developers

Mobile devices have been increasing in screen size, screen resolution, memory, and other capabilities on a continuous basis from the time I got my first Apple Newton MessagePad in 1993. Back then screens were about 336×240 pixels, and each pixel was either on or off — no color. There was a total of 4.625 MB (that’s MEGA bytes) of memory. My first Windows CE device was probably my HP 620 LX in 1998. It was a “clamshell” design with a 640×240 screen and 16 MB of memory.

The thing we knew intuitively from being involved in personal computing since there was such a thing as personal computing was that “change is the status quo”. Our programs never assumed how big the screen was, because we knew our program would need to run next week on a bigger screen, so we wrote our code so that it queried the operating system to ask how big the screen was before dynamically laying out its user interface to fill all available pixels. We never assumed that devices would always be monochromatic, so we wrote our compressed file format to accommodate “words of Christ in red” before they could even be displayed in anything but black on a greenish screen. And even though the entire Bible wouldn’t fit in memory of those first devices, we plowed ahead with the best compression we could manage and a user interface that supported displaying two Bibles simultaneously, knowing that very soon you’d be able to get not just one of our Bibles but two whole Bibles onto the device at the same time.

Fast forward to the iPhone in 2007. When you work for Apple you apparently get big-headed and begin to think you’re among the smartest programmers in the world. Nobody can match your brilliance. Each generation of device you work on is “magical”. It has capabilities and features that nobody could have imagined even six months ago. Features like a more memory and a bigger screen.

Since you couldn’t imagine those features last year, and since you’re God’s gift to technology, you’re positive that nobody else could have imagined those features. So what’s going to happen to all those apps written by people “too dumb to work at Apple” when your new device with a bigger screen comes out? Why, they’ll crash, of course.

Not PocketBible.

You only have to be in this business a week to realize that you can’t hard-code your program to assume a particular screen size. But Apple does this with every single device. Up until iOS 8, we had to prepare a “splash image” to display when the program launched in every possible size and resolution. Currently, that means we have to create launch images in 13 different sizes, one for each iPhone screen size that has ever been shipped, in both portrait and landscape orientation.

Current iOS launch image requirements

Current iOS launch image requirements


If instead they allowed us to manipulate a single image at run-time, we could do all of these with one PNG. But they require us to know every size of every screen we might ever run on (by the way, the image above omits devices prior to the iPhone 4, which would add another half-dozen sizes if they hadn’t already been abandoned by Apple).

This isn’t about managing lots of images. It’s about a philosophy that can’t think past yesterday.

Because of this philosophy, when a bigger screen comes out, Apple either “letterboxes” old apps (putting black bars in the empty space that the program couldn’t possibly imagine would ever be there) or scales them (allowing them to believe the screen is no bigger than last year’s device, then scaling up everything they draw to fill the bigger screen). They believe they are saving developers from having to re-release their apps every time a new device comes out. But in reality, they are requiring every developer to re-release their app to jump through whatever hoop is required to get Apple to stop letterboxing or scaling their apps.

iPhone 6 scaling

Pre-iPhone 6 version of PocketBible on the left gets scaled up. Adding a “launch screen” (which is unrelated to drawing text) tells iOS not to lie to us about the screen size, producing the sharper image on the left with absolutely no changes to PocketBible code!


With iOS 7, there was a special checkbox we had to check to tell the OS that we understood their new semi-transparent user interface elements. With iOS 8, in order to convince iOS not to scale your app (producing blurry text), you have to provide a special, scalable launch image that works on any screen size. (Gee whiz, 2015 and we’re finally recognizing that screens might get bigger in the future! Thanks, Apple!) Until you do that (which requires re-releasing your app), iOS will lie to you about the size of the screen then scale your user interface up to the bigger physical size of the screen, producing blurry text.

Oh, and you still have to provide those 13 launch images for older devices.

The result of this policy of “technical advancement by lying to developers” is that instead of one guy at Apple having to write zero lines of new code, hundreds of thousands of developers have to update and re-release their apps. There would not have been a personal computing revolution in the 80’s and 90’s if Microsoft would have taken this approach. Back then, Microsoft would collect commercial software products and use them for regression testing of new versions of DOS and Windows. After all, you wouldn’t want to do something stupid and break every single app the way Apple does with every release of the iPhone.

This industry used to be exciting. I was like a kid in a candy shop. Technology was changing and we were riding the “bleeding edge”. Now I feel like the only grown up in the room. I want to slap some of these Apple and Google kids around and tell them to shape up.

Delete Program Preferences in OS X (Including Cache)

Often while debugging an app it’s handy to delete its preferences so it will “start over” like a fresh install. You used to be able to find the .plist file in the Preferences folder and delete it. Simple.

Starting with OS X 10.9, preferences are cached. So even after deleting them, they’re still around. Here’s the magic shell command that deletes them:

defaults delete com.company.programName

Why I Don’t Care About Swift

Swift is a new programming language created by Apple for use on OS X and iOS devices. The programming world is agog. Apple’s fantastic new language apparently solves all their problems, as evidenced, they say, by the fact that some programmer ported Flappy Birds to it in a few hours.

I’ve been around long enough to see languages come and go. Each claimed to solve all the problems introduced by its predecessors, yet each was replaced by a language that solved all its problems. In some cases, the new language surpassed the success of the language it replaced (C++ and Java); in other cases, the new language faded into obscurity (Modula-2 and Ada).

Lately the motivations for new languages have been dubious. There is a big emphasis on making a language easy to learn and having it hide nasty issues related to memory management and type safety. One review of Swift I read stated, “Apple hopes to make the language more approachable, and hence encourage a new group of self-taught programmers”. While that sounds great, it means that those of us who have mastered our craft after 30 years or more of practice are saddled with the training wheels and water wings that are written into these languages for the noobs.

A classic example is the lack of unsigned integers in Java. The motivation for this was to simplify the language for “new and self-taught programmers” by avoiding errors caused by a lack of understanding of sign-extension. However, for those of us who showed up for class the day that sign extension was taught (that would be day two), we’re left with a language that unnecessarily limits the range of positive integers and requires us to actually have mastered sign extension in order to understand what is happening when we directly manipulate the bits in our integer variables.

Explicit vs. Implicit Typing

One of the simplifications Swift makes is that it infers the types of variables from the values assigned to them rather than requiring the programmer to explicitly type variables. If this was true “weak typing” like I’m familiar with in VBScript, it would be great (though it would come with its own set of problems). But all Swift does is infer the type of the variable from the first value you assign to it.

This actually introduces problems, because it’s not always possible to unequivocally determine the type of a literal value. So Swift gives you ways to force it to interpret a literal value as a given type. Rather than removing the necessity of the programmer understanding types, Swift thus requires “new and self-taught” programmers to have a mastery of types so that they can understand how Swift is working behind the scenes and make sure that their variables have the desired type.

Strings

Swift is said to improve string-handling over Objective-C (the current language used on OS X and iOS). There is certainly room for improvement there. When I first started programming in Objective-C, one of the first things I did was bring over my own C++ string class, as I found NSString to be overly complicated and muddled. Over the years I’ve gotten better with NSString.

I would argue, however, that some of the so-called “improvements” in Swift with respect to strings are differences without a distinction. So instead of this in Objective-C:

[NSString stringWithFormat:@"The value of num is %d", num]

you say this in Swift:

"The value of num is \(num)"

The Swift version is obviously more concise, but it is also less powerful. To add more complex format specifications to Swift you actually have to invoke the functionality of the underlying NSString class, which means the “new and self-taught” programmer, again, needs to understand the details of the implementation in order to do anything beyond the simplest strings.

One of the stated benefits of string handling in Swift is that “all strings are mutable”. One need not worry about whether the string is declared as an NSString (immutable) or NSMutableString (mutable). Well, you don’t have to worry unless you do have to worry — strings assigned to constants are immutable in Swift. So:

var myString1 = "Mutable string"
let myString2 = "Immutable string"
myString1 += myString2    // perfectly legal
myString2 += myString1    // compile-time error

Switch Statements

Swift eliminates the “fall-through” behavior of switch statements, which is said to eliminate bugs caused by omitting the break at the end of each case block. But, oops, sometimes the fall-through behavior is exactly what you want. So Swift adds the fallthrough keyword. It could be argued that Swift eliminates a line of code (the break) while giving the behavior one normally desires. But at the same time, it adds a keyword (fallthrough) that does the opposite. This requires “new and self-taught” programmers to have the same thorough understanding of switch behavior that Objective-C and C++ programmers do.

Single-line Blocks

The Swift compiler will warn you if you omit the braces in any block (such as after an if) and does not allow single-line blocks, thus avoiding this error:

if (x < 0)
    goto fail;
    goto fail;

The code above will always execute one or the other of the goto statements in Objective-C or C++. Even though the second goto is indented, it is not part of the if-block and will be executed if the condition is false.

Swift will warn you about the missing braces and force you to write this:

if (x < 0)
    {
    goto fail;
    }
goto fail;

Or, for those of you who don’t do your braces the right way, this…

if (x < 0) {
   goto fail;
}
goto fail;

This is fine, and hard to argue with. The supposition is that the programmer will immediately recognize the flaw or won’t make the mistake in the first place. On the other hand, I would argue that the same C++ programmer who wrote the erroneous code will write this in Swift:

if (x < 0) {
    goto fail; }
    goto fail;

I always put braces around my blocks, even if they are one-line, so this doesn’t affect me. It’s ironic, however, that while Swift prides itself in eliminating the unnecessary break statement at the end of a case block, it requires two to four additional lines (braces) in if, for, and while statements, which are more numerous.

PocketBible and Swift

I will be more than happy to learn and use Swift for programming on iOS and OS X. I just don’t believe the hype and won’t convert just for the sake of doing something new.

I am a strong proponent of platform-independent languages like C, C++, Java, and, to a lesser extent, Objective-C (the latter is primarily an Apple language, though it has its origins outside of Apple). Such languages allow me to develop code on one platform and re-use it on another. One of the promises of C++ and Java was that you could develop the code for one platform and use it on many others. Swift is an Apple language (the same way C# is a Microsoft language). It only works on Apple devices. While those are numerous, they’re not the only devices out there. So rather than moving toward the “write once, read everywhere” model promised by Java, we’re back to “write everywhere” as each platform requires its own language.

I don’t mind learning a new language. I already jump from C++ to C# to Java to VBScript to Javascript to MS-SQL on a daily basis. For those of us who write code for a living, being multilingual is a job requirement. This is precisely why I care so very little about the supposed advantages of Swift; this isn’t a religious war for me, it’s just a tool. When someone comes out with a new kind of screwdriver, I may or may not buy it until I need it. And then I’ll just buy one and use it — I won’t try to convert all my screwdriver-toting friends.

So will PocketBible for OS X and/or iOS be re-written in Swift? Probably not today, and probably not until Apple requires it. But Swift depends on Objective-C under the hood, so my guess is that Apple will continue to support Objective-C apps for a long time.

Enabling Web Inspector in Web-Kit WebViews in OS X Apps

You can turn on Safari’s Web Inspector functionality in any app that uses WebView to display HTML. First, enable the Developer menu in Safari’s preferences. Then enter the following command in Terminal:

defaults write com.example.myApp WebKitDeveloperExtras -bool true

Where com.example.myApp is the bundle identifier for the app. Launch the app, right-click in the WebView, and as long as the developer hasn’t completely disabled the context menu, you’ll be able to select Inspect Element and see the source code running in that view.

A program can enable this functionality itself by executing:

[[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:@"WebKitDeveloperExtras"];
[[NSUserDefaults standardUserDefaults] synchronize];

Similarly, I believe one could defeat this functionality by setting the value to FALSE inside the app.

Symbolicating iOS and OS X Apps

Many of the errors that happen in Mac OS X and iOS apps don’t actually crash the app, they just dump a stack trace to the console. You can view these using the Console app — select the System Log and you’ll see all the messages the app sends to the console.

Unfortunately, these stack dumps can’t be directly used by the programmer to find the bug. With a little work, however, it’s possible to get right down to the line of code that caused the problem.

A stack trace will look like this:

Sep 13 19:04:32 Users-Mac.local PocketBible[727]: *** -[__NSCFString rangeOfString:options:range:locale:]: Range {3040, 18446744073709551600} out of bounds; string length 3504
Sep 13 19:04:32 Users-iMac.local PocketBible[727]: (
		0   CoreFoundation                      0x00007fff910e225c __exceptionPreprocess + 172
		1   libobjc.A.dylib                     0x00007fff96598e75 objc_exception_throw + 43
		2   CoreFoundation                      0x00007fff910e210c +[NSException raise:format:] + 204
		3   Foundation                          0x00007fff94074985 -[NSString rangeOfString:options:range:locale:] + 186
		4   Foundation                          0x00007fff940945b4 -[NSString rangeOfString:options:range:] + 29
		5   PocketBible                         0x00000001077cec78 PocketBible + 797816
		6   PocketBible                         0x000000010776c771 PocketBible + 395121
		7   PocketBible                         0x000000010776aa43 PocketBible + 387651
		8   AppKit                              0x00007fff92c84c38 -[NSTabView selectTabViewItem:] + 389
		9   AppKit                              0x00007fff92ff8b09 -[NSTabView mouseDown:] + 145
		10  AppKit                              0x00007fff92b76a58 -[NSWindow sendEvent:] + 11296
		11  AppKit                              0x00007fff92b155d4 -[NSApplication sendEvent:] + 2021
		12  AppKit                              0x00007fff929659f9 -[NSApplication run] + 646
		13  AppKit                              0x00007fff92950783 NSApplicationMain + 940
		14  PocketBible                         0x000000010770d244 PocketBible + 4676
		15  ???                                 0x0000000000000001 0x0 + 1
	)

The trick, of course, is to find the last bit of PocketBible code that was running when the error occurred. To do this, we need our symbol map. Fortunately, XCode archives that with our program and we can access those archives through the Organizer. So here’s what we need to do:

  1. Create a working folder somewhere
  2. Go into the Archive area of Organizer and select the archived version of the program from which the stack trace was created
  3. Right-click and select Show In Finder
  4. Right-click on the archive and select Show Package Contents
  5. Copy the .dSYM file from the dSYMs folder into the working folder
  6. Copy the application from Products/Applications into the working folder
  7. In Terminal, go to the working folder

Now enter this command:

atos -o PocketBible.app/Contents/MacOS/PocketBible -arch x86_64 -l [load address] [target address]

To calculate [load addresses], subtract the offset you see on any PocketBible line from the address to its left. So looking at line 5, you would subtract 797816 (decimal) from 0x1077cec78 (hex) and get 0x10770c000. [target_address] is the address you see in the stack trace for the line you’re interested in (for example, 0x1077cec78 for line 5).

If you do it right, atos will tell you the object and method, plus the file and line number in the file corresponding to the line in the stack trace:

got symbolicator for PocketBible.app/Contents/MacOS/PocketBible, base address 100000000
-[NSString(HTMLTags) rangeOfHtmlTagInRange:] (in PocketBible) (NSString+HTMLTags.m:67)

Which sends us to NSString+HTMLTags.m, line 67.

If you want to enter several addresses, press enter after [load address]. You are then in “interactive mode” and can enter addresses and get results without leaving atos or re-entering all the other parameters. Press ^C to exit this mode.

Craig 1, Hacker 0

When you purchase a product from our website, you click on a link to download it. The link appears to be legit — just a regular link to a file on our server. But it’s not. The file does not actually exist. We intercept the link and parse it to determine what to download to you.

When geeks like me see something like this, they poke around to see what they can find. When our server sees someone like me poking around, it sends me emails so I can watch them do it, because that’s what geeks like me like to do. No, we don’t tell the customer who’s doing the poking that we’re watching them. In fact, the error message they get tells them to forward the message to tech support. In reality we already know. :-)

So here’s a customer from Australia doing some late-night hacking. He’s trying to download MyBible 5 for Palm OS without paying for it. Ironically, it’s free so if he really wants it, he can just go through the steps of ordering it and we’ll add it to his legitimate download account. But it’s more fun to try to get a free thing for free without not paying for it.

Two things you need to know: The product code for MyBible 5 is 3MBPGM005, and MyBible 3 is 3MBPGM002. The file name he’s trying to accidentally discover is “mb5setup.exe”. So this is the real link he’s trying to find: http://www.laridian.com/files/1158044/3MBPGM005/mybible5/program/mb5setup.exe

From the log:


http://www.laridian.com:80/files/1158044/3MBPGM005/mybible5/program/MyBibleSetup.exe
The filename requested (\mybible5\program\MyBibleSetup.exe) does not match the product (3MBPGM005). http://www.laridian.com:80/files/1158044/3MBPGM005/mybible5/program/MyBible5Setup.exe
The filename requested (\mybible5\program\MyBible5Setup.exe) does not match the product (3MBPGM005). http://www.laridian.com:80/files/1158044/3MBPGM005/mybible5/program/
The filename requested (\mybible5\program\) does not match the product (3MBPGM005). http://www.laridian.com:80/files/1158044/3MBPGM005/mybible5/program/MyBible51.exe
The filename requested (\mybible5\program\MyBible51.exe) does not match the product (3MBPGM005).

Next he tries to get an older version:


http://www.laridian.com:80/files/1158044/3MBPG3002/mybible3/program/MyBible3.exe
The filename requested (\mybible3\program\MyBible3.exe) does not match the product (3MBPG3002).

Back to looking for MyBible 5:


http://www.laridian.com:80/files/1158044/3MBPGM005/mybible5/program/MyBible5.exe
The filename requested (\mybible5\program\MyBible5.exe) does not match the product (3MBPGM005).

And back to MyBible 3:


http://www.laridian.com:80/files/1158044/3MBPG3002/mybible3/program/mb3setup.exe
The filename requested (\mybible3\program\mb3setup.exe) does not match the product (3MBPG3002). http://www.laridian.com:80/files/1158044/3MBPG3002/mybible3/program/MB3Setup.exe
The filename requested (\mybible3\program\MB3Setup.exe) does not match the product (3MBPG3002).

Here he gets it right! But he can’t download it because he doesn’t own it:


http://www.laridian.com:80/files/1158044/3MBPGM002/mybible3/program/mb3setup.exe
Customer 1158044 is not authorized to download product 3MBPGM002.

Now he switches his customer number to see if he can find a customer who *IS* authorized to download it. But he’s not going to get it without logging in as that customer first:


http://www.laridian.com:80/files/1158045/3MBPGM002/mybible3/program/mb3setup.exe
You are requesting files for customer 1158045 but customer 1158044 is logged in. You must access files through your download account. Exit your browser, then re-launch and go to our Login page to log in again.

Not sure what he’s doing here:


http://www.laridian.com:80/files/1158044/3MBPG3002/mybible3/program/mb3setup.exe
The filename requested (\mybible3\program\mb3setup.exe) does not match the product (3MBPG3002).

And at this point he admits defeat. Craig 1, hacker 0.

Braces and Indenting: You’re Doing it Wrong

Screen Shot 2014-01-28 at 8.33.08 AMJava, C++, Objective-C, and C# all use braces ( { and } ) to delineate the beginning and end of blocks of code. Over the years, several styles have evolved, with the worst of them dominating the literature. Once you see The Light you’ll wonder how we ever let this get out of hand.

Before we begin, let’s remind ourselves what braces are for: They mark the beginning and end of blocks of code. In many contexts a block stands in place of a single statement. It allows us to put two or more statements in a place where a single statement is called for in the grammar. In those contexts a block is functionally equivalent to the single statement it replaces. This will be important in our understanding of the One Right Way to indent.

In other contexts, such as the bodies of functions, surrounding the cases in a switch statement, and surrounding the declarations in a class definition, braces demarcate the contents of the function, switch, and class. For convenience, I’ll refer to any group of lines of code surrounded by braces as a “block”, even though the language definition may not always use that term in every context in which braces are used.

So the the first question is to ask: “To what do the braces belong: the block they surround or the syntactical element (if, for, switch, class etc.) to which the block belongs?”

When braces are used to surround a true block (the else clause of an if statement, for example), it’s clear the braces belong to the block. Together with the lines of code they contain, they replace a single statement.

The implication is that the braces should be indented at the same level as the lines of code in the block they surround, for they are part of that block.

The second question we need to ask is: “Should braces share the line with any other code; either a statement from the block they surround or the statement the block belongs to?”

Clearly we would not format code like this:

    x
    = y
    +
    z
    ;

We might break a very long line into two or more lines, but a short statement should always be on one line. Similarly, we try to avoid code like this:

    x = y + z; if ( x > 10 ) foo(x); bar(z); switch (y) {case 1: x = 2 * y; break; case 2: default: foo(x); break;}

The commonly accepted practice is to put one statement on each line. (There are exceptions but they are rare.) Similarly, I would argue that braces belong on a line by themselves. They are not “inline operators” like + or ==. They do not belong to the statement to their right or left; they surround those statements.

The reason we don’t put two or more statements on one line is that it is more difficult to read. It’s why we break up our thoughts into sentences and paragraphs. It aids in comprehension. The same is true of code. Consider the following:

    if ( x < 10 ) { foo(x);
        bar(y); }

The call to foo(x) belongs to the then-clause because it is inside the brace but it would be easy to glance at the code and assume bar(y) is the only statement executed when the if-condition is true because the call to foo(x) is “hidden” at the end of the if statement.

For this reason I would argue that braces belong on a line by themselves. It is too easy to miss them when they are “hidden” at the end of another line of code. So unless you’re in the habit of writing a dozen statements on one line, it doesn’t make sense to put a brace on the same line as another line of code.

With these two rules (i.e. braces belong to the block they surround and braces belong on a line by themselves), there’s only One Right Way to indent your code:

    if ( x < 10 )
        {
        foo(x);
        bar();
        }
    else
        {
        x += 10;
        foo(x);
        }

Now we can see why the predominant indenting style is so, so wrong:

    if ( x < 10 ) {    // should not be on same line as "if"; should be indented with block
        foo(x);
        bar();
    } else {              // should not be on same line as else (*2); should be indented like block above/below
        x += 10;
        foo(x);
    }                     // should be indented like block above

I realize those of you who grew up doing this wrong and reading all the literature from others who do it wrong will find the One Right Way more difficult to read. But it can be argued that you only find it difficult to read because you’re not accustomed to doing things the One Right Way, while the wrong style as illustrated above is difficult for me to read because it makes no attempt to be logically consistent. This makes it objectively wrong, not just a matter of personal preference.


Postscript
In the spirit of unity and the cause of world peace, practitioners of the One Right Way will accept the following style with the hope that those practicing it will see the one small error in their way and with proper mentoring and encouragement, will correct it:

    if ( x < 10 )
    {
        foo(x);
        bar();
    }
    else
    {
        x += 10;
        foo(x);
    }

Objective-C Memory Management

Perhaps I’m showing my age, but I’m getting awful tired of language designers trying to improve on C/C++ memory management.

Just for review, here’s how memory management should work:

void foo()
  {
  // x is created on the stack. It is deallocated at the end of
  // the block/function and therefore its lifetime matches its
  // scope with no further effort. 

  int x;

  // pX is a pointer to an int that the programmer creates with
  // new. By using "new", the programmer is taking responsibility
  // for freeing the memory used by pX before it goes out of scope.

  int *pX = new int(0);

  // ... interesting code goes here ...

  // The obligatory delete before we exit the block/function.

  delete pX;

  }

Everything else in C/C++ is a variation on this. You can put pointers and variables in structures and classes/objects but they follow the same rules: If you allocate with new, you must free with delete before you lose track of the memory (i.e. the one and only (or last remaining) pointer goes out of scope).

When we started coding for iOS, we ran into “manual retain/release” which is a variation on the C/C++ technique (or rather, a manual method of the automatic garbage collection used in Mac OS):

@interface bar
  {
  // Like C++, when the pointer is a member (instance) variable, 
  // someone else is responsible for allocating memory for it.

  NSString * memberString;
  NSString * anotherString;
  }

// But if the instance variable is accessible from the outside
// world we can say it's a "property" and some of this is 
// managed for us. 

@property (retain) NSString * memberString;

// Unless we don't specify "retain". Now we're responsible for
// making sure the memory for anotherString is allocated and
// freed.

@property (assign) NSString * anotherString;

@end

@implementation bar

- (void)foo
  {
  // These are the same. They're on the stack and are automatically 
  // released when you exit the method/block.

  int x;

  // This is the equivalent of C/C++ "new", kind of. We can't just
  // do memory allocation without also initializing the object 
  // (handled by new and the constructor in C++, but that's the 
  // subject of a different article). The result is a pointer that
  // we're obligated to release before string goes out of scope.

  NSString * string = [[NSString alloc] init];

  // Another way of doing the same thing, but this time the 
  // resulting pointer is automatically released sometime in
  // the future that we don't care about.

  NSString * arString = [[[NSString alloc] init] autorelease];

  // Yet another way of doing the same thing, but the autorelease
  // is done for us. We can tell because the method name starts
  // with something that looks like the name of the class but
  // without the prefix. Intuitively obvious, right?

  NSString * autoString = [[NSString alloc] stringWithUTF8String:"Automatically released"];

  // Required release

  [string release];
  }

@end

And autorelease isn’t as automatic as you might think. You need to think about whether or not you need to create your own autorelease pool. This is important if you’re going to create a large number of autoreleased variables before returning to the run loop. You may want to manage your own autorelease pool in that case so you can free memory up at more convenient times.

If that’s not ridiculous enough, along comes Automatic Reference Counting (ARC) to “simplify” memory management.

@interface bar
  {
  // Like C++, when the pointer is a member (instance) variable, 
  // someone else is responsible for allocating memory for it.

  NSString * memberString;
  NSString * anotherString;
  }

// Instead of "retain", we create a "strong" reference. Memory
// is freed when this particular instance variable goes out
// of scope (is no longer accessible). 

@property (strong) NSString * memberString;

// We use "weak" instead of "assign" to mean that we understand
// someone else is in control of when this memory gets freed.

@property (weak) NSString * anotherString;

@end

@implementation bar

- (void)foo
  {
  // These are the same. They're on the stack and are automatically 
  // released when you exit the method/block. In reality, they're
  // qualified with __strong by default.

  int x = 10;
  NSString * string = [[NSString alloc] init]; // could add __strong for clarity

  // You can also create weak pointers for some reason:

  NSString * __weak weakString;

  // Unfortunately, that introduces a bug into these lines of code:

  weakString = [[NSString alloc] initWithFormat:@"x = %d", x];
  NSLog(@"weakString is '%@'", weakString);

  // In the code above, weakString is immediately deallocated after
  // it is created because there is no strong reference to it. See
  // how this is getting easier?

  // Not to mention:

  NSString * __autoreleasing arString;
  NSString * __unsafe_unretained uuString;

  // Now we don't have to do this:
  // [string release];
  // And that's really all we saved by introducing "Automatic Reference Counting".
  // At the same time, we created a new way to introduce a bug by failing
  // to have any strong pointers to an object from one line of code to
  // the next.
  }

@end

So we’ve gone from:

new / delete

to

retain / release (or autorelease with no release)

to

strong/__strong/weak/__weak/__autoreleasing/__unsafe_unretained

all in the interest of “simplification” and avoiding having to delete/release the memory we allocate. I frankly don’t see the benefits.

On Open Source License Agreements

While I’m a fan of all the open-source code available on the Internet these days, I sure wish they paid more attention to the licensing agreements to which they require us to agree when we use their code. They’re just confusing. Most just go along with them, but it bothers me enough that I try to avoid them at every turn. Here are some examples with my comments interspersed.

BSD 2-Clause License

Copyright (c) <YEAR>, <OWNER>
All rights reserved.

The parenthesized “c” is not a legal substitute for ©. Fortunately it is not required at all when the word “Copyright” appears. (One of “Copyright”, “Copr”, or © is required in a copyright statement.) The statement “All rights reserved” is redundant and is also not required. These are minor points; they just demonstrate the lack of sophistication of the open source community and those who advise them.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Note that software authors like us who incorporate open-source software into our programs are required to explicitly tell you about the above conditions under the second of those conditions. However, since we don’t distribute the source code, the first condition is irrelevant to you. And since you can’t extract the binary version of the code from our program (it is inextricably compiled and linked into our program in a way that makes it impossible for the end-user to even find, let alone extract), the second condition will never apply to you. Despite these facts, we’re required to tell you the conditions under which you can redistribute this thing that you don’t have, can’t find, and would have no reason to redistribute.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

There are two problems with the above clause. One is that it is unenforceable because you have no way to consent to it. If you are maimed by our program while it is running a line of licensed open-source code, your lawyer would sue the pants off both us and the copyright holder of the open-source code. You would lose, but not because of this clause. It would be because it would be impossible to show that the particular lines of code licensed under this agreement were responsible for your loss of a limb or whatever.

The problem with the BSD licenses is that they really don’t account for 99% of the usage of software components — that is, when they are compiled into another program. It should be sufficient for us to say the following: Portions Copyright <YEAR>, <OWNER>. The owner still gets their attribution and there’s no confusing legalese to confuse an end-user.

MIT License

Here’s another example.

Copyright (c) <year> <copyright holders>

Again, the parenthesized “c” has no legal standing.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

This paragraph defines “the Software” as the files “obtained”. It gives us a list of allowed uses. The construction of the sentence is confusing. If we simplify it by removing what I would call “parenthetical” clauses, we get: “Permission is granted… to deal in the Software without restriction… and to permit persons to whom the Software is furnished to do so, subject to the following conditions”. The question is: Do we have permission to deal in the Software without restriction, or are we subject to the restrictions listed in the paragraph that follows (“subject to the following conditions”)?

One could interpret the paragraph to mean that the person obtaining the software can do two things: First, deal in the Software without restriction, and second, permit other people to do the same but only if the conditions that follow are met. That would mean that a company like ours, which is not distributing the Software (i.e. the files we obtained) is not obligated to meet the conditions of the next paragraph.

One could also interpret the paragraph to mean that the person obtaining the software must always meet the following conditions whether they’re “dealing in the Software” or “permitting other persons to do so”. I think this is the meaning intended by the authors of this license agreement, since users of this form of license seem to believe their copyright notice must be included in any program that makes use of their Software.

The problem, however, with the second interpretation is that it imposes restrictions on those who would “deal in the Software”, and the first part of the statement makes it clear that those who “deal in the  Software” can do so without charge and without restriction.

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

Remember “the Software” is the files “obtained” by the user of the software. We do not distribute copies of those files, and therefore, we do not distribute the Software. So if we interpret the preceding paragraph as saying those who “deal in the Software” are subject to the conditions here (that is, the requirement to include the copyright notice and the permission notice in all copies of the Software), then since we’re not distributing the Software, we’re not obligated to include the copyright statement anywhere in our program (other than leaving it in the original source code, but that is irrelevant to the end user who uses our program).

This paragraph further begs the question, “What is the ‘permission notice’?” The preceding paragraph identifies itself right away as granting permission, so it could be argued that it is the “permission notice”. That leaves the next paragraph in limbo:

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

I would argue that this paragraph, which I would call a “disclaimer”, not “permission”, is for my benefit only and that the preceding paragraphs do not obligate me to pass it along to anyone to whom I might distribute the Software. I’m confident that no open source software author who uses this license agreement does so believing that this disclaimer would not be provided to subsequent recipients of the Software.

I am not a lawyer, but I believe as an expert in computer software and the English language that there is nothing in this license agreement that affects me in any way other than giving me permission to use the product of this open source software author’s work with no attribution, at no charge, and with no restrictions.