ลงนามในการแปลงที่ไม่ได้ลงนามใน C - ปลอดภัยเสมอหรือไม่?


140

สมมติว่าฉันมีรหัส C ต่อไปนี้

unsigned int u = 1234;
int i = -5678;

unsigned int result = u + i;

การแปลงโดยนัยเกิดขึ้นที่นี่และรหัสนี้ปลอดภัยสำหรับค่าทั้งหมดของuและiหรือไม่ (ปลอดภัยในแง่ที่แม้ว่าผลลัพธ์ในตัวอย่างนี้จะล้นไปเป็นจำนวนบวกจำนวนมาก แต่ฉันสามารถส่งกลับไปเป็นintและได้ผลลัพธ์ที่แท้จริง)

คำตอบ:


233

คำตอบสั้น ๆ

ของคุณiจะถูกแปลงเป็นจำนวนเต็มที่ไม่ได้ลงนามโดยการเพิ่มUINT_MAX + 1จากนั้นการบวกจะดำเนินการกับค่าที่ไม่ได้ลงนามทำให้มีค่ามากresult(ขึ้นอยู่กับค่าของuและi)

คำตอบยาว

ตามมาตรฐาน C99:

6.3.1.8 การแปลงเลขคณิตปกติ

  1. หากตัวถูกดำเนินการทั้งสองมีประเภทเดียวกันก็ไม่จำเป็นต้องมีการแปลงเพิ่มเติม
  2. มิฉะนั้นหากตัวถูกดำเนินการทั้งสองมีการลงนามประเภทจำนวนเต็มหรือทั้งคู่มีประเภทจำนวนเต็มที่ไม่ได้ลงชื่อตัวถูกดำเนินการที่มีประเภทของอันดับการแปลงจำนวนเต็มน้อยจะถูกแปลงเป็นประเภทของตัวถูกดำเนินการที่มีอันดับสูงกว่า
  3. มิฉะนั้นถ้าตัวถูกดำเนินการที่มีชนิดจำนวนเต็มที่ไม่ได้ลงชื่อมีอันดับมากกว่าหรือเท่ากับอันดับของชนิดของตัวถูกดำเนินการอื่นตัวถูกดำเนินการที่มีประเภทจำนวนเต็มที่ลงนามจะถูกแปลงเป็นชนิดของตัวถูกดำเนินการที่มีประเภทจำนวนเต็มที่ไม่ได้ลงชื่อ
  4. มิฉะนั้นหากชนิดของตัวถูกดำเนินการที่มีประเภทจำนวนเต็มที่ลงนามสามารถแสดงค่าทั้งหมดของชนิดของตัวถูกดำเนินการที่มีประเภทจำนวนเต็มที่ไม่ได้ลงชื่อตัวถูกดำเนินการที่มีประเภทจำนวนเต็มไม่ได้ลงนามจะถูกแปลงเป็นชนิดของตัวถูกดำเนินการที่มีประเภทจำนวนเต็มที่มีการลงชื่อ
  5. มิฉะนั้นตัวถูกดำเนินการทั้งสองจะถูกแปลงเป็นประเภทจำนวนเต็มที่ไม่ได้ลงนามซึ่งตรงกับประเภทของตัวถูกดำเนินการที่มีประเภทจำนวนเต็มที่ลงนาม

ในกรณีของคุณเรามี int ( u) และ int ( i) ที่ไม่ได้ลงนามหนึ่งรายการ อ้างถึง (3) ข้างต้นเนื่องจากตัวถูกดำเนินการทั้งสองมีอันดับเดียวกันคุณiจะต้องถูกแปลงเป็นจำนวนเต็มที่ไม่ได้ลงชื่อ

6.3.1.3 จำนวนเต็มที่ลงชื่อและไม่ได้ลงชื่อ

  1. เมื่อค่าที่มีชนิดจำนวนเต็มถูกแปลงเป็นจำนวนเต็มชนิดอื่นที่ไม่ใช่ _Bool หากสามารถแสดงค่าได้ด้วยชนิดใหม่ค่านั้นจะไม่เปลี่ยนแปลง
  2. มิฉะนั้นหากประเภทใหม่ไม่ได้ลงนามค่าจะถูกแปลงโดยการเพิ่มหรือลบหนึ่งมากกว่าค่าสูงสุดที่สามารถแสดงในประเภทใหม่ซ้ำ ๆ จนกว่าค่าจะอยู่ในช่วงของประเภทใหม่
  3. มิฉะนั้นประเภทใหม่จะถูกลงนามและไม่สามารถแสดงค่าได้ ไม่ว่าผลลัพธ์จะถูกกำหนดโดยการนำไปใช้งานหรือสัญญาณที่กำหนดการนำไปใช้งานจะถูกยกขึ้น

ตอนนี้เราต้องอ้างถึง (2) ด้านบน ของคุณจะถูกแปลงเป็นค่าที่ได้รับการรับรองโดยการเพิ่มi UINT_MAX + 1ดังนั้นผลลัพธ์จะขึ้นอยู่กับวิธีที่UINT_MAXกำหนดไว้ในการนำไปใช้งานของคุณ มันจะใหญ่ แต่จะไม่ล้นเพราะ:

6.2.5 (9)

การคำนวณที่เกี่ยวข้องกับตัวถูกดำเนินการที่ไม่ได้ลงชื่อจะไม่มีวันล้นเพราะผลลัพธ์ที่ไม่สามารถแสดงโดยประเภทจำนวนเต็มที่ไม่ได้ลงนามที่เป็นผลลัพธ์จะถูกลดโมดูโลจำนวนที่มากกว่าค่าที่มากที่สุดที่สามารถแสดงโดยประเภทผลลัพธ์ได้

โบนัส: Arithmetic Conversion Semi-WTF

#include <stdio.h>

int main(void)
{
  unsigned int plus_one = 1;
  int minus_one = -1;

  if(plus_one < minus_one)
    printf("1 < -1");
  else
    printf("boring");

  return 0;
}

คุณสามารถใช้ลิงค์นี้เพื่อลองออนไลน์ได้ที่https://repl.it/repls/QuickWhimsicalBytes

โบนัส: ผลข้างเคียงของการแปลงเลขคณิต

กฎการแปลงทางคณิตศาสตร์สามารถนำมาใช้เพื่อให้ได้ค่าของUINT_MAXโดยการเริ่มต้นค่าไม่ได้ลงนามไป-1คือ:

unsigned int umax = -1; // umax set to UINT_MAX

สิ่งนี้รับประกันได้ว่าจะพกพาได้ไม่ว่าระบบจะแสดงหมายเลขที่มีลายเซ็นเป็นอย่างไรเนื่องจากกฎการแปลงที่อธิบายไว้ข้างต้น ดูคำถาม SO นี้สำหรับข้อมูลเพิ่มเติม: การใช้ -1 เพื่อตั้งค่าบิตทั้งหมดเป็นจริงนั้นปลอดภัยหรือไม่


ฉันไม่เข้าใจว่าทำไมมันไม่สามารถทำค่าสัมบูรณ์ได้แล้วถือว่าไม่ได้ลงนามเหมือนกับจำนวนบวก?
Jose Salvatierra

7
@ D.Singh ช่วยชี้ส่วนที่ผิดในคำตอบได้ไหม
Shmil The Cat

สำหรับการแปลงที่เซ็นชื่อเป็นไม่ได้ลงชื่อเราจะเพิ่มมูลค่าสูงสุดของค่าที่ไม่ได้ลงชื่อ (UINT_MAX +1) ในทำนองเดียวกันวิธีง่ายๆในการแปลงจากไม่ลงชื่อเป็นเซ็นคืออะไร? เราจำเป็นต้องลบจำนวนที่กำหนดออกจากค่าสูงสุด (256 ในกรณีของถ่านที่ไม่ได้ลงชื่อ) หรือไม่ ตัวอย่างเช่น 140 เมื่อแปลงเป็นหมายเลขที่มีลายเซ็นจะกลายเป็น -116 แต่ 20 กลายเป็น 20 เอง เคล็ดลับง่ายๆที่นี่?
Jon Wheelock


24

การแปลงจากเซ็นชื่อเป็นไม่ได้ลงนามไม่จำเป็นต้องคัดลอกหรือตีความการแสดงค่าที่ลงนามอีกครั้ง อ้างถึงมาตรฐาน C (C99 6.3.1.3):

เมื่อค่าที่มีชนิดจำนวนเต็มถูกแปลงเป็นจำนวนเต็มชนิดอื่นที่ไม่ใช่ _Bool หากสามารถแสดงค่าได้ด้วยชนิดใหม่ค่านั้นจะไม่เปลี่ยนแปลง

มิฉะนั้นหากประเภทใหม่ไม่ได้ลงนามค่าจะถูกแปลงโดยการเพิ่มหรือลบหนึ่งมากกว่าค่าสูงสุดที่สามารถแสดงในประเภทใหม่ซ้ำ ๆ จนกว่าค่าจะอยู่ในช่วงของประเภทใหม่

มิฉะนั้นประเภทใหม่จะถูกลงนามและไม่สามารถแสดงค่าได้ ไม่ว่าผลลัพธ์จะถูกกำหนดโดยการนำไปใช้งานหรือสัญญาณที่กำหนดการนำไปใช้งานจะถูกยกขึ้น

สำหรับการแสดงส่วนเสริมของทั้งสองที่เกือบจะเป็นสากลในทุกวันนี้กฎจะสอดคล้องกับการตีความบิตใหม่ แต่สำหรับการแสดงอื่น ๆ (เครื่องหมายและขนาดหรือส่วนเติมเต็ม) การใช้งาน C ยังต้องจัดให้ได้ผลลัพธ์เดียวกันซึ่งหมายความว่าการแปลงไม่สามารถคัดลอกบิตได้เท่านั้น ตัวอย่างเช่น (ไม่ได้ลงนาม) -1 == UINT_MAX โดยไม่คำนึงถึงการเป็นตัวแทน

โดยทั่วไปการแปลงใน C ถูกกำหนดให้ทำงานกับค่าไม่ใช่ในการแทนค่า

ในการตอบคำถามเดิม:

unsigned int u = 1234;
int i = -5678;

unsigned int result = u + i;

ค่าของฉันจะถูกแปลงเป็น int UINT_MAX + 1 - 5678ไม่ได้ลงนามยอม ค่านี้จะเพิ่มแล้วค่าไม่ได้ลงนาม 1234 UINT_MAX + 1 - 4444ผลผลิต

(ไม่เหมือนกับการโอเวอร์โฟลว์ที่ไม่ได้ลงนามการโอเวอร์โฟลว์ที่ลงนามจะเรียกใช้พฤติกรรมที่ไม่ได้กำหนดไว้การตัดรอบเป็นเรื่องปกติ แต่ไม่ได้รับการรับรองจากมาตรฐาน C และการเพิ่มประสิทธิภาพคอมไพเลอร์สามารถสร้างความเสียหายให้กับโค้ดที่ทำให้เกิดข้อสันนิษฐานที่ไม่มีการรับประกัน


5

อ้างถึงพระคัมภีร์ :

  • การดำเนินการเพิ่มเติมของคุณทำให้ int ถูกแปลงเป็น int ที่ไม่ได้ลงนาม
  • สมมติว่าการแสดงส่วนเสริมสองรายการและประเภทที่มีขนาดเท่ากันรูปแบบบิตจะไม่เปลี่ยนแปลง
  • การแปลงจาก int ที่ไม่ได้ลงนามเป็น int ที่ลงนามนั้นขึ้นอยู่กับการใช้งาน (แต่อาจจะได้ผลในแบบที่คุณคาดหวังในแพลตฟอร์มส่วนใหญ่ในทุกวันนี้)
  • กฎจะซับซ้อนกว่าเล็กน้อยในกรณีของการรวมเซ็นชื่อและไม่ได้ลงนามที่มีขนาดต่างกัน

4

เมื่อมีการเพิ่มตัวแปรที่ไม่ได้ลงนามและหนึ่งตัวแปรที่ลงนาม (หรือการดำเนินการไบนารีใด ๆ ) ทั้งสองจะถูกแปลงโดยปริยายเป็นไม่ได้ลงนามซึ่งในกรณีนี้จะส่งผลให้เกิดผลลัพธ์ที่ยิ่งใหญ่

ดังนั้นจึงปลอดภัยในแง่ที่ว่าผลลัพธ์อาจจะใหญ่โตและผิดพลาด แต่จะไม่มีวันผิดพลาด


ไม่จริง. 6.3.1.8 การแปลงเลขคณิตปกติหากคุณรวม int และและถ่านที่ไม่ได้ลงชื่อตัวหลังจะถูกแปลงเป็น int หากคุณรวมถ่านสองตัวที่ไม่ได้ลงนามพวกมันจะถูกแปลงเป็น int
2501

3

เมื่อการแปลงจากเซ็นเป็นไม่ได้ลงนามมีความเป็นไปได้สองประการ ตัวเลขที่เดิมเป็นค่าบวกจะยังคงอยู่ (หรือตีความว่า) เป็นค่าเดียวกัน จำนวนที่เดิมเป็นค่าลบจะถูกตีความว่าเป็นจำนวนบวกที่มากขึ้น


1

ตามที่ได้รับคำตอบก่อนหน้านี้คุณสามารถส่งไปมาระหว่างลงชื่อและไม่ได้ลงชื่อได้โดยไม่มีปัญหา ขอบกรณีสำหรับจำนวนเต็มที่ลงนามคือ -1 (0xFFFFFFFF) ลองบวกและลบจากสิ่งนั้นแล้วคุณจะพบว่าคุณสามารถส่งกลับและทำให้ถูกต้องได้

อย่างไรก็ตามหากคุณจะแคสต์ไปมาฉันขอแนะนำอย่างยิ่งให้ตั้งชื่อตัวแปรของคุณเพื่อให้ชัดเจนว่าเป็นประเภทใดเช่น:

int iValue, iResult;
unsigned int uValue, uResult;

มันง่ายเกินไปที่จะเบี่ยงเบนความสนใจจากปัญหาที่สำคัญกว่าและลืมว่าตัวแปรใดคือประเภทใดหากพวกเขาตั้งชื่อโดยไม่มีคำใบ้ คุณไม่ต้องการส่งไปยังสิ่งที่ไม่ได้ลงชื่อแล้วใช้สิ่งนั้นเป็นดัชนีอาร์เรย์


0

การแปลงโดยนัยเกิดขึ้นที่นี่

ฉันจะถูกแปลงเป็นจำนวนเต็มไม่ได้ลงชื่อ

และรหัสนี้ปลอดภัยสำหรับค่า u และ i ทั้งหมดหรือไม่

ปลอดภัยในแง่ของการถูกกำหนดไว้อย่างชัดเจนใช่ (ดูhttps://stackoverflow.com/a/50632/5083516 )

โดยทั่วไปกฎจะเขียนด้วยมาตรฐานที่อ่านยาก แต่โดยพื้นฐานแล้วการแทนค่าใดก็ตามที่ใช้ในจำนวนเต็มที่ลงนามจำนวนเต็มที่ไม่ได้ลงนามจะมีการแทนค่า 2 ของจำนวน

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

การหารและการแคสต์ไปยังประเภทจำนวนเต็มที่ไม่ได้ลงนามที่มีขนาดใหญ่ขึ้นจะมีผลลัพธ์ที่กำหนดไว้อย่างดี แต่ผลลัพธ์เหล่านั้นจะไม่ใช่การแทนค่า 2 ของ "ผลลัพธ์จริง"

(ปลอดภัยในแง่ที่แม้ว่าผลลัพธ์ในตัวอย่างนี้จะล้นไปเป็นจำนวนบวกจำนวนมาก แต่ฉันสามารถส่งกลับไปเป็น int และได้ผลลัพธ์ที่แท้จริง)

ในขณะที่การแปลงจากเซ็นเป็นไม่ได้ลงนามถูกกำหนดโดยมาตรฐาน แต่การย้อนกลับถูกกำหนดให้ใช้งานได้ทั้ง gcc และ msvc กำหนดการแปลงเพื่อให้คุณได้รับ "ผลลัพธ์จริง" เมื่อแปลงหมายเลขเสริมของ 2 ที่เก็บไว้ในจำนวนเต็มที่ไม่ได้ลงนามกลับเป็นจำนวนเต็มที่ลงนาม . ฉันคาดหวังว่าคุณจะพบพฤติกรรมอื่น ๆ ในระบบที่คลุมเครือซึ่งไม่ได้ใช้ส่วนเติมเต็ม 2 สำหรับจำนวนเต็มที่ลงนาม

https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html#Integers-implementation https://msdn.microsoft.com/en-us/library/0eex498h.aspx


-17

คำตอบที่น่ากลัวมากมาย

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 หลังจากการเพิ่มผลลัพธ์อาจยังคงล้น


6
"ints ที่ไม่ได้ลงชื่ออาจได้รับการเลื่อนระดับเป็น ints" ไม่จริง. ไม่มีการส่งเสริมจำนวนเต็มเกิดขึ้นเนื่องจากประเภทมีอันดับ> = int แล้ว 6.3.1.1: "อันดับของประเภทจำนวนเต็มที่ไม่ได้ลงชื่อจะต้องเท่ากับอันดับของประเภทจำนวนเต็มที่ลงนามที่เกี่ยวข้องถ้ามี" และ 6.3.1.8: "มิฉะนั้นถ้าตัวถูกดำเนินการที่มีประเภทจำนวนเต็มที่ไม่ได้ลงนามมีอันดับมากกว่าหรือเท่ากับอันดับของประเภทของตัวถูกดำเนินการอื่นตัวถูกดำเนินการที่มีประเภทจำนวนเต็มที่ลงนามจะถูกแปลงเป็นชนิดของตัวถูกดำเนินการที่มีจำนวนเต็มไม่ได้ลงชื่อ ประเภท. " ทั้งคู่รับประกันว่าintจะถูกแปลงเป็นunsigned intเมื่อใช้การแปลงเลขคณิตตามปกติ
CB Bailey

1
6.3.1.8 เกิดขึ้นหลังจากการส่งเสริมจำนวนเต็มเท่านั้น เปิดย่อหน้าว่า "มิฉะนั้นการส่งเสริมจำนวนเต็มจะดำเนินการกับตัวถูกดำเนินการทั้งสองจากนั้นกฎต่อไปนี้จะนำไปใช้กับตัวถูกดำเนินการที่ได้รับการส่งเสริม" ไปอ่านกฎการส่งเสริม 6.3.1.1 ... "วัตถุหรือนิพจน์ที่มีประเภทจำนวนเต็มซึ่งอันดับการแปลงจำนวนเต็มน้อยกว่าหรือเท่ากับอันดับของ int และ int ที่ไม่ได้ลงนาม" และ "ถ้า int สามารถแทนค่าทั้งหมดของ ชนิดดั้งเดิมค่าจะถูกแปลงเป็น int "
Elite Mx

1
6.3.1.1 ส่งเสริมจำนวนเต็มใช้ใช้ในการแปลงชนิดจำนวนเต็มบางอย่างที่ไม่intหรือunsigned intให้เป็นหนึ่งในประเภทเหล่านั้นที่บางสิ่งบางอย่างจากประเภทunsigned intหรือintคาดว่า เพิ่ม "หรือเท่ากับ" ใน TC2 เพื่อให้ประเภทของอันดับ Conversion ที่แจกแจงเท่ากับintหรือunsigned intจะแปลงเป็นประเภทใดประเภทหนึ่ง มันก็ไม่ได้ตั้งใจว่าโปรโมชั่นที่อธิบายไว้จะแปลงระหว่างและunsigned int intการกำหนดประเภททั่วไประหว่างunsigned intและintยังคงอยู่ภายใต้ 6.3.1.8 แม้จะโพสต์ TC2
CB Bailey

19
การโพสต์คำตอบผิดในขณะที่วิจารณ์คำตอบที่ผิดของผู้อื่นไม่ได้เป็นกลยุทธ์ที่ดีในการหางาน ... ;-)
R .. GitHub STOP HELPING ICE

6
ฉันไม่ได้โหวตให้ลบเนื่องจากความผิดระดับนี้รวมกับความหยิ่งผยองนั้นสนุกสนานเกินไป
MM
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.