Bu kılavuzda bir işlev olarak bahsettiğimiz bazı şeyler aslında bir makro tanımı olabilir. Bu durum makro tanımı da işlevin yaptığını yaptığından yazılımın çalışması açısından bir sorun çıkmaz. Kütüphane işlevlerinin makro eşdeğerlerinin argümanları işlev çağrılarındaki gibi değerlendirilir. İşlev tanımları yerine bu makro tanımlarının yapılmasının sebebi, makrolar satıriçi sembolik dile özgü yorumlar şeklinde üretebildiğinden, bir işlevden daha hızlı çalışabilmeleridir.
Bir kitaplık işlevinin adresini almak, bu bir makro olarak tanımlanmış olsa bile çalışır. Bu bağlam içerisinde çalışmasının sebebi, işlevin adından sonra, bir makro çağrısını tanımak için gereken sol parantezin olmamasıdır.
Kimi zaman bir makro tanımının bir işlev olarak kullanılmasını istemeyebilirsiniz. Bu, yazılımınızda hata ayıklamayı kolaylaştırır. Bunu yapmanın iki yolu vardır:
Makro çağrılarına özel olarak, işlev ismini parantez içine alarak bir makro tanımından kurtulabilirsiniz. Bunun çalışmasının sebebi işlev isminin sözdizimsel olarak artık bir makro çağrısı olarak algılanmamasıdır.
Makro tanımını kaynak kodunuzun içinde #undef önişlemci deyimi ile (oluşumun açıklamasında aksi belirtilmediği sürece) devredışı bırakabilirsiniz.
Örneğin, stdlib.h başlık dosyasında abs isimli bir işlevin bildirimi olduğunu kabul edelim:
Ve, abs için bir makro tanımı olsun:
#include stdlib.h
int f (int *i) { return abs (++*i); }
Burada abs, hem bir makro hem de bir işlevdir. Aşağıdaki örneklerde ise abs sadece bir işlevdir, bir makro değildir.
#include stdlib.h
int g (int *i) { return (abs) (++*i); }
#undef abs
int h (int *i) { return abs (++*i); }
Makro tanımları, asıl işlevin yaptığını yapmaktan başka bir makro da tanımladığından bu yöntemlere gerçekte hiç ihtiyaç yoktur. Ayrıca, bir makro tanımının kaldırılması yazılımınızın daha yavaş çalışmasına sebep olacaktır.