Derleyici bir üstbilgi dosyasını kendi başına iki kez içe aktarmaktan neden kaçınamaz?


13

C ++ 'da yeni! Bunu okuyordum: http://www.learncpp.com/cpp-tutorial/110-a-first-look-at-the-preprocessor/

Başlık korumaları

Üstbilgi dosyaları diğer üstbilgi dosyalarını içerebileceğinden, bir üstbilgi dosyasının birden çok kez dahil edilmesine neden olabilir.

Bundan kaçınmak için önişlemci direktifleri yapıyoruz. Ama emin değilim - neden derleyici sadece ... olamaz değil iki kez aynı şeyi ithal?

Başlık korumalarının isteğe bağlı olduğu göz önüne alındığında (ancak görünüşe göre iyi bir uygulama), neredeyse bir şeyi iki kez içe aktarmak istediğinizde senaryolar olduğunu düşündürüyor. Her ne kadar böyle bir senaryo düşünemiyorum. Herhangi bir fikir?


MS derleyicisinde #pragma once, derleyiciye bu dosyayı yalnızca bir kez eklemesini söyleyen dosya vardır.
CodesInChaos

Yanıtlar:


27

Yeni diller tarafından gösterildiği gibi yapabilirler.

Ancak, tüm yıllar önce bir tasarım kararı verildi (C derleyicisi birden fazla bağımsız aşama olduğunda) ve şimdi uyumluluğu korumak için ön işlemcinin eski kodun beklendiği gibi derlendiğinden emin olmak için belirli bir şekilde hareket etmesi gerekiyor.

C ++, C'den başlık dosyalarını işleme biçimini devraldıkça aynı teknikleri sürdürdü. Eski bir tasarım kararını destekliyoruz. Ancak çalışma şeklini değiştirmek çok risklidir, çok sayıda kod potansiyel olarak kırılabilir. Bu yüzden şimdi yeni kullanıcılara dil muhafızlarının nasıl kullanılacağını öğretmeliyiz.

Kasıtlı olarak birkaç kez dahil ettiğiniz başlık dosyalarına sahip birkaç püf noktası vardır (bu aslında kullanışlı bir özellik sağlar). Yine de paradigmayı sıfırdan yeniden tasarlasaydık, bunu dosyaları dahil etmenin varsayılan olmayan yolu yapabiliriz.


7

Aksi takdirde, C ile uyumluluğu sürdürmeyi ve böylece geleneksel bir paketleme sisteminden ziyade bir önişlemciyi kullanmaya devam etmeyi seçtikleri kadar anlamlı olmazdı.

Aklıma gelen şeylerden biri API olan bir projem olması. İki başlık dosyam vardı x86lib.hve x86lib_internal.h. Dahili büyük olduğundan, "genel" bitleri x86lib.h'ye ayırdım, böylece kullanıcılar derleme için fazladan zaman ayırmak zorunda kalmadılar.

Bu bağımlılıklar ile komik bir sorun tanıttı ama ben x86lib_internal böyle bir akış vardı sona erdi

  1. DAHİLİ önişlemci tanımını ayarlama
  2. X86lib.h (dahili tanımlandığında belirli bir şekilde hareket etmek akıllıca)
  3. Bazı şeyler yapın ve x86lib.h dosyasında kullanılan bazı şeyleri tanıtın
  4. Önişlemci tanımından SONRA ayarla
  5. X86lib.h dosyasını tekrar ekleyin (bu sefer x86lib_internal öğelerine bağlı ayrılmış bir AFTER bölümü hariç her şeyi yok sayacaktı

Bu konuda en iyi yol olduğunu söyleyemem, ama istediğimi elde etti.


0

Otomatik yinelenen başlık dışlamasıyla ilgili bir zorluk, C standardının dosya adlarının ne anlama geldiği konusunda nispeten sessiz olmasıdır. Örneğin, derlenen ana dosyanın yönergeler içerdiğini #include "f1.h"ve #include "f2.h"bu yönergeler için bulunan dosyaların her ikisinin de içerdiğini varsayalım #include "f3.h". Eğer f1.hve f2.hfarklı dizinlerde, ancak arama yaparak bulundu o zaman belirsiz olurdu yolları dahil #includebu dosyaların içindeki yönergeler aynı yüklemek için amaçlanan edildi f3.hdosyası veya farklı olanları.

Göreli yollar da dahil olmak üzere dosya ekleme olanaklarına eklenirse işler daha da kötüleşir. Üstbilgi dosyalarının iç içe yerleştirme için göreli yollar kullandığı bazı durumlarda ve bir kişinin sağlanan üstbilgi dosyalarında herhangi bir değişiklik yapmaktan kaçınması durumunda, bir üstbilgi dosyasının bir projenin dizin yapısı içinde birden çok yerde çoğaltılması gerekebilir. Bu başlık dosyasının birden çok fiziksel kopyası mevcut olsa da, bunlar semantik olarak tek bir dosya gibi değerlendirilmelidir.

Eğer #pragma onceyönerge takip etmek bir tanımlayıcı izin oncetanımlayıcı önceki bir-karşılaştı birini eşleşirse derleyici dosyayı atlamak gerektiğini semantik ile, #pragma onceyönerge, sonra semantik net olurdu; bir #includedirektifin aynı #pragma onceetiketli dosyayı daha önceki bir dosyayla yükleyeceğini söyleyebilen bir derleyici , dosyayı tekrar açmadan atlayarak biraz zaman kazandırabilir, ancak dosya atlanıp atlanmayacağı için böyle bir algılama semantik olarak önemli olmaz. veya dosya adı eşleşme olarak tanınmadı. Ancak bu şekilde çalışan herhangi bir derleyicinin farkında değilim. Bir derleyiciye sahip olmak, bir dosyanın kalıpla eşleşip eşleşmediğini gözlemleyin #ifndef someIdentifier / #define someIdentifier / #endif [for that ifndef] / nothing followingve yukarıdaki gibi bir şeye yukarıdaki gibi #pragma once someIdentifierdavranınsomeIdentifier tanımlı kalır, esasen iyidir.

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.