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::terminate
ve 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_error
bir 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_arg
Bir 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ı .
nullptr
gerektiğini düşünürüm what()
. Bu nullptr
, en iyi sorunlu olan ve çökmesi kesin olan bir kayıt dışı bırakma olacaktır.
strcmp
değ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ındanullptr
muhtemelen sorunlara yol açacağını geçirilir.