Standart C Programlama Dili


9.24. tgmath.h: Tip Genel Matematik

C Standardına nispeten yeni bir ekleme olan _Generic işleci ile belirli bir ifadenin tipine göre ifade seçimi yapma olanağı gelmiştir. Genel sözdizim şöyledir:

_Generic ( kontrol-ifadesi ,
  tip-ismi_1 : ifade_1 ,
  tip-ismi_2 : ifade_2 ,
  
  default : ifade_def
)

Burada, en başta verilen kontrol-ifadesi’nin tipine bakılır; kontrol-ifadesi hiçbir şekilde hesaplanmaz, sadece derleyici tarafından tipi belirlenir. Belirlenen tip devamında verilmiş olan tip-ismi : ifade ikililerinden hangi birine uyuyorsa, oradaki ifade hesaplanır ve değeri _Generic işlecinin sonucu olur. Belirlenen tip verilmiş olan herhangi bir tip-ismine denk gelmiyorsa, iki olasılık söz konusudur: Eğer default tipi verildiyse, o zaman arkasındaki ifade_def hesaplanır ve kullanılır. Eğer default tipi verilmediyse, derleyici hata verir. _Generic işleci ile ilgili anlatılan bu işlemlerin derleme sırasında yerine getirildiğine dikkat edin.

_Generic işleci daha çok önişlemci makrolarında kullanılır. Örneğin, aşağıda verilen programda BAS makrosu, verilen argümanın tipine bakarak, uygun bir şekilde değerini bastırmaya çalışır:

#include <stdio.h>

#define BAS(X) (printf(  \
 _Generic((X),           \
   char: "Karakter: %c\n",       \
   char *: "Karakter dizisi: %s\n",     \
   int: "Tamsayi: %d\n",         \
   short: "Kisa tamsayi: %hd\n", \
   long: "Uzun tamsayi: %ld\n",  \
   long long: "Cok uzun t.s.: %lld\n",  \
   double: "Cift duyarlikli: %f\n",     \
   long double: "Uzun c.d.: %Lf\n",     \
   void *: "Gosterge: %p\n",     \
   default: "Bilinmeyen!\n"      \
 ), (X)))

int main (void)
{
  BAS((char)'A');
  BAS("BCD");
  BAS(1);
  BAS((short)2);
  BAS(3L);
  BAS(4LL);
  BAS(5.0);
  BAS(6.0L);
  BAS((void *)"EFG");
  BAS(main);
}

tgmath.h başlık dosyasında, yukarıda verilen örneğe benzer şekilde, tipten bağımsız olarak tek isimle çağrılabilecek makrolar tanımlanmıştır. Bu makrolar, argümanın tipine bakarak math.h ve complex.h dosyalarında değişik tipler için tanımlanmış olan uygun fonksiyonu çağırırlar. Makro ismi olarak, bu dosyalarda double tipi için verilmiş olan isim kullanılır. Örneğin, fabs makrosu, verilen argümanın tipine göre fabsf, fabs, fabsl, cabsf, cabs veya cabsl fonksiyonunu çağırır. Makro listesi şöyledir:

acos        cosh        fmin        log1p       rint
acosh       erf         fmod        log2        round
asin        erfc        frexp       logb        scalbln
asinh       exp         hypot       lrint       scalbn
atan        exp2        ilogb       lround      sin
atan2       expm1       ldexp       nearbyint   sinh
atanh       fabs        lgamma      nextafter   sqrt
cbrt        fdim        llrint      nexttoward  tan
ceil        floor       llround     pow         tanh
copysign    fma         log         remainder   tgamma
cos         fmax        log10       remquo      trunc