Konu hakkında tarihçe:
Makrolar, C dilinden gelen ve ön işleme aşamasında tekrarlanan kod parçalarını otomatik hale getirmenin güçlü bir yolu olarak ortaya çıkmıştır. C++'da kullanımı esneklik sağlarken, tür kontrolü eksikliğinden ve ön işlemcinin işleyişinin belirsizliğinden dolayı birçok gizli tehlike de getirmiştir.
Sorun:
Makroların kullanımındaki ana riskler:
Çözüm:
Modern C++ standartlarında, makrolar yerine inline fonksiyonlar, şablonlar, constexpr, enum class ve constexpr değişkenlerin kullanılması önerilmektedir.
Kod örneği:
// Kötü: #define MAX(a, b) ((a) > (b) ? (a) : (b)) // İyi: template<typename T> constexpr T max(T a, T b) { return a > b ? a : b; }
Anahtar özellikler:
Bir makro, inline fonksiyonundan daha tehlikeli olabilir mi?
Evet. Makro, sözdizimi ve tür kurallarına tabi değildir. Yan etkileri olan parametrelerin geçirilmesi durumunda beklenmedik sonuçlar meydana gelebilir.
#define SQUARE(x) ((x) * (x)) int y = 5; int z = SQUARE(y++); // y iki kez artırılıyor!
#include de bir makro mudur?
Hayır, #include bir ön işleme yönergesidir, ancak makrolar ve include arasında bir ilişki vardır; bir makro aracılığıyla dahil edilen dosyaların listesini değiştirmek mümkündür (şiddetle önerilmez).
Bir makroyu normal bir fonksiyon gibi hata ayıklamak mümkün mü?
Hayır, hata ayıklayıcı makroyu açar ve zaten yerleştirilmiş metni gösterir, ayrı isimlendirilmiş varlıklar yoktur.
Eski kodda yan etkileri bulunan sayısız hesaplama makrosu tanımlanmıştı (örneğin, artırma); bu da yeni işlevlerin kullanımı sırasında tespit edilmesi zor hatalara neden oluyordu.
Artılar:
Eksiler:
Makrolar yeniden yapılandırılırken, şablon ve constexpr fonksiyonlarla değiştirildi ve makro bayrakları yerine enum class kullanıldı.
Artılar:
Eksiler: