Koşullu derleme için kısayol olarak C / C ++ makroları kullanmak iyi bir uygulama mı?


13

Diyelim ki kodumda birkaç tür çıkış mesajı var. Bunlardan biri DEBUG, kod Hata Ayıklama modunda derlendiğinde yalnızca yazdırılır.

Genellikle şöyle bir şey yazmam gerekirdi

#ifdef DEBUG
    std::cout << "Debug message" << std::endl;
#endif

birçok yerde kullanmak oldukça hantal ve sinir bozucu.

Kod pasajı için bir makro tanımlamak iyi bir uygulamadır, bu yüzden onu bu şekilde kullanırsınız?

MSG_DEBUG("Debug message")

Yoksa makrolarla başa çıkmanın daha zarif bir yolu var mı? Her iki dili de farklı projelerde kullandığım için hem C hem de C ++ ile olası çözümlerle ilgileniyorum.



Koşullu kodu neden sadece bir fonksiyona koymayacağınız ve bunu çağırmayacağınız sorusundan net değil. Bunu engelleyecek başka bir kısıtlama var mı?
Alex

@gnat Bahsettiğiniz soru o kadar geniştir ki, çoğu insan bu konuyla, özellikle de internette bu özel soruyu ararken onlar ile bağlantı kurmaz.
Eenoku

3
Sorunuz hem etiketlenmiş c ve c ++ , ancak, bu oldukça farklı dillerdir. Hangisinden bahsettiğinizi açıklayabilir misiniz? Örneğiniz C'de mükemmel olur, ancak constexpr iförneğin C ++ ' da daha iyi uygulanabilir .
Jörg W Mittag

1
Bir yana, teşhis gitmeli STDERR. Ayrıca, bunun yerine neden olduğu NDEBUGgibi bağımlı hale assert()getirmiyorsunuz? Daha sonra bunu #define DEBUG_MSG(MSG) assert(std::cerr << MSG), akış durumunu da test eden gibi tanımlayabilirsiniz .
Tekilleştirici

Yanıtlar:


19

Tabii, ilk etapta makroları kullanmakta sorun yaşıyorsanız, aynı koşullu kodu tekrarlamak yerine parametreli bir tane tanımlamak, iyi kodlamanın herhangi bir ölçüsü tarafından kesinlikle tercih edilir.

Hiç makro kullanmalı mısınız? Benim görüşüme göre, C'de pratik olarak kabul edildiğinden ve makro içermeyen herhangi bir çözüm , hata ayıklama modunun dışında bile en azından bir şey yürütülmesini gerektirecektir . Tipik C programcısı gereksiz çalışma zamanı çabasıyla biraz çirkin bir makro seçer.


13

Burada kişisel tercih unsuru var, ama C ++ 'da bunu başlık dosyasında yapmayı tercih ediyorum:

#ifdef _DEBUG
    void DebugMessage(...);
#else
    inline void DebugMessage(...) {}
#endif

Böylece işlev sürüm derlemelerinde satır içine alınır, ancak hata ayıklama derlemesinde uygun bir işlevdir, böylece daha sonra uygun tür denetimi, mantıklı hata iletileri, vb.

Açıkçası, işlevin karşılık gelen tanımını .cppbir #ifdef _DEBUGblokta da içermeniz gerekir .


Ama burada genel çağrı var, değil mi?
Eenoku

7
Derleyiciniz bir sürüm derlemesinde bilinen boş bir işlevi çağırmak için kod üretecekse, verimliliği artırmak için yapmanız gereken ilk ve en büyük şey çok daha iyi bir derleyici almaktır. Bu gerçekten önemsiz bir optimizasyon.
David Thornley

@Eenoku Hayır, David'in dediği gibi, kullanmanız gereken herhangi bir derleyici tarafından kaldırılacaktır.
Jack Aidley

3
Burada önemli bir fark var: makro (nasıl yazıldığına bağlı olarak) argüman ifadelerini değerlendirmezken, işlev her zaman yapardı. Ayrıca, önemsiz olmayan argümanları varargs işlevlerine geçirmek tanımsız bir davranıştır (ve genellikle derleyici uyarılarını tetikler).
Sebastian Redl


2

Kesinlikle, ekibiniz tarafından verilen kod yönergelerine adım atmadığınızdan emin olun. Sistemdeki başka hiçbir kodun genel if koşulu üzerinden aynı işlevselliğe ulaşmaya çalışmadığından emin olun.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.