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. :)