2013-03-15 24 views
5

static const 's sınıf bir diş güvenli midir? Aşağıdaki kodda, static const karakter dizisi olan trailingBytesForUTF8 var. CConvertUTF sınıfının kendi nesne örneğine sahip birçok iş parçacığı olabilir. Birden çok iş parçacığı aynı trailingBytesForUTF8 dizisine aynı anda erişirken veya başka herhangi bir iş parçacığı sorunu olduğunda herhangi bir değişebilir durum sorunu olacak mı? Ayrıca ipler aslaCConvertUTF sınıfın aynı nesne örneğini paylaşacak unutmayın.statik const char [] sınıf iş parçacığı güvenli midir?

// .h 
class CConvertUTF final 
{ 
    private: 
     static const char trailingBytesForUTF8[256]; 
    public: 
     bool IsLegalUTF8Sequence(const char *source, const char *sourceEnd); 
     bool IsLegalUTF8(const char *source, int length); 
}; 

// .cpp 
const char CConvertUTF::trailingBytesForUTF8[256] = { 
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 
    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 
}; 

bool CConvertUTF::IsLegalUTF8Sequence(const char *source, const char *sourceEnd) { 
    int length = trailingBytesForUTF8[*source]+1; 
    if (source+length > sourceEnd) { 
    return false; 
    } 
    return IsLegalUTF8(source, length); 
} 

bool CConvertUTF::IsLegalUTF8(const char *source, int length) { 
    char a; 
    const *char = source+length; 
    switch (length) { 
    default: return false; 
    /* Everything else falls through when "true"... */ 
    case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; 
    case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; 
    case 2: if ((a = (*--srcptr)) > 0xBF) return false; 

    switch (*source) { 
     /* no fall-through in this inner switch */ 
     case 0xE0: if (a < 0xA0) return false; break; 
     case 0xED: if (a > 0x9F) return false; break; 
     case 0xF0: if (a < 0x90) return false; break; 
     case 0xF4: if (a > 0x8F) return false; break; 
     default: if (a < 0x80) return false; 
    } 

    case 1: if (*source >= 0x80 && *source < 0xC2) return false; 
    } 
    if (*source > 0xF4) return false; 
    return true; 
} 
+0

(HMM verilmişse const char testi [] = {0xA, 0xFF, 0xA};. IsLegalUTF8Sequence (testi, + 3) ' 'TRUE.) hata ayıklama için – aschepler

+0

@aschepler sayesinde kod sadece bir nesne yönelimli programlama tarzı eklemiş Unicode Inc. eski açık kaynak kodu olmasıdır. –

cevap

7

Salt okunur (const) değişkenleri, yok edildikleri ana kadar her zaman güvenlidir. Statik bir nesne sadece program sonlandırmada yok edildiğinden, programın ömrü için iyidir.

tek istisnası mutable üyesi ile bir nesne olurdu, ama o bir char diziye geçerli değildir. static const olarak belirtilir

+0

gönderenin örnek (muhtemelen) evreli herhangi bir yeni ipler oluşturulmadan önce o (muhtemelen) başlatılır beri olmakla değişkenlerin çoğu const, hatta static const içinde olsa bile, muteks kilitleri olmadan güvenilir bir iş parçacığı güvenli değildir Önlerinde, küresel alanda görünseler bile (initalizasyon emri üzerinde kontrol sahibi olmadığınız için). Bunun C++ 11'de sabit olduğunu düşünüyorum. – Scott

+1

@Scott Yanıtımı, bu değişkenlerin * başlangıç ​​durumuna getirilebileceği varsayımına dayanarak * herhangi bir alternatif iş parçacığı başlatılabilir. Bir başka statik başlatma, bir iş parçacığı başlatabilir veya bir statik değişken, sınıf seviyesinden ziyade blok seviyesinde (bir fonksiyonun içinde) olabilir. Statik yapıda POD türleri için fark yaratmaz, çünkü bunları başlatmanın evrensel yöntemi, içeriğini yürütme başlamadan önce yüklenen kod alanına koymaktır. –

+1

Anlaşmalı. Standardın bunu garanti edip etmediğini bilmiyorum, ancak herhangi bir kod çalıştırılmadan önce statik POD'un bulunması çok muhtemeldir. Bir * işaretçi * 'nin bir const değilse (const verisine işaret eder, ancak kendisi non-const ise), işaretçi main() öğesinden önce başlatılamayabilir. Ben sadece hepsini getirdim çünkü kısa bir süre önce tekli bir sınıfla (birden çok ileti dizisini kullandım) tembel durağan başlatma ile (yani C :: örnek() {statik C örneği; dönüş örneği; İlk kez "ve aynı zamanda kurucu çalıştı - neyse ki bir seg-fault hatayı bulmamıza yardımcı oldu. – Scott

3

herhangi bir veri geneldir ve salt okunur.

hiç kimse verileri değiştirmek olacağından yarış koşullarına karşı korunmaktadır Bu araçlar.

veri yarış durumu en azından yazma işlemi ile ilgili olmalıdır görünmesi için

+0

muhtemelen tıpkı diğer nesneler önce verilerin bir damla değişken noktaları başlatıldı, ancak başlatma sırası garanti edilmez olduğunu "söyleme" evreli kod oluşturur derleyici, hatta statik" bir multi-thread tehlike var const "veri. Bunun C++ 11'de sabit olduğunu düşünüyorum. – Scott