Birkaç açıklama. Birincisi geneldir, ikincisi ise parametrelere sahip C önişlemci makrolarına özeldir:
Akış kontrolü
Bunun düz C kodunda kullanıldığını gördüm. Temel olarak, goto'nun daha güvenli bir sürümüdür, çünkü ondan çıkabilirsiniz ve tüm bellek düzgün bir şekilde temizlenir.
Neden böyle bir şey goto
iyi olsun? Her çizgi bir hata döndürebilir hemen hemen kuralların var ama hepsini aynı şekilde tepki gerekiyorsa Eh, (örneğin teslim temizlemeye sonra arayana hata ile), bir önlemek için genellikle daha okunabilir var if( error ) { /* cleanup and error string generation and return here */ }
olduğu temizleme kodunun tekrarlanmasını önler.
Bununla birlikte, C ++ 'da tam olarak bu amaç için istisnalar + RAII var, bu yüzden kötü kodlama stili olduğunu düşünürdüm.
Noktalı virgülle kontrol
Fonksiyon benzeri bir makro çağırmadan sonra noktalı virgülü unutursanız, bağımsız değişkenler istenmeyen bir şekilde daralabilir ve geçerli sözdiziminde derlenebilir. Makroyu hayal edin
#define PRINT_IF_DEBUGMODE_ON(msg) if( gDebugModeOn ) printf("foo");
Buna yanlışlıkla denir
if( foo )
PRINT_IF_DEBUGMODE_ON("Hullo\n")
else
doSomethingElse();
"Diğer" ile ilişkili olarak kabul edilecek gDebugModeOn
, yani olduğu zaman foo
, false
amaçlananın tam tersi gerçekleşecektir.
Geçici değişkenler için bir kapsam sağlamak.
Do / while küme parantezi içerdiğinden, geçici değişkenlerin açıkça tanımlanmış kapsamı vardır ve kaçamazlar.
"Muhtemelen istenmeyen noktalı virgül" uyarılarından kaçınma
Bazı makrolar yalnızca hata ayıklama yapılarında etkinleştirilir. Onları şöyle tanımlıyorsunuz:
#if DEBUG
#define DBG_PRINT_NUM(n) printf("%d\n",n);
#else
#define DBG_PRINT_NUM(n)
#endif
Şimdi, bunu bir koşullu içinde bir sürüm yapısında kullanırsanız,
if( foo )
;
Birçok derleyici bunu şu şekilde görür:
if( foo );
Genellikle yanlışlıkla yazılır. Yani bir uyarı alırsınız. Do {} while (false) bunu derleyiciden gizler ve burada gerçekten hiçbir şey yapmak istemediğinizin bir göstergesi olarak kabul edilir .
Koşullu satırların yakalanmasından kaçınmak
Önceki örnekten makro:
if( foo )
DBG_PRINT_NUM(42)
doSomething();
Şimdi, bir hata ayıklama yapısında, alışılmış bir şekilde noktalı virgülü de eklediğimiz için, bu gayet iyi derlenir. Bununla birlikte, sürüm yapısında bu aniden şuna dönüşür:
if( foo )
doSomething();
Veya daha net biçimlendirilmiş
if( foo )
doSomething();
Hangi hiç amaçlanmadı. Makronun etrafına bir do {...} eklenmesi (false) eksik noktalı virgülü bir derleme hatasına dönüştürür.
Bu, OP için ne anlama geliyor?
Genel olarak, hata işleme için C ++ 'da istisnaları ve makrolar yerine şablonları kullanmak istersiniz. Bununla birlikte, makrolara hala ihtiyaç duyduğunuz (örneğin, simge yapıştırmayı kullanarak sınıf adları oluştururken) veya düz C ile sınırlı olduğunuz çok nadir durumlarda, bu yararlı bir kalıptır.