Archive for the 'GCC' Category

Weirdest compiler warning I’ve ever seen

Saturday, February 9th, 2008

Here's the code:

[[GrowlApplicationController sharedController] setQuitAfterOpen:YES];

And here's the warning:

Core/Source/GrowlApplicationBridgePathway.m:43: warning: ‘GrowlPreferencesController’ may not respond to ‘-setQuitAfterOpen:’

Wait, what? I said GrowlApplicationController, not GrowlPreferencesController!

The problem is that the compiler is recognizing “sharedController” as a class method, and assuming that I'm using the class that it knows has it—which, in this case, is GrowlPreferencesController. GrowlPreferencesController is declared in its header, which is imported by the prefix header; GrowlApplicationController, meanwhile, is declared only with @class (in another header). So I think it's assuming that GrowlApplicationController is a subclass or something.

However, +[GrowlPreferencesController sharedController] is typed as returning a GrowlPreferencesController *, so when I try to call a GrowlApplicationController method on it, it gives me that warning.

The fix is to #import "GrowlApplicationController.h" so that the compiler knows that GrowlApplicationController has a sharedController method of its own.

WWDC 2007 session videos are out

Monday, July 30th, 2007

If you attended WWDC, you can head over to ADC on iTunes and see what you missed.

A simple way to make your NSLogs and NSAsserts more informative

Wednesday, June 13th, 2007

OK, so I'm not totally radio-silent. I learned about this in a WWDC session, but since it's already public API in Tiger (actually, it's a GCC extension), I can talk about it.

It's a built-in macro called __PRETTY_FUNCTION__. This is a fully-qualified human-readable signature of the function you're in. The GCC docs don't mention this part, but it even works in Objective-C, in addition to C++ and plain C. Here's a test app, containing this code:

@implementation Blah(blah)
- (void)blah {
    NSLog(@"%s", __PRETTY_FUNCTION__);
}
@end

And the output:

2007-06-14 07:50:37.733 printmethod[1800] -[Blah(blah) blah]

Notice that it includes the class name, category name (if any), and method selector.

Note that that's a C-string, not an NSCFString. Be sure to set up your format string accordingly.

Why you should use #pragma mark

Saturday, January 20th, 2007

It's a minute and a half, and it's 200 K, and you'll need QuickTime 7 to watch it.


pragma mark at work in Xcode's editor.

Useful as #pragma mark is, I wouldn't recommend it for cross-platform code. GCC's documentation of #pragma mark seems to suggest that it's Darwin-only.

On initializing static variables

Thursday, January 4th, 2007

Did you know that you don't have to initialize static variables? (If you've done any Cocoa programming, you know that statics are commonly treated as class ivars, most commonly to hold singleton instances.)

Quoth C99 (§6.7.8 paragraph 10):

… If an object that has static storage duration is not initialized explicitly, then:

  • if it has pointer type, it is initialized to a null pointer;
  • if it has arithmetic type, it is initialized to (positive or unsigned) zero;
  • if it is an aggregate [array or structure —PRH], every member is initialized (recursively) according to these rules;
  • if it is a union, the first named member is initialized (recursively) according to these rules.

And I've prepared a test app that shows that gcc 4.0.1 on OS X 10.4.8 does seem to comply with this handy part of the standard.

Happy not-initializing!

Making GCC use proper quote marks

Tuesday, September 19th, 2006

When you build a program in Xcode, you may have noticed that error messages from GCC look like this:

error.c: In function `main':
error.c:2: warning: implicit declaration of function `pirntf'

This shouldn't happen on a modern operating system with modern text capabilities. Fortunately, it is easy enough to make it do the Right Thing, which is to use Unicode quote marks.

First, figure out the correct ISO 639-1 language code for your preferred language. I use English, so mine is “en”. The Library of Congress has a list of ISO 639-1 language codes. In addition, you may want to append a region code; I use American English, so mine is “US”. These should be separated by an underscore; my full language specifier, then, is “en_US”.

Then, append “.UTF-8” to this (= “en_US.UTF-8”), and set it in your LC_ALL environment variable. You can do this by adding this variable to $HOME/.MacOSX/environment.plist. If you don't already have one, you can create it with Property List Editor; you will need to move it to the proper location with Terminal. Either way, you will then need to logout and login.

GCC will then use nice Unicode quote marks in its output:

error.c: In function ‘main’:
error.c:2: warning: implicit declaration of function ‘pirntf’

There's extra work to do if you also invoke builds from Terminal or xterm (whether you use xcodebuild, make, or gcc directly).

Terminal

  1. Right-click on any Terminal window and choose “Window Settings…”.
  2. Switch to the “Display” pane.
  3. Set the character set encoding to UTF-8.
  4. Turn off “wide glyphs for Japanese/Chinese/etc.”.
  5. Click “Use Settings as Defaults”.

xterm

  1. In your .Xdefaults file, add these lines:

    xterm*font:        -*-clean-medium-r-*-*-12-*-*-*-*-*-iso10646-*
    xterm*boldFont:    -*-clean-bold-r-*-*-12-*-*-*-*-*-*-*
    xterm*utf8:        1

    Note that you can specify any font for the two font values; however, “clean”'s Unicode version only exists in plain, not boldface.

Parsing the preprocessor

Thursday, June 15th, 2006

If you've ever run GCC's preprocessor alone and looked at its output, you've seen lines like these:

# 1 "/usr/include/sys/types.h"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "/usr/include/sys/types.h"
# 66 "/usr/include/sys/types.h"
# 1 "/usr/include/sys/appleapiopts.h" 1 3 4
# 67 "/usr/include/sys/types.h" 2


# 1 "/usr/include/sys/cdefs.h" 1 3 4
# 70 "/usr/include/sys/types.h" 2

And you probably wondered what all that means. Here's your secret decoder ring.

First, these are called "line markers" in libcpp. The format of a line marker is:

  1. A line number
  2. The path to the relevant file
  3. Flags

The flag values are:

1
Push (enter) header
2
Pop (leave) header
3
This is a system header (determined by these rules with this modification)
4
Requires extern "C" protection (determined by the same rules as above); never found without 3

Note that a pop applies to the header above (in the include stack) the one referenced in the marker.

Example:

# 66 "/usr/include/sys/types.h"
# 1 "/usr/include/sys/appleapiopts.h" 1 3 4
# 67 "/usr/include/sys/types.h" 2
  1. Fast-forward to line 66 of <sys/types.h> (nothing interesting occurs before this line).
  2. Enter <sys/appleapiopts.h>. Everything from this point until the next marker is from that header. Note that this header is a system header (3) and requires extern "C" protection (4).
  3. As it turns out, nothing interesting happened there. So the very next line is a pop marker: <sys/appleapiopts.h> is popped, so now we're back in <sys/types.h>, now on line 67 (the line after the #include <sys/appleapiopts.h>).

The relevant code in libcpp is in directives.c. The function that parses line markers (presumably used by the compiler rather than the preprocessor itself; the preprocessor generates them) is do_linemarker. Additional include-related code is in files.c.

UPDATE 23:24 PDT: Beware of pragmas. Seems obvious now, but I didn't think of it earlier: The preprocessor leaves #pragma directives untouched, being that they're for the compiler rather than the preprocessor. So if you're only looking for line markers, you may get tripped up if you don't properly handle/ignore a pragma.

Technorati tags: , , .

Report-an-Apple-bug Friday! 36

Friday, April 28th, 2006

This bug is -mtune (Instruction Scheduling) does not include Intel processors. It was filed on 2006-04-28 at 00:35 PDT.


Summary:

With the move to Intel processors, Xcode needs to support processor-specific optimization for them.

Steps to Reproduce:

  1. Get info on a target or project.
  2. Switch to the Build tab.
  3. Change the active Collection to one that includes GCC/Code Generation.
  4. Edit the "Instruction Scheduling" setting.

Expected Results:

At least pentium-m is listed, being (presumably) the most similar to Yonah (the "Core Solo"/"Core Duo" processors). Ideally, scheduling optimizations for Yonah itself should be added to GCC, with a matching listing in Xcode's pop-up menu.

Actual Results:

Only G3, G4, and G5 are listed (besides "None").

Regression:

This wasn't a problem before the move to Intel.

Notes:

Direct Yonah support isn't supported by GCC (yet) according to the GCC manual's page "i386 and x86-64 Options". GNU's current documentation doesn't list it either.


Technorati tags: ,

Report-an-Apple-Bug Friday! 3 (repost)

Saturday, February 4th, 2006

fie on Blogger. this post isn't visible from the front page or the Dashboard, even though it exists. so I'm reposting it.

UPDATE 2006-02-25: it has been closed as a duplicate.


C99 escapes in Obj-C string contain UTF-8 interpreted as an 8-bit encoding. as last time, edited only for HTMLification.

Summary:

since C99, C has a \u escape for Unicode characters. for example, a snowman is \u2603.

when used in an Obj-C string literal (@"foo"), however, these escapes are broken.

Steps to Reproduce:

  1. write a program that displays a string, created from an Obj-C string literal containing a Unicode escape.
  2. compile it.
  3. run it.
  4. observe the display of the string.

Expected Results:

the Unicode character is displayed as such.

Actual Results:

the Unicode character's UTF-8 representation is displayed in some 8-bit encoding (possibly ISO 8859-1).

Regression:

none known.

Notes:

the bug only occurs in Obj-C string literals, not plain C string literals.

it appears that the compiler uses UTF-8 for internal storage, which works. NSConstantString, however, seems to expect ISO 8859-1, and interpret its input as such.

the enclosed tarball contains test programs (command-line) in plain C (using printf) and Obj-C (using NSLog). the plain C version works; the Obj-C does not.

I found the bug when displaying an Obj-C constant string (which had been passed through NSLocalizedString, but there is no matching localisation for it yet) as an NSMenuItem's title. so the problem is not specific to terminals or Terminal's display, nor dependent on the value of any locale environment variables.


I also attached two test cases.