Macros in C

written by Martin Häcker on

(Zu "Feuer Frei" von Rammstein)

Makros in C sind ja so eine Sache.

Zum einen kommt man in C an vielen Stellen gar nicht ohne aus, da sie die einzige Möglichkeit sind Ausdrücke OHNE sie zu evaluieren an mehreren stellen zu verwenden. Zum anderen Sind sie rein Textuell, "unhygienisch" und haben keine Ahnung was in ihnen eigentlich passiert.

Das macht vor allem in Objective-C mächtig Schwierigkeiten. Das hier zum Beispiel geht nicht.

#define DO(argument) argument

DO([NSString stringWithFormat:@"%s", "asdf"]);

Der Compiler meckert hier über zu viele Kommas und denkt das ich das Makro mit zwei Argumenten aufrufen will. Gnah.

Warum beschäftigt mich das eigentlich?

Ich möchte gerne Macro's haben, die je nach Typ des Arguments etwas anderes machen. Für Unit-Tests z.B. möchte ich sagen:

- (void) testOverloadedAssert
{
    ASSERT_EQUALS(3, 3);
    ASSERT_EQUALS(@"barf", @"barf");
    ASSERT_EQUALS("bar", "bar");

    // These should fail in a sensible manner
    ASSERT_EQUALS("bar", @"bar");
    ASSERT_EQUALS(3, 3.3);
}

Das ist aber schon ein großes Problem. In C++ könnte man den ersten teil ja noch über überladene Funktionen lösen - das geht in reinem Objective-C aber schon mal nicht. Dazu kommt ja noch der zweite Teil - da kriegt man vielleicht noch Compiler-Fehlermeldungen, wenn der Compiler nicht auto-conversion von Parametern anwirft. :-/

Dazu kommt, das ich C++ nicht mag und schon gar nicht in alle meine Tests eine zwingende Abhängigkeit auf C++ einfügen will.

Will man dann aber noch weiter gehen, wird es endgültig schwierig. Hier ein paar Beispiele:

- (void) testAdvancedAssert
{
    ASSERT_EQUALS(3.3, 3.3, 0.1 /* accuracy */);
    ASSERT_EQUALS(3.3, 3.3, @"important meta information");
    ASSERT_EQUALS(3, 3, @"info contains: %@ in %s:%d",
         @"other info", __PRETTY_FUNCTION__, __LINE__);
}

In reinem C hätte man hier gar keine Möglichkeiten mehr etwas zu machen.

Wie weit ich mit einer Lösung dennoch gekommen bin - morgen. :)