คำถามติดแท็ก language-lawyer

สำหรับคำถามเกี่ยวกับความซับซ้อนของข้อกำหนดอย่างเป็นทางการหรือมีสิทธิ์ของภาษาโปรแกรมและสภาพแวดล้อม

2
การหักอาร์กิวเมนต์เทมเพลตสำหรับอาร์กิวเมนต์ของประเภทฟังก์ชั่น
พิจารณาโปรแกรมต่อไปนี้ #include <iostream> template <typename T> void f( void ( *fn )( T ) ) { fn( 42 ); } void g( int x ) { std::cout << "g( " << x << " );\n"; } int main() { f( g ); } โปรแกรมคอมไพล์ได้สำเร็จและผลลัพธ์คือ g( 42 ); ตอนนี้ขอเปลี่ยนชื่อฟังก์ชั่นที่ไม่ใช่แม่แบบเพื่อgf #include <iostream> …

1
ทำไมการเพิ่มความหมายที่สองทำให้ไม่สามารถโต้แย้งได้
ฉันเจอปัญหานี้เมื่อพยายามเพิ่มความหมายAdd<char> for Stringลงในไลบรารีมาตรฐาน แต่เราสามารถทำซ้ำได้อย่างง่ายดายโดยไม่ต้องมีผู้ควบคุม shenanigans เราเริ่มต้นด้วยสิ่งนี้: trait MyAdd<Rhs> { fn add(self, rhs: Rhs) -> Self; } impl MyAdd<&str> for String { fn add(mut self, rhs: &str) -> Self { self.push_str(rhs); self } } เรียบง่ายพอสมควร ด้วยวิธีนี้รหัสต่อไปนี้รวบรวม: let a = String::from("a"); let b = String::from("b"); MyAdd::add(a, &b); ทราบว่าในกรณีนี้การแสดงออกอาร์กิวเมนต์ที่สอง ( &b) &Stringมีชนิด จากนั้นจะถูกบีบอัด&strและการเรียกใช้ฟังก์ชันทำงาน …

2
C ++ - เหตุใดจึงต้องใช้คำหลัก 'เทมเพลต' ที่นี่
ฉันมีรหัสต่อไปนี้: template <typename TC> class C { struct S { template <typename TS> void fun() const {} }; void f(const S& s) { s.fun<int>(); } }; // Dummy main function int main() { return 0; } เมื่อมีการสร้างนี้มีทั้ง GCC 9.2 และเสียงดังกราว (9.0) ฉันได้รับการรวบรวมข้อผิดพลาดเนื่องจากการคำหลักที่ถูกต้องสำหรับการกล่าวอ้างtemplate funเสียงดังกราวแสดง: error: use 'template' keyword to treat 'fun' …

1
เสียงดังกราว / gcc ในความเชี่ยวชาญเฉพาะทางของชั้นเรียน
ฉันเจอปัญหานี้ในขณะที่พยายามชำนาญtuple_size/ tuple_elementสำหรับคลาสที่กำหนดเองใน C ++ 17 สำหรับการโยงโครงสร้าง โค้ดด้านล่างรวบรวมใน GCC แต่ไม่ใช่ในเสียงดังกราว (ทั้งรุ่นลำตัวดูที่ลิงค์ด้านล่าง) #include <type_traits> template<typename T, typename... Ts> using sfinae_t = T; template<typename T, bool... Bs> using sfinae_v_t = sfinae_t<T, typename std::enable_if<Bs>::type...>; template <typename T> struct Test; template <typename T> struct Test<sfinae_v_t<T, std::is_integral_v<T>>> {}; void f() { Test<int> t; } https://godbolt.org/z/ztuRSq นี่คือข้อผิดพลาดที่จัดทำโดยเสียงดังกราว: …

2
การเปลี่ยนแปลงเกี่ยวกับชุดรูปแบบการสะกดคำแบบพิมพ์: การสร้างสิ่งเล็กน้อยในสถานที่
ฉันรู้ว่านี่เป็นเรื่องที่ค่อนข้างทั่วไป แต่เท่าที่ UB ทั่วไปหาได้ง่ายฉันไม่พบตัวแปรนี้จนถึงตอนนี้ ดังนั้นฉันจึงพยายามแนะนำวัตถุพิกเซลอย่างเป็นทางการในขณะที่หลีกเลี่ยงการคัดลอกข้อมูลจริง ถูกต้องหรือไม่ struct Pixel { uint8_t red; uint8_t green; uint8_t blue; uint8_t alpha; }; static_assert(std::is_trivial_v<Pixel>); Pixel* promote(std::byte* data, std::size_t count) { Pixel * const result = reinterpret_cast<Pixel*>(data); while (count-- > 0) { new (data) Pixel{ std::to_integer<uint8_t>(data[0]), std::to_integer<uint8_t>(data[1]), std::to_integer<uint8_t>(data[2]), std::to_integer<uint8_t>(data[3]) }; data += sizeof(Pixel); } return result; …

1
ตัวชี้ไปยังชนิดที่ไม่สมบูรณ์สามารถไม่สมบูรณ์ได้หรือไม่?
สามารถint (*)[]จะเป็นประเภทที่ไม่สมบูรณ์? C 2018 6.2.5 1 พูดว่า: ณ จุดต่าง ๆ ภายในหน่วยการแปลประเภทของวัตถุอาจไม่สมบูรณ์ (ขาดข้อมูลเพียงพอที่จะกำหนดขนาดของวัตถุประเภทนั้น) หรือสมบูรณ์ (มีข้อมูลเพียงพอ) ดังนั้นจึงดูเหมือนว่าถ้าขนาดของประเภทเป็นที่รู้จักประเภทจะเสร็จสมบูรณ์ 6.2.6.1 28 ระบุว่าพอยน์เตอร์บางประเภทต้องมีขนาดเท่ากัน (พอยน์เตอร์voidและตัวอักษร, พอยน์เตอร์ไปยังประเภทที่เข้ากันได้, พอยน์เตอร์ไปยังโครงสร้างและพอยน์เตอร์เป็นสหภาพ) แต่พอยน์เตอร์ ในการนำ C ไปใช้งานที่ตัวชี้ทั้งหมดหรือตัวชี้ทั้งหมดไปยังอาร์เรย์intมีขนาดเท่ากันแล้วขนาดint (*)[]เป็นที่รู้จักดังนั้นจึงจะสมบูรณ์ ในการใช้งานที่กล่าวว่าใช้ตัวชี้ที่แตกต่างกันสำหรับอาร์เรย์ขนาดใหญ่ขนาดจะไม่เป็นที่รู้จักดังนั้นจึงไม่สมบูรณ์ เมื่อMM ชี้ให้เห็นโครงสร้างจะต้องไม่มีสมาชิกที่มีชนิดไม่สมบูรณ์ยกเว้นสมาชิกอาร์เรย์สุดท้ายที่ยืดหยุ่นตามข้อ จำกัด ใน 6.7.2.1 3. สิ่งนี้ชี้ให้เห็นว่าการนำไปปฏิบัติที่มีพอยน์เตอร์ขนาดเดียวต้องยอมรับstruct { int (*p)[]; }ในขณะที่การนำไปใช้ที่แตกต่างกัน ขนาดสำหรับอาร์เรย์ดังกล่าวจะต้องวินิจฉัยการละเมิดข้อ จำกัด (นี่หมายความว่าคำประกาศดังกล่าวไม่ได้เป็นส่วนหนึ่งของการปฏิบัติตามค. อย่างเคร่งครัด)

1
ลำดับการดำเนินการของตัวดำเนินการใหม่และอาร์กิวเมนต์ของตัวสร้าง
ไม่ c ++ spec ระบุลำดับoperator newและคอนสตรัคของในA กรัม ++ ให้การสั่งซื้อจะ-> -> แต่เสียงดังกราว ++ ให้มันเป็น-> -> ความแตกต่างเกิดจากพฤติกรรมที่ไม่ระบุหรือไม่?new C(A())A()newC()newA()C() g ++: 7.4.0 clang ++: 10.0.0 #include <iostream> #include <cstdlib> struct A { A() { std::cout << "call A()\n"; } }; struct C { C(A) { std::cout << "call S()\n"; } void *operator new(size_t …

1
พยายามทำความเข้าใจแม่แบบและค้นหาชื่อ
ฉันพยายามเข้าใจตัวอย่างโค้ดต่อไปนี้ ตัวอย่าง # 1 template <typename T> struct A { static constexpr int VB = T::VD; }; struct B : A<B> { }; ไม่ว่าจะเป็น gcc9 หรือ clang9 ข้อผิดพลาดที่นี่ ถามทำไมรหัสนี้ถึงคอมไพล์? เราไม่ได้ยกตัวอย่างA<B>เมื่อได้รับมรดกจาก B? ไม่มี VD ใน B ดังนั้นคอมไพเลอร์ไม่ควรโยนข้อผิดพลาดที่นี่หรือ ตัวอย่าง # 2 template <typename T> struct A { static constexpr auto AB = …

1
“ เกิดขึ้นก่อนหน้านี้” หมายความว่าอะไร?
วลี "เกิดขึ้นอย่างแรงก่อน" ถูกใช้หลายครั้งในมาตรฐานฉบับร่าง C ++ ตัวอย่างเช่น: การยุติ [basic.start.term] / 5 หากความสมบูรณ์ของการเริ่มต้นของวัตถุที่มีระยะเวลาการจัดเก็บแบบคงที่เกิดขึ้นก่อนที่จะเรียก std :: atexit (ดู, [support.start.term]) การเรียกฟังก์ชั่นผ่านไปยัง std :: atexit ถูกจัดลำดับก่อนการเรียกไปยัง destructor สำหรับวัตถุ ถ้าการเรียกไปยัง std :: atexit เกิดขึ้นอย่างมากก่อนที่การเริ่มต้นของวัตถุที่มีระยะเวลาการจัดเก็บแบบสแตติกการเรียกไปยัง destructor สำหรับวัตถุนั้นจะถูกจัดลำดับก่อนที่การเรียกไปยังฟังก์ชันที่ส่งผ่านไปยัง std :: atexit . หากการเรียกไปยัง std :: atexit เกิดขึ้นอย่างยิ่งก่อนการเรียกไปยัง std :: atexit การเรียกใช้ฟังก์ชันที่ส่งไปยังการเรียก std :: atexit ที่สองจะถูกจัดลำดับก่อนการเรียกไปยังฟังก์ชันที่ส่งไปยัง first std :: …

2
สร้างข้อยกเว้นมาตรฐานด้วยอาร์กิวเมนต์ตัวชี้โมฆะและ postconditions ที่เป็นไปไม่ได้
พิจารณาโปรแกรมต่อไปนี้: #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 ในการสร้างข้อยกเว้น ดูgodbolt คอมไพเลอร์ทำงานตามมาตรฐานหรือไม่ ส่วนที่เกี่ยวข้องของมาตรฐาน[diagnostics.range.error] (C ++ 17 …

1
มันเป็น UB ที่จะกลับมาทำงานเป็นสมาชิก coroutine ของวัตถุที่อายุการใช้งานสิ้นสุดลงหรือไม่?
คำถามนี้เกิดจากความคิดเห็นนี้: คำอธิบายตลอดอายุการใช้งานแลมบ์ดาสำหรับ coroutines C ++ 20 เกี่ยวกับตัวอย่างนี้: auto foo() -> folly::coro::Task<int> { auto task = []() -> folly::coro::Task<int> { co_return 1; }(); return task; } ดังนั้นคำถามคือการดำเนินการ coroutine กลับโดยfooจะส่งผลใน UB "การเรียก" ฟังก์ชันสมาชิก (หลังจากสิ้นสุดอายุการใช้งานของวัตถุ) คือ UB: http://eel.is/c++draft/basic.life#6.2 ... ตัวชี้ใด ๆ ที่แสดงที่อยู่ของที่เก็บสินค้าซึ่งวัตถุนั้นจะเป็นหรือที่ตั้งอาจถูกนำมาใช้ แต่ในรูปแบบที่ จำกัด เท่านั้น [... ] โปรแกรมมีพฤติกรรมที่ไม่ได้กำหนดหาก: [ ... ] - ตัวชี้ใช้เพื่อเข้าถึงสมาชิกข้อมูลที่ไม่คงที่หรือเรียกใช้ฟังก์ชันสมาชิกแบบไม่คงที่ของวัตถุหรือ …

1
การสร้างวัตถุโดยนัยที่ไม่ระบุ
เนื่องจากP0593 การสร้างวัตถุโดยปริยายสำหรับการจัดการวัตถุระดับต่ำได้รับการยอมรับวัตถุจึงอาจถูกสร้างโดยนัยใน C ++ 20 โดยเฉพาะถ้อยคำที่นำโดยข้อเสนอที่จะช่วยให้การดำเนินการบางอย่าง (เช่นstd::malloc) เพื่อสร้างโดยอัตโนมัติและเริ่มต้นชีวิตของวัตถุบางชนิดที่เรียกว่าประเภทนัยชีวิต , ถ้าการแนะนำของวัตถุดังกล่าวจะทำให้โปรแกรมที่มีพฤติกรรมที่ไม่ได้กำหนดไว้เป็นอย่างอื่นที่จะมี พฤติกรรมที่กำหนดไว้ ดู[intro.object] / 10 ตอนนี้ร่างเพิ่มเติมกล่าวว่าหากมีหลายชุดของวัตถุดังกล่าวที่สามารถสร้างขึ้นโดยปริยายเพื่อให้พฤติกรรมที่กำหนดโปรแกรมมันจะไม่ได้ระบุชุดของชุดเหล่านี้จะถูกสร้างขึ้น (ดูเหมือนว่าประโยคที่เกี่ยวข้องจะไม่ปรากฏในการแก้ไขข้อเสนอล่าสุดที่ฉันสามารถเข้าถึงได้ R5 แต่อยู่ในร่างข้อตกลง) จริง ๆ แล้วมีโปรแกรมที่ตัวเลือกของชุดวัตถุที่สร้างขึ้นโดยปริยายนี้สามารถสังเกตได้หรือไม่? ในคำอื่น ๆ มีโปรแกรมที่มีการกำหนด แต่ไม่ได้ระบุพฤติกรรมผ่านกฎใหม่นี้เช่นว่ามันเป็นไปได้ที่จะอนุมานจากการส่งออกซึ่งชุดประเภทของวัตถุโดยปริยาย (มากกว่าหนึ่งที่เป็นไปได้มากกว่าหนึ่ง) ถูกสร้างขึ้น? หรือประโยคนี้มีความหมายเพียงเพื่อชี้แจงการดำเนินการของโปรแกรมบนเครื่องนามธรรม (โดยไม่มีผลกระทบที่สังเกตได้)?

2
ทำไม C ++ deduce T ในการโทรไปยัง Foo <T> :: Foo (T&&) ไม่ได้?
รับโครงสร้างแม่แบบต่อไปนี้: template&lt;typename T&gt; struct Foo { Foo(T&amp;&amp;) {} }; การคอมไพล์นี้และTถูกอนุมานว่าเป็นint: auto f = Foo(2); แต่สิ่งนี้ไม่ได้รวบรวม: https://godbolt.org/z/hAA9TE int x = 2; auto f = Foo(x); /* &lt;source&gt;:12:15: error: no viable constructor or deduction guide for deduction of template arguments of 'Foo' auto f = Foo(x); ^ &lt;source&gt;:7:5: note: candidate function [with …
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.