2011-09-30 18 views
8

Şu anda, belirli dizeleri bu dizelerin karmalarını değiştirmemi gerektiren bir kod projesi üzerinde çalışıyorum. Bu dizeler çalışma zamanında değişmeyeceği için, ön işlemcinin, derleme zamanında karma olduğunu beyan ettiğim her dizimde karma işlevimi çalıştırması avantajlı olacaktır.Derleme sırasında C önişlemcisi kod yürütme nasıl yapılır?

C önişlemcisini derleme zamanında karma işlevimi çalıştırmak için herhangi bir yolu var mı?

Bunun yukarıda açıkladığım şekilde çalışmadığını biliyorum, ancak nereye gideceğim hakkında bir fikir edinmek için, bir makro kullanan bazı sözde kodlar. yerine basitçe makro genişletme, önişlemci karma işlevi koştu ve o hash fonksiyonu dönüş değerine genişletilmiş düşünün: Yine

#include <iostream> 
    #include <string> 

    #define U64_HASH(inputString) getU64HashCode(inputString) 

    //my hash function 
    unsigned long long getU64HashCode (string inputString) 
    { 
     /*code*/ 
    } 

    int main() 
    { 
     cout << U64_HASH("thanks for helping me") << endl; 
     return 0; 
    } 

, ideal olarak cout << U64_HASH("thanks for helping me") << endl; yazdım cout << 12223622566970860302 << endl;

kadar genişleyip Bir başlık dosyası üreticisi ve bu proje için iyi çalışıyor.

Nihai Çözüm

Ben sadece müthiş olduğu gibi bu proje için John Purdy's perl script kullanmaya karar ve bana derleyiciye doğrudan istediğiniz çıktıyı beslemek için izin verir var. Çok sağol John.

+0

Değil çılgın büyü olmadan. –

+0

C++ 11, kullanıcı tanımlı hazır bilgi ve dizinlere sahiptir. Bunlar yardımcı olabilir. – Pubby

+1

her zaman bu dizeleri karma olarak tanımlayabilirdiniz? AFAIK C ön işlemcinin kod çalıştırma yeteneği yoktur. – Serdalis

cevap

6

bir yolu bir başlık dosyası içine tüm dizeleri koymak ve onlara isim etmektir senin StringHeader.h program her dize karma ve yedek başlık dosyası oluşturmak için:

// Generated StringHeader.h 
#define helloWorld    097148937421 
#define error_invalid_input  014782672317 
#define this_could_get_tedious 894792738384 

Bu, ilk başta çok manuel ve sıkıcı görünüyor, ama otomatikleştirmek için yollar var. Örneğin, kaynak kodunuzu ayrıştırmak için "alıntılanan dizeleri" bulmak için bir şeyler yazabilirsiniz. Daha sonra her bir dizeyi isimlendirebilir, tek bir StringHeader.h'a yazabilir ve satır içi alıntılanmış dizgiyi yeni adlandırılmış dizge sabitiyle değiştirebilir. Dosyayı oluştururken ek bir adım olarak, her dizeyi alabilirdiniz - ya da dosyayı oluşturduktan sonra bir defada taşıyabilirsiniz. Bu, dosyanın karma olmayan ve karma olmayan bir sürümünü oluşturmanıza olanak sağlayabilir (karma olmayan bir Hata Ayıklama sürümünü ve karma sürüm sürümünü oluşturmak güzel olabilir).

Bunu denerseniz, ilk ayrıştırıcınızın dizeleri araması, kenar durumlarını (yorumlar, satırlar, çoğaltılmış dizgiler, vb.) Işlemek zorunda kalacaktır.Bir derleyici hiç bu destekliyorsa

0

İşlemcinin bunu sizin için yapmasını sağlayamıyorsanız, önce bu işlemi yapmak için kendi ön işlemcinizi yazabilirsiniz.

+1

Evet, bunu düşünüyorum ve gerekirse bunu yapacağım, ancak eğer yapabilirsem standart önişlemciyi kullanmak istiyorum. –

0

Zorlamak için bir yol yok, ancak derleyiciniz yeterince iyi ise, bunu yapabilir. Optimizasyon seçenekleri ile oynayın ve herhangi birinin istediğini elde etmesine izin verip vermediğini görmek için hata ayıklayıcısındaki kodun sökülmesini inceleyin. O zaman çalıştırabilirsiniz

#include "StringHeader.h" 
std::cout << this_could_get_tedious << std::endl; 

:

// StringHeader.h 
#define helloWorld    "Hello World" 
#define error_invalid_input  "Error: Invalid Input" 
#define this_could_get_tedious "this could get tedious" 

Sonra bu dizeleri kullanabilirsiniz: Bunu gerçekleştirmek için

+3

Konuştuğunuz şeyi yapacak tek bir derleyici adlandırabilir misiniz? –

+1

Tek yapmanız gereken, tüm kareyi makronun kendisinde yazmak - sonra derleyici onu sabit bir ifade olarak görmeli ve değeri değiştirmelidir (en iyileştirme ayarlarının izin verdiği varsayılarak). Kolay! * (* Hard) – geofftnz

+0

@David: Bence DMD derleyicisi CTFE ile bunu yapabilir :) C++ da mümkün olup olmadığını merak etsem de. Hiç duymadım –

6

, C++ 11 user defined literals sahiptir:

constexpr unsigned long long operator "" U64_HASH_(
    const char *literal_string) { ... } 

#define U64_HASH(inputString) inputString U64_HASH_ 

veya constexpr ile:

constexpr unsigned long long operator "" U64_HASH(
    const char *literal_string) { ... } 
+0

Bu, dize değişmezleri için karma değeri döndürmek için garanti edilir mi? –