Aşağıdaki programı düşünün:
#include<stdexcept>
#include<iostream>
int main() {
try {
throw std::range_error(nullptr);
} catch(const std::range_error&) {
std::cout << "Caught!\n";
}
}
GCC ve Clang ile libstdc ++ çağrı std::terminateve mesaj ile programı iptal
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
İstisna yapımında libc ++ segfaults ile clang.
Bkz Godbolt .
Derleyiciler standart uyumlu mudur? Standart [diagnostics.range.error] (C ++ 17 N4659) ' un ilgili bölümü, aşırı yüklenmeye göre tercih edilmesi gereken std::range_errorbir const char*yapıcı aşırı yüklenmesine sahip olduğunu söylüyor const std::string&. Bölüm ayrıca yapıcı üzerinde herhangi bir ön koşulu belirtmez ve yalnızca son koşulu belirtir
Hedefşartlar :
strcmp(what(), what_arg) == 0.
what_argBir boş gösterici ise bu son koşul her zaman tanımsız davranışa sahiptir , bu da programımın tanımlanmamış davranışa sahip olduğu ve her iki derleyicinin de uygun davrantığı anlamına mı geliyor? Değilse, standartta böyle imkansız postconditions nasıl okunmalıdır?
İkinci düşüncemde, bunun benim programım için tanımlanmamış davranış anlamına gelmesi gerektiğini düşünüyorum, çünkü eğer o zaman (geçerli) null sonlu dizelere işaret etmeyen işaretçiler de izin verilecekti, bu açıkça anlamsızdı.
Dolayısıyla, bunun doğru olduğunu varsayarak, soruna standardın bu tanımlanmamış davranışı nasıl ima ettiği üzerine daha fazla odaklanmak istiyorum. Çağrının tanımlanmamış davranışa sahip olması veya önkoşulun basitçe unutulması mıdır?
Bu sorudan ilham alındı .
nullptrgerektiğini düşünürüm what(). Bu nullptr, en iyi sorunlu olan ve çökmesi kesin olan bir kayıt dışı bırakma olacaktır.
strcmpdeğerini tanımlamak için kullanılan beri argümanın geçerli bir C dize işaret bir önkoşul olduğunu düşünüyorum what_arg. C standardından ilgili bölümün yine de belirttiği şey, bu spesifikasyon tarafından belirtilmektedir <cstring>. Tabii ki ifadeler daha açık olabilir.
what()sırasındanullptrmuhtemelen sorunlara yol açacağını geçirilir.