คำถามติดแท็ก undefined-behavior

ผลลัพธ์ที่คาดเดาไม่ได้ของการคอมไพล์หรือเอ็กซีคิ้วท์โปรแกรมที่ทำลายกฏของภาษาไม่ว่าจะเป็นคอมไพเลอร์, ล่ามหรือระบบรันไทม์จะต้องบังคับใช้ ห้ามใช้แท็กนี้สำหรับคำถามเกี่ยวกับประเภทข้อมูลหรือค่าส่งคืนของ "undefined" ในกรณีเหล่านั้นควรใช้แท็ก [ไม่ได้กำหนด] แทน

4
คัดลอก structs กับสมาชิกที่ไม่ได้กำหนดค่าเริ่มต้น
มันถูกต้องหรือไม่ที่จะคัดลอก struct ที่สมาชิกบางคนไม่ได้เริ่มต้น? ฉันสงสัยว่ามันเป็นพฤติกรรมที่ไม่ได้กำหนด แต่ถ้าเป็นเช่นนั้นมันจะทำให้สมาชิกที่ไม่ได้กำหนดค่าเริ่มต้นในโครงสร้าง (แม้ว่าสมาชิกเหล่านั้นจะไม่เคยใช้งานโดยตรง) ค่อนข้างอันตราย ดังนั้นฉันสงสัยว่ามีบางอย่างในมาตรฐานที่อนุญาตหรือไม่ เช่นนี้ถูกต้องหรือไม่ struct Data { int a, b; }; int main() { Data data; data.a = 5; Data data2 = data; }

3
C มีค่า std :: น้อยกว่าจาก C ++ หรือไม่
ฉันเพิ่งตอบคำถามเกี่ยวกับพฤติกรรมที่ไม่ได้กำหนดของการทำp < qใน C เมื่อpและqเป็นตัวชี้ไปยังวัตถุ / อาร์เรย์ที่แตกต่างกัน นั่นทำให้ฉันคิดว่า: C ++ มีพฤติกรรมเหมือนกัน (ไม่ได้กำหนด) <ในกรณีนี้ แต่ยังมีเท็มเพลตไลบรารีมาตรฐานstd::lessซึ่งรับประกันว่าจะส่งคืนสิ่งเดียวกันกับ<ที่สามารถเปรียบเทียบตัวชี้และส่งคืนการสั่งซื้อบางอย่างที่ไม่สอดคล้อง C เสนอบางสิ่งที่มีฟังก์ชั่นคล้ายกันซึ่งจะช่วยให้เปรียบเทียบตัวชี้ตามอำเภอใจ (กับประเภทเดียวกัน) ได้อย่างปลอดภัยหรือไม่? ฉันพยายามมองผ่านมาตรฐาน C11 และไม่พบอะไรเลย แต่ประสบการณ์ของฉันใน C คือขนาดที่เล็กกว่า C ++ ดังนั้นฉันอาจจะพลาดอะไรบางอย่างได้อย่างง่ายดาย

1
ทำไมฟังก์ชั่น consteval ถึงมีพฤติกรรมที่ไม่ได้กำหนดไว้?
มีคุณสมบัติที่เป็นระเบียบมากของนิพจน์คงที่ใน C ++: การประเมินของพวกเขาไม่สามารถมีพฤติกรรมที่ไม่ได้กำหนด ( 7.7.4.7 ): นิพจน์ e เป็นนิพจน์ค่าคงที่หลักเว้นแต่ว่าการประเมิน e ตามกฎของเครื่องนามธรรม ([intro.execution]) จะประเมินข้อใดข้อหนึ่งต่อไปนี้: ... การดำเนินการที่จะมีพฤติกรรมที่ไม่ได้กำหนดตามที่ระบุไว้ใน [บทนำ] ถึง [cpp] ของเอกสารนี้ [หมายเหตุ: รวมถึงตัวอย่างเช่นจำนวนเต็มล้นลงนาม ([expr.prop]) บางตัวชี้ทางคณิตศาสตร์ ([expr.add]) การหารด้วยศูนย์หรือการเลื่อนบางอย่าง - หมายเหตุท้าย]; การพยายามเก็บค่าของ13!ในข้อผิดพลาดconstexpr intจริงทำให้คอมไพล์คอมไพล์ดี : constexpr int f(int n) { int r = n--; for (; n > 1; --n) r *= n; return …

2
เป็นโปรแกรมที่ไม่เคยยกเลิกโปรแกรม C ++ ที่ถูกต้องหรือไม่?
จำเป็นต้องมีโปรแกรมหรือไม่ ในคำอื่น ๆ เป็นโปรแกรมที่ทำงานตลอดเวลาพฤติกรรมที่ไม่ได้กำหนดทางเทคนิค? โปรดทราบว่านี่ไม่เกี่ยวกับลูปที่ว่างเปล่า การพูดเกี่ยวกับโปรแกรมที่ทำ "สิ่ง" (เช่นพฤติกรรมที่สังเกตได้) ตลอดไป เช่นบางสิ่งเช่นนี้ int main() { while (true) { try { get_input(); // calls IO process(); put_output(); // calls IO, has observable behavior // never break, exit, terminate, etc } catch(...) { // ignore all exceptions // don't (re)throw // never go out …

3
การเรียกใช้ฟังก์ชันที่มีตัวชี้ไปยังไม่ใช่ const และตัวชี้ไปยังอาร์กิวเมนต์ const ของที่อยู่เดียวกัน
ฉันต้องการเขียนฟังก์ชั่นที่ป้อนอาร์เรย์ของข้อมูลและส่งออกอาเรย์อีกหนึ่งข้อมูลโดยใช้พอยน์เตอร์ ฉันสงสัยว่าผลลัพธ์คืออะไรถ้าทั้งคู่srcและdstชี้ไปยังที่อยู่เดียวกันเพราะฉันรู้ว่าคอมไพเลอร์สามารถปรับให้เหมาะสมสำหรับ const มันเป็นพฤติกรรมที่ไม่ได้กำหนดหรือไม่? (ฉันติดแท็กทั้ง C และ C ++ เพราะฉันไม่แน่ใจว่าคำตอบอาจแตกต่างกันหรือไม่และฉันต้องการทราบเกี่ยวกับทั้งคู่) void f(const char *src, char *dst) { dst[2] = src[0]; dst[1] = src[1]; dst[0] = src[2]; } int main() { char s[] = "123"; f(s,s); printf("%s\n", s); return 0; } นอกเหนือจากคำถามข้างต้นแล้วสิ่งนี้ได้กำหนดไว้อย่างชัดเจนหรือไม่หากฉันลบconstในรหัสต้นฉบับ?

1
พฤติกรรมที่ไม่ได้กำหนดเป็นไปได้ในการใช้งาน static_vector ดั้งเดิม
tl; dr: ฉันคิดว่า static_vector ของฉันมีพฤติกรรมที่ไม่ได้กำหนด แต่ฉันหามันไม่พบ ปัญหานี้เกิดขึ้นกับ Microsoft Visual C ++ 17 ฉันมีการใช้งาน static_vector ที่เรียบง่ายและไม่สมบูรณ์เช่นเวกเตอร์ที่มีความจุคงที่ที่สามารถจัดสรรสแต็กได้ นี่คือโปรแกรม C ++ 17 โดยใช้ std :: aligned_storage และ std :: launder ฉันพยายามต้มลงไปด้านล่างเพื่อชิ้นส่วนที่ฉันคิดว่าเกี่ยวข้องกับปัญหา: template <typename T, size_t NCapacity> class static_vector { public: typedef typename std::remove_cv<T>::type value_type; typedef size_t size_type; typedef T* pointer; typedef const T* …

1
`string.assign (string.data (), 5)` มีการกำหนดชัดเจนหรือ UB หรือไม่
เพื่อนร่วมงานต้องการเขียนสิ่งนี้: std::string_view strip_whitespace(std::string_view sv); std::string line = "hello "; line = strip_whitespace(line); ผมบอกว่ากลับมาstring_viewทำให้ฉันไม่สบายใจเบื้องต้นและนอกจาก aliasing ที่นี่ดูเหมือน UB ให้ฉัน ฉันสามารถพูดด้วยความมั่นใจว่าในกรณีนี้จะเทียบเท่ากับline = strip_whitespace(line) line = std::string_view(line.data(), 5)ฉันเชื่อว่าจะเรียกstring::operator=(const T&) [with T=string_view]ซึ่งถูกกำหนดให้เทียบเท่ากับline.assign(const T&) [with T=string_view]ซึ่งถูกกำหนดให้เทียบเท่ากับline.assign(line.data(), 5)ซึ่งถูกกำหนดให้ทำเช่นนี้: Preconditions: [s, s + n) is a valid range. Effects: Replaces the string controlled by *this with a copy …

5
กำลังจับวัตถุที่สร้างขึ้นใหม่โดย const อ้างอิงพฤติกรรมที่ไม่ได้กำหนด
ต่อไปนี้เป็นตัวอย่าง (contrived) หรือไม่หรือเป็นพฤติกรรมที่ไม่ได้กำหนดไว้: // undefined behavior? const auto& c = SomeClass{}; // use c in code later const auto& v = c.GetSomeVariable();

2
จะเกิดอะไรขึ้นถ้าพฤติกรรม C ++ ที่ไม่ได้กำหนดตรงกับพฤติกรรมที่กำหนดไว้ C?
ฉันมี*.cppไฟล์ที่คอมไพล์ด้วย C ++ (ไม่ใช่คอมไพเลอร์ C) ฟังก์ชั่นที่มีอยู่อาศัยนักแสดง (ดูบรรทัดสุดท้าย) ซึ่งดูเหมือนว่าจะถูกกำหนดใน C (โปรดแก้ไขถ้าฉันผิด!) แต่ไม่ใช่ใน C ++ สำหรับประเภทพิเศษนี้ [...] C++ code [...] struct sockaddr_in sa = {0}; int sockfd = ...; sa.sin_family = AF_INET; sa.sin_port = htons(port); bind(sockfd, (struct sockaddr *)&sa, sizeof sa); [...] C++ code [...] เนื่องจากฉันคอมไพล์ไฟล์นี้ในไฟล์ C ++ ตอนนี้มันเป็นพฤติกรรมที่กำหนดหรือไม่ได้กำหนดหรือไม่? หรือฉันจะต้องย้ายสิ่งนี้เป็น*.cไฟล์เพื่อให้มันเป็นพฤติกรรมที่กำหนดไว้?

1
GCC ล้มเหลวในการรายงานการโทรแลมบ์ดาแบบ constexpr ที่ไม่เหมาะสม
ด้านล่างเป็นสองกรณีทดสอบสำหรับพฤติกรรมที่ไม่ได้กำหนดซึ่งแสดงเป็น IIFE (เรียกว่า Lambda-Axpression ทันที): constexpr auto test3 = []{ int* p{}; { int x{}; p = &x; } return *p; // Undefined Behaviour }(); // IIFE constexpr auto test4 = []{ int x = std::numeric_limits<int>::min(); int y = -x; // Undefined Behaviour return y; }(); int main() {} เมื่อรวบรวมกับ …

1
“ คำสั่งฮาร์ดแวร์ที่ผิดกฎหมาย” จากรหัสที่ง่ายมาก
ในขณะที่ตรวจสอบการอ้างสิทธิ์ที่น่าสงสัยฉันได้เขียนโปรแกรมทดสอบเล็กน้อยนี้noway.c int proveit() { unsigned int n = 0; while (1) n++; return 0; } int main() { proveit(); return 0; } ทดสอบสิ่งนี้ฉันจะได้รับ: $ clang -O noway.c $ ./a.out zsh: illegal hardware instruction ./a.out วัด หากฉันรวบรวมโดยไม่มีการเพิ่มประสิทธิภาพมันแฮงค์ตามที่คาดไว้ ฉันดูที่ชุมนุมและไม่มีเสียงระฆังและเสียงนกหวีดmainฟังก์ชั่นที่มีลักษณะเช่นนี้: _main: ## @main pushq %rbp movq %rsp, %rbp ud2 ที่ud2เห็นได้ชัดคือคำสั่งที่เฉพาะเจาะจงสำหรับพฤติกรรมที่ไม่ได้กำหนด การเรียกร้องที่น่าสงสัยดังกล่าว "ฟังก์ชั่นที่ไม่เคยส่งคืนคือ UB" …

2
กำลังส่งการอ้างอิงฟังก์ชันที่สร้างตัวชี้ที่ไม่ถูกต้อง
ฉันกำลังติดตามข้อผิดพลาดในรหัสบุคคลที่สามและฉัน จำกัด ให้แคบลงเหลือบางอย่างตามลำดับ use libc::c_void; pub unsafe fn foo() {} fn main() { let ptr = &foo as *const _ as *const c_void; println!("{:x}", ptr as usize); } วิ่งบนเสถียร 1.38.0 นี้จะพิมพ์ตัวชี้ฟังก์ชั่น แต่เบต้า (1.39.0-beta.6) และส่งคืน '1' ทุกคืน ( สนามเด็กเล่น ) _การอนุมานคืออะไรและทำไมพฤติกรรมจึงเปลี่ยนไป ฉันถือว่าวิธีที่ถูกต้องในการส่งแบบนี้จะเป็นไปได้foo as *const c_voidแต่นี่ไม่ใช่รหัสของฉัน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.