2010-03-09 32 views
10

A kullanarak std :: string'in NULL const char * ile hatalı başlatılmasını algılayabilen herhangi bir g ++ seçeneği var mı?Hatalı std :: string initialization ile NULL const char * kullanarak g ++

Ben std :: string olanları içine bazı int alanları dönüm sürecinde, yani oldu: ...

struct Foo 
{ 
    int id; 
    Foo() : id(0) {} 
}; 

dönüştü: Tamamen kötü 'kimlik' gözden kaçan

struct Foo 
{ 
    std::string id; 
    Foo() : id(0) {} //oooops! 
}; 

0 ve g ++ ile başlatma, bana hiç uyarı vermedi. Bu hata çalışma zamanında tespit edildi (std :: string constructor bir istisna attı) ama derleme zamanında böyle şeyleri tespit etmek isterim. Herhangi bir yol var mı?

+2

Ne yazık ki, 0, int'den işaretçiye geçersiz bir dönüşüm için bir hata tetiklemeyen bir değerdir. Elbette 0 sıfır boş bir işaretçi sabit olduğundan, herhangi bir işaretçi türüne dönüştürülebilir. Ziyaretçinin söylediği gibi, baştan başlatabilmek için yapabileceğiniz şeyden başka bir şey bilmiyorum. –

+0

Uygun çözüm, özel bir kurucu 'std :: string :: string (int); Bu daha iyi bir eşleşme olur ve bu nedenle bir derleme zamanı hatasına neden olur. – MSalters

+1

Bu şekilde kastettiğinizden emin değilsiniz, ancak aslında bu, 'int''den' string''e yapılan bu değişiklikten kaynaklanan hataları yakalamak için bir kerelik bir test olarak işe yarayabilir. G ++ standart başlıklarında std :: basic_string işlevini değiştirin, yeni kodun derlendiğini, ardından hızlı bir şekilde herkesin fark etmediğini kontrol edin. –

cevap

5

Aslında, tanımlanmamış bir davranış olduğunu ve derleyici tarafından denetlenmediğini düşünüyorum. Bu uygulamanın bir istisna oluşturduğu konusunda şanslısınız.

Ancak, varsayılan istiyorum ya da tip-agnostik şekilde sıfır başlatma olduğunu belirterek bu tür sorunları önleyebilirsiniz:

struct Foo 
{ 
    X id; 
    Foo() : id() {} //note empty parenthesis 
}; 
+0

Hm ... Yani int tür atamaları için varsayılan kurucu 0 diyorsunuz? – pachanga

+3

Bu sözdizimi yerleşik türler için sıfır başlatma anlamına gelir. – visitor

+0

Bilgi için teşekkürler! – pachanga

2

tam uyarı bu tür üretmek için GCC altyapı yok:

void foo(const char* cstr) __attribute__((nonnull (1))); 

void bar() { 
    foo(0); 
} 

(-Wall tarafından uygulanır) -Wnonnull derlenmiş üretir:

warning: null argument where non-null required (argument 1) 

Yani prensipte Eğer benzer (senin $ HOME/bit/basic_string.h kopyalama kendi değiştirebilir ve daha sonra sistem -isystem $HOME ile bir geçersiz, deney için daha iyi ya da) ilgili sistem başlığını değiştirmek yapabilmelidir:

basic_string(const _CharT* __s, const _Alloc& __a = _Alloc()) 
    __attribute__((nonnull (1))); 

Ancak bu, (en azından 4.0.1 sürümü) -Wnonnull'un C++ tarafından desteklenmediğinden ve öznitelik açıkça yok sayıldığından, bu yardımcı olmaz. Bunun neden böyle olduğu belli değil; Belki de aşırı yükleme veya bir şeyle kötü etkileşimde bulundu.

+1

Aslında, 'basic_string' ctor' __attribute __ ((null (1))) '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''; __s __n olmayan değerin kontrol edilmesi için __attribute __ ((nonnull (2))) 'i değiştiriniz; http://gcc.gnu.org/ml/gcc/2006-04/msg00549.html sayfasına bakın. – vladr

7

Ben derleme sırasında bu algılamak için bir yol düşünemiyorum, bu yüzden düzgün boş göstericilerle ilgilenen dize oluşturucu işlevi yazdı:

// FUNCTION :  safe_string(char const* pszS) 
// PARAMATERS : pszS  source string to build a string from (may be NULL or 0-length) 
// DESCRIPTION : Safely builds a string object from a char*, even a NULL pointer 
// RETURNS :  string 

template<class C> 
inline basic_string<C> safe_string(const C* input) 
{ 
    if(!input) 
     return basic_string<C>(); 
    return basic_string<C>(input); 
} 

Bir dize oluşturmak her Bunu kullanabilirim ve Girişin NULL olabileceği bir şans var.

İlgili konular