SORU
12 EYLÜL 2014, Cuma


"" bir C

Çok acayip şeyler kodumu oluyor geçiriyorum. Bölümü etiketli izlerini bulmuştu inanıyorum "burada" (kod, elbette sadeleştirilmiş):

std::string func() {
    char c;
    // Do stuff that will assign to c
    return ""   c; // Here
}

Bir sürü 5 ** Bu işlev sonucu çalıştığımda olacak. Hatta alttaki C belgelerinin adet ve segmentation fault birçok kurtarmayı başardım sanırım. Bu C (stringstream string dönüşümler yapmak için şimdi müracaat ettim) çalışmıyor bu benim için açıktır, ama neden bilmek istiyorum. C çok kullandıktan sonra# uzunca bir süre ve C için , bu bana çok acı verdi.

CEVAP
12 EYLÜL 2014, Cuma


  • "" bir dize. Bu türü varconst char N dizi. Özellikle bu dize1 const char dizisibir öğe null sonlandırıcı olmak.

  • Diziler kolay bir işaretçi gereken ilk unsuru, örneğin ifadelerde işaretçiler içine çürüme.

  • lhs rhs lhs gibi diziler için tanımlı değil ve rhs olarak tamsayılar. Ama her zamanki işaretçi aritmetiği ile oluşturduğu olarak belirtin ve tamsayılar gibi işaretçiler için tanımlanmış.

  • char (bir tamsayı olarak işlem görür yani) çekirdek C dilinde ayrılmaz bir veri türüdür.

==> dize karakterbu nedenle yorumlanırgösterici tamsayı.

İfadesi "" c Aşağı Yukarı eşit sayılır:

static char const lit[1] = {'\0'};
char const* p = &lit[0];
p   c // ""   c is roughly equivalent to this expression

std::string bir geri. İfadesi "" c veririşaretçi 21* *için. const char* beklediği std::string oluşturucu null sonlandırılmış bir karakter dizisi için bir işaretçi olmasını bekler.

c != 0 ifade "" c Tanımsız Davranışlara neden olur

  • c > 1, işaretçi aritmetiği Tanımsız Davranış üretir. İşaretçi aritmetiği sadece diziler tanımlanır ve sonuç ise aynı dizinin bir öğesi.

  • Eğer char imzalanırsa, c < 0 aynı nedenle Tanımsız Davranış üretir.

  • c == 1, işaretçi aritmetiği içindeğilTanımsız Davranış üretmek. Bu özel bir durum, bir dizinin son elemanı son bir elemanı işaret (işaret ne kullanmak için, ama izin verilmez) izin verilir. Hala std::string kurucu burada adı verilen argüman geçerli bir dizi (ve boş sonlandırılmış bir dize) bir işaretçi olması gerekir beri Tanımsız Davranışlara yol açar. -Son--son öğe dizinin kendisi bir parçası değil. Bu şartı ihlal eden de İK yol açar.


Muhtemelen şu anda ne olduğunu kurucu std::string çalışır belirlemek için boyutu null sonlandırılmış bir dize geçti, aramalar (ilk) karakter dizisi yani eşit '\0':

string(char const* p)
{
    // simplified
    char const* end = p;
    while(*end != '\0')   end;
    //...
}

bu da erişim ihlaline neden olacak, ya da yarattığı dize içerir "". çöp Derleyici bu Tanımsız Davranış asla olmayacağını varsayar olması da mümkündür, ve garip davranışlara neden, bazı komik iyileştirmeleri.


Bu parçacık için: clang 3.5 emits a nice warning Bu arada

uyarı: ekleme 'char' için bir dize dize ekleme. [-Wstring-plus-int]

return ""   c; // Here
       ~~~^~~

not: sessizlik için dizi indeksleme bu uyarı kullanın

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Jason Rosolowski

    Jason Rosolo

    25 EKİM 2006
  • paulandstorm

    paulandstorm

    4 EYLÜL 2006
  • Simon Hayter

    Simon Hayter

    20 HAZİRAN 2010