August 2010 Archives


| 1 Comment

errno is a macro on OS X and expands to this:

#define errno (*__error())

The reason for this is for thread safety. That means that in the debugger, if you want to see what the current value of errno is, you can type:

p *(int *)__error()

It’s important to remember that if you’re using errno, any system call can reset it. The following code is broken:

NSLog (@"errno: %d", errno);
if (errno == EIO)

The call to NSLog can, and probably will, reset errno. On 10.6 calls to the free library function (which NSLog can call) will usually reset errno to 2 (ENOENT), so bear this in mind if you’re seeing an errno value of 2 when you wouldn’t expect it.

As a consequence of this, you cannot single step through code in Xcode when you have “Use Data Formatters” checked, and expect errno to be preserved. You will find in many cases errno is reset to 2. In fact, I would recommend turning off “Use Data Formatters”—they cause many problems. Hopefully lldb will bring a non-invasive method of inspecting variables.

Was this post born from bitter experience? Yes it was.

Compile Time Checks

| 1 Comment

Here’s a handy macro you can use to do compile time checks:

#define CHECK__(line, x) typedef char check_##line##_[(x) ? 1 : -1];
#define CHECK_(line, x) CHECK__(line, x)
#define CHECK(x) CHECK_(__LINE__, (x))

You’ll get a compiler error if the check is false. Obviously the condition needs to be something the compiler can figure out at compile time. You might use it like this:

#pragma pack(push, 1)
struct x {
  uint8_t  a;
  uint32_t b;
#pragma pack(pop)

CHECK (sizeof (struct x) == 5)

I use it to check sizes of structures that have to match a protocol or format, for example, on disk structures that you know are supposed to be 512 bytes in size.