คำตอบที่น่ากลัวมากมาย
Ozgur Ozcitak
เมื่อคุณส่งจากการลงชื่อเป็นไม่ได้ลงนาม (และในทางกลับกัน) การแสดงตัวเลขภายในจะไม่เปลี่ยนแปลง สิ่งที่เปลี่ยนแปลงคือวิธีที่คอมไพลเลอร์ตีความบิตเครื่องหมาย
นี่เป็นสิ่งที่ผิดอย่างสิ้นเชิง
Mats Fredriksson
เมื่อมีการเพิ่มตัวแปรที่ไม่ได้ลงนามและหนึ่งตัวแปรที่ลงนาม (หรือการดำเนินการไบนารีใด ๆ ) ทั้งสองจะถูกแปลงโดยปริยายเป็นไม่ได้ลงนามซึ่งในกรณีนี้จะส่งผลให้เกิดผลลัพธ์ที่ยิ่งใหญ่
นี่ก็ผิดเช่นกัน ints ที่ไม่ได้ลงนามอาจได้รับการเลื่อนระดับเป็น ints หากมีความแม่นยำเท่ากันเนื่องจากมีการเติมบิตในประเภทที่ไม่ได้ลงนาม
smh
การดำเนินการเพิ่มเติมของคุณทำให้ int ถูกแปลงเป็น int ที่ไม่ได้ลงนาม
ไม่ถูกต้อง. บางทีมันอาจจะเป็นเช่นนั้นและอาจจะไม่
การแปลงจาก int ที่ไม่ได้ลงนามเป็น int ที่ลงนามนั้นขึ้นอยู่กับการใช้งาน (แต่อาจจะได้ผลในแบบที่คุณคาดหวังในแพลตฟอร์มส่วนใหญ่ในทุกวันนี้)
ไม่ถูกต้อง. เป็นพฤติกรรมที่ไม่ได้กำหนดหากทำให้เกิดโอเวอร์โฟลว์หรือค่าจะถูกรักษาไว้
ไม่ระบุชื่อ
ค่าของ i ถูกแปลงเป็น int ที่ไม่ได้ลงนาม ...
ไม่ถูกต้อง. ขึ้นอยู่กับความแม่นยำของ int เทียบกับ int ที่ไม่ได้ลงนาม
ราคา Taylor
ตามที่ได้ตอบไปก่อนหน้านี้คุณสามารถส่งไปมาระหว่างลงชื่อและไม่ได้ลงชื่อได้โดยไม่มีปัญหา
ไม่ถูกต้อง. การพยายามจัดเก็บค่านอกช่วงของจำนวนเต็มที่มีลายเซ็นจะส่งผลให้เกิดพฤติกรรมที่ไม่ได้กำหนด
ตอนนี้ฉันสามารถตอบคำถามได้ในที่สุด
หากความแม่นยำของ int เท่ากับ int ที่ไม่ได้ลงนามคุณจะได้รับการเลื่อนระดับเป็น int ที่มีการเซ็นชื่อและคุณจะได้รับค่า -4444 จากนิพจน์ (u + i) ตอนนี้ยูและฉันควรจะมีค่าอื่น ๆ ที่คุณอาจได้รับล้นและพฤติกรรมที่ไม่ได้กำหนด แต่มีตัวเลขที่แน่นอนที่คุณจะได้รับ -4444 [1] ค่านี้จะมีประเภท int แต่คุณกำลังพยายามจัดเก็บค่านั้นไว้ใน int ที่ไม่ได้ลงชื่อเพื่อที่จะถูกส่งไปยัง int ที่ไม่ได้ลงนามและค่าที่ได้จะเป็น (UINT_MAX + 1) - 4444
หากความแม่นยำของ int ที่ไม่ได้ลงนามมากกว่า int ที่ลงนาม int จะถูกเลื่อนระดับเป็น int ที่ไม่ได้ลงนามโดยให้ค่า (UINT_MAX + 1) - 5678 ซึ่งจะถูกเพิ่มเข้าไปใน int 1234 อื่น ๆ ที่ไม่ได้ลงนามควรคุณและฉันมี ค่าอื่น ๆ ซึ่งทำให้นิพจน์อยู่นอกช่วง {0..UINT_MAX} ค่า (UINT_MAX + 1) จะถูกเพิ่มหรือลบจนกว่าผลลัพธ์ DOES จะอยู่ในช่วง {0..UINT_MAX) และจะไม่มีพฤติกรรมที่ไม่ได้กำหนดเกิดขึ้น .
ความแม่นยำคืออะไร?
จำนวนเต็มมี padding bits, sign bits และ value bits จำนวนเต็มที่ไม่ได้ลงชื่อจะไม่มีเครื่องหมายที่ชัดเจน ถ่านที่ไม่ได้ลงชื่อจะรับประกันเพิ่มเติมว่าจะไม่มีบิตช่องว่างภายใน จำนวนบิตของค่าจำนวนเต็มมีความแม่นยำเท่าใด
[Gotchas]
ไม่สามารถใช้แมโครขนาดของแมโครเพียงอย่างเดียวเพื่อกำหนดความแม่นยำของจำนวนเต็มหากมีบิตการเว้นวรรค และขนาดของไบต์ไม่จำเป็นต้องเป็นออคเต็ต (แปดบิต) ตามที่กำหนดโดย C99
[1]การล้นอาจเกิดขึ้นที่จุดใดจุดหนึ่งจากสองจุด ก่อนการเพิ่ม (ระหว่างการส่งเสริมการขาย) - เมื่อคุณมี int ที่ไม่ได้ลงนามซึ่งมีขนาดใหญ่เกินไปที่จะใส่ไว้ใน int นอกจากนี้การล้นยังอาจเกิดขึ้นหลังจากการเพิ่มแม้ว่า int ที่ไม่ได้ลงชื่อจะอยู่ในช่วงของ int หลังจากการเพิ่มผลลัพธ์อาจยังคงล้น