Zum Beispiel bin ich kürzlich im Linux-Kernel auf Folgendes gestoßen:
/* Force a compilation error if condition is true */ #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
Wenn Sie also in Ihrem Code eine Struktur haben, die beispielsweise ein Vielfaches von 8 Bytes groß sein muss, möglicherweise aufgrund einiger Hardwareeinschränkungen, können Sie Folgendes tun:
BUILD_BUG_ON((sizeof(struct mystruct) % 8) != 0);
und es wird nicht kompiliert, es sei denn, die Größe von struct mystruct ist ein Vielfaches von 8, und wenn es ein Vielfaches von 8 ist, wird überhaupt kein Laufzeitcode generiert.
Ein weiterer Trick, den ich kenne, stammt aus dem Buch “Graphics Gems”, der es einer einzelnen Header-Datei ermöglicht, Variablen in einem Modul sowohl zu deklarieren als auch zu initialisieren, während sie in anderen Modulen, die dieses Modul verwenden, lediglich als extern deklariert werden.
#ifdef DEFINE_MYHEADER_GLOBALS #define GLOBAL #define INIT(x, y) (x) = (y) #else #define GLOBAL extern #define INIT(x, y) #endif GLOBAL int INIT(x, 0); GLOBAL int somefunc(int a, int b);
Damit macht der Code, der x und somefunc definiert:
#define DEFINE_MYHEADER_GLOBALS #include "the_above_header_file.h"
während Code, der nur x und somefunc() verwendet, Folgendes tut:
#include "the_above_header_file.h"
Sie erhalten also eine Header-Datei, die sowohl Instanzen von Globals als auch Funktionsprototypen dort deklariert, wo sie benötigt werden, sowie die entsprechenden externen Deklarationen.
Also, was sind Ihre liebsten C-Programmiertricks in dieser Richtung?
Dies scheint eher ein C-Präprozessor-Trick zu sein.
– Jmucchiello
1. März 2009 um 10:24 Uhr
Um
BUILD_BUG_ON
Makro, was ist falsch an der Verwendung#error
innen und#if
?– Ricardo
15. Oktober 2011 um 11:46 Uhr