unique_ptr <0 หรือผู้ปฏิบัติงานทำอะไรน้อยกว่า


9

ฉันกำลังจัดการกับรหัสที่ฉันไม่ได้เขียน ฉันมีคำสั่งนี้:

// p is type of std::unique_ptr<uint8_t[]>
if (p < 0) { /* throw an exception */ }

ดังนั้นp < 0ในบริบทนี้หมายความว่าอย่างไร
บนหน้าเอกสารผมเชื่อว่ากรณีของฉันเป็น16) y < nullptrที่เป็น0nullptr

แต่มันจะทำอะไร?


1
จากข้อเท็จจริงที่ว่าใน x64 พอยน์เตอร์แบบบัญญัติในช่วงเคอร์เนลมีการตั้งค่าบิตบนอาจเป็นวิธี (โง่ hardcoded) เพื่อตรวจสอบว่าตัวชี้เป็นของเคอร์เนลพื้นที่ - ถ้าคำตอบด้านล่างถูกต้องแม้ว่าไม่มี .
Michael Chourdakis

1
ใน WINAPI p==-1เป็นหมายเลขอ้างอิงที่ไม่ถูกต้อง เนื่องจาก2^64เป็นจำนวนมากไร้สาระใด ๆ ที่pเป็นบวกเสมอ ดังนั้นp<0ตรวจสอบหมายเลขอ้างอิงที่ไม่ถูกต้องของ WINAPI นี่ไม่ใช่รหัสที่ดี
ALX23z

@OP: คุณช่วยอธิบายเล็กน้อยเกี่ยวกับบริบทที่ใช้รหัสนี้ได้หรือไม่ ใช้กับ Linux หรือ Windows หรือไม่ ค่าของตัวชี้เกี่ยวข้องกับรหัส WINAPI บางรหัสหรือไม่ ฉันคิดว่าถ้าคุณชี้แจงว่าความคิดเห็นข้างต้นอาจเป็นคำตอบที่ดี
วอลนัท

@ ALX23z แต่ WINAPI จัดการควรเป็นประเภทuint8_t*(หรือแม้กระทั่งอาร์เรย์uint8_t)? ฉันคิดว่าพวกvoid*เขาใช่มั้ย
วอลนัท

@ วอลนัตพวกเขาไม่ใช่void*พวกเขามีมาโคร HANDLE_PTR หรือบางสิ่งซึ่งโดยทั่วไปจะเป็นlong*iirc
ALX23z

คำตอบ:


2

unique_ptr <0 หรือผู้ปฏิบัติงานทำอะไรน้อยกว่า

มันตรงกับการโอเวอร์โหลด (11) ใน operator<(const unique_ptr&, nullptr_t);cppreference 0 std::nullptr_tแปลงโดยปริยาย std::less<unique_ptr<T,D>::pointer>()(x.get(), nullptr)ตามเอกสารผลที่ได้คือ

ผลที่ได้คือการดำเนินการที่กำหนดไว้ แต่ไม่มีเงื่อนไขเท็จในระบบส่วนใหญ่ สันนิษฐานได้ว่าในระบบที่แปลกใหม่ที่เป็นโมฆะไม่มีการเป็นตัวแทนไบนารีของ 0 ผลอาจจะเป็นจริง

ฉันเชื่อว่ากรณีของฉันคือ 16)

(16) เป็นวิธีอื่น ๆ 0 > unique_ptrรอบเดียวกัน: ผลลัพธ์เหมือนกัน


แต่คอมไพเลอร์0พิจารณาnullptrแล้วหรือยัง? ฉันคิดว่านั่นคือสิ่งที่เขาสงสัย อย่างน้อยก็ไม่สมเหตุสมผลกับฉันเช่นกัน
เปลี่ยนแปลง

@alteredinstance 0 ไม่ใช่ "ถือว่า" nullptr(หรือขึ้นอยู่กับสิ่งที่คุณหมายถึงโดยการพิจารณา) 0 std::nullptr_tแปลงโดยปริยาย
eerorika

นั่นคือสิ่งที่ฉันคิด ฉันสงสัยว่ามีเอกสารใด ๆ เกี่ยวกับการแปลงโดยนัยของ0เป็นnullptrเพราะฉันเห็นเพียงสองรายการที่เข้ากันได้กับการเปรียบเทียบแบบบูลีน พวกมันเปรียบได้ แต่ฉันอยู่ภายใต้การแสดงผลที่ไม่สามารถเปลี่ยนแปลงได้
เปลี่ยนแปลง

@alteredinstance การแปลงไม่ได้เกิดขึ้นในทางตรงกันข้าม int x = nullptrมีรูปแบบไม่ดี
eerorika

2
@alteredinstance std::nullptr_tถูกออกแบบมาให้สามารถใช้งานได้กับค่าคงที่ตัวชี้โมฆะใด ๆ nullptrไม่ได้เป็นเพียง 0 (เช่นเดียวกับ 0L ตัวอย่าง) std::nullptr_tมีค่าคงที่ชี้โมฆะดังนั้นจึงเป็นความตั้งใจที่พวกเขาสามารถนำมาใช้ในการสร้าง
eerorika

2

ตรวจสอบoperator <ว่าไม่ได้โหลดมากเกินไปในฐานรหัสของคุณ นั่นเป็นวิธีเดียวที่(p < 0)จะเป็นtrueไปได้

ตัวอย่าง:

bool operator< (const std::unique_ptr<uint8_t[]>&, int) { return true; }

int main() {
    std::unique_ptr<uint8_t[]> p;
    std::cout << (p < 0) << std::endl;
}

พิมพ์:

1

การสาธิตสด

มิฉะนั้นอย่างที่คนอื่นพูด, 0แปลงโดยปริยายstd::nullptr_t, ซึ่งจะเลือกbool operator<(const unique_ptr<T, D>& x, nullptr_t)โอเวอร์โหลดซึ่งจะเรียกstd::less(p, 0)ซึ่งจะกลับfalse(แม้แต่บน Windows ด้วย-1ค่าตัวชี้)


มันไม่จำเป็นต้องfalseกลับมา มันเป็นทั้งการกำหนดการใช้งานหรือไม่ระบุ (ฉันไม่แน่ใจ) แต่ฉันยอมรับว่ามันอาจจะกลับมาfalseในการใช้งานมากที่สุด (ทั้งหมด?) ดูคำตอบเพิ่มเติมโดย @eerorika
walnut

0

นิพจน์นี้ตรงกับตัวดำเนินการเทมเพลตนี้ (0 ถูกแปลงเป็นnullptr):

template <class T, class D>
bool operator<(const unique_ptr<T, D>& x, nullptr_t);

ผลตอบแทนนี้std::less<unique_ptr<T,D>::pointer>()(p.get(), nullptr)ซึ่งเป็นเท็จเสมอ (เช่นเดียวกับstd::lessfunctor คำสั่งที่เข้มงวด) ( สาธิต )


มันไม่ได้เสมอfalseกลับ ไม่ว่าจะเป็นแบบกำหนดตามการนำไปใช้หรือไม่ระบุ มันอาจจะกลับมาเสมอfalseในการใช้งานปัจจุบัน (ทั้งหมด?) ส่วนใหญ่
วอลนัท

@ วอลนัตยกเว้นคำถามที่ถามอย่างชัดเจนเกี่ยวกับสิ่งที่มาตรฐานพูด (ผ่านแท็กภาษาทนายความ ) ฉันพยายามตอบจากมุมมองที่ใช้งานได้จริง ทั้งหมดการดำเนินการในทางปฏิบัติของการกลับมาstd::less false
YSC

ไม่เป็นไรฉันไม่พบเหตุผลของคุณ (" ในฐานะ std :: less is functor order ที่เข้มงวด ") falseมันอาจจะเป็นคำสั่งอย่างเคร่งครัดโดยไม่ต้องกลับ เหตุผลที่เป็นไปได้คือค่าตัวชี้ศูนย์จะแสดงด้วยที่อยู่ที่ต่ำที่สุดหรือบางสิ่งบางอย่างตามเส้นเหล่านั้น
วอลนัท
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.