พิจารณาโปรแกรมต่อไปนี้:
#include<stdexcept>
#include<iostream>
int main() {
try {
throw std::range_error(nullptr);
} catch(const std::range_error&) {
std::cout << "Caught!\n";
}
}
GCC และ Clang ด้วยการโทร libstdc ++ std::terminate
และยกเลิกโปรแกรมด้วยข้อความ
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
เสียงดังกราวกับ libc ++ segfaults ในการสร้างข้อยกเว้น
คอมไพเลอร์ทำงานตามมาตรฐานหรือไม่ ส่วนที่เกี่ยวข้องของมาตรฐาน[diagnostics.range.error] (C ++ 17 N4659) กล่าวว่าstd::range_error
มีconst char*
Constructor Overload ซึ่งควรเป็นที่ต้องการมากกว่าconst std::string&
Overload ส่วนนี้ยังไม่ได้ระบุเงื่อนไขใด ๆ บนตัวสร้างและระบุเพียง postcondition
postconditions
strcmp(what(), what_arg) == 0
:
postcondition นี้มักจะมีพฤติกรรมที่ไม่ได้กำหนดหากwhat_arg
เป็นตัวชี้โมฆะดังนั้นนี่หมายความว่าโปรแกรมของฉันยังมีพฤติกรรมที่ไม่ได้กำหนดและคอมไพเลอร์ทั้งคู่ทำตาม ถ้าไม่เราจะอ่าน postconditions ที่เป็นไปไม่ได้ในมาตรฐานได้อย่างไร?
ในความคิดที่สองฉันคิดว่ามันต้องหมายถึงพฤติกรรมที่ไม่ได้กำหนดไว้สำหรับโปรแกรมของฉันเพราะถ้ามันไม่ถูกต้อง (ไม่ถูกต้อง) พอยน์เตอร์ที่ไม่ได้ชี้ไปที่สตริงที่สิ้นสุดด้วยค่า null จะได้รับอนุญาตด้วย
ดังนั้นสมมติว่าเป็นเรื่องจริงฉันอยากจะถามคำถามเพิ่มเติมเกี่ยวกับวิธีที่มาตรฐานแสดงถึงพฤติกรรมที่ไม่ได้กำหนดนี้ มันเป็นไปตามความเป็นไปไม่ได้ของ postcondition ที่การโทรนั้นมีพฤติกรรมที่ไม่ได้กำหนดหรือถูกลืมก่อน
แรงบันดาลใจจากคำถามนี้
nullptr
ผ่านไปแล้วฉันจะคิดว่าwhat()
จะต้องทำการตรวจสอบอีกครั้งเพื่อให้ได้ค่า นั่นคือการยกเลิกการพิจารณาnullptr
ซึ่งเป็นปัญหาที่ดีที่สุดและบางอย่างที่จะผิดพลาดนั้นเลวร้ายที่สุด
strcmp
what_arg
นั่นคือสิ่งที่เกี่ยวข้องจากส่วนมาตรฐานซี<cstring>
กล่าวต่อไปซึ่งถูกอ้างถึงโดยสเปคของ แน่นอนว่าถ้อยคำอาจชัดเจนขึ้น
what()
เมื่อnullptr
ผ่านไปอาจทำให้เกิดปัญหา