มาตรฐาน C รับประกันว่าsize_t
เป็นประเภทที่สามารถเก็บดัชนีอาร์เรย์ใด ๆ ซึ่งหมายความว่ามีเหตุผลsize_t
ควรจะสามารถเก็บตัวชี้ใด ๆ ฉันได้อ่านในเว็บไซต์บางแห่งที่ฉันพบใน Googles ว่าถูกกฎหมายและ / หรือควรทำงาน:
void *v = malloc(10);
size_t s = (size_t) v;
ดังนั้นใน C99 มาตรฐานแนะนำintptr_t
และuintptr_t
ประเภทซึ่งลงนามและไม่ได้ลงนามประเภทรับประกันว่าจะสามารถเก็บพอยน์เตอร์:
uintptr_t p = (size_t) v;
ดังนั้นความแตกต่างระหว่างการใช้size_t
และuintptr_t
คืออะไร? ทั้งสองแบบไม่ได้ลงนามและทั้งคู่ควรจะสามารถถือตัวชี้ประเภทใดก็ได้ มีเหตุผลที่น่าสนใจจริง ๆuintptr_t
หรือไม่ที่จะใช้(หรือดีกว่า, a void *
) มากกว่า a size_t
, มากกว่าความชัดเจน? ในโครงสร้างทึบซึ่งเขตข้อมูลจะถูกจัดการโดยฟังก์ชันภายในเท่านั้นมีเหตุผลใดที่จะไม่ทำเช่นนี้หรือไม่?
ด้วยโทเค็นเดียวกันptrdiff_t
มีชนิดที่มีลายเซ็นสามารถถือความแตกต่างของตัวชี้ได้และดังนั้นจึงสามารถจับตัวชี้ส่วนใหญ่ได้ดังนั้นจึงแตกต่างจากintptr_t
อย่างไร
ไม่ทุกประเภทเหล่านี้โดยทั่วไปให้บริการฟังก์ชั่นรุ่นเดียวกันที่แตกต่างกันเล็กน้อย? ถ้าไม่ทำไม ฉันไม่สามารถทำอะไรกับหนึ่งในนั้นที่ฉันไม่สามารถทำกับคนอื่นได้? ถ้าเป็นเช่นนั้นเหตุใด C99 จึงเพิ่มประเภทฟุ่มเฟือยสองประเภทลงในภาษา
ฉันยินดีที่จะเพิกเฉยต่อพอยน์เตอร์ของฟังก์ชั่นเนื่องจากมันไม่ได้ใช้กับปัญหาปัจจุบัน แต่อย่าลังเลที่จะพูดถึงมันเนื่องจากฉันมีความสงสัยที่ด้อมพวกเขาจะเป็นศูนย์กลางของคำตอบที่ "ถูกต้อง"
size_t
และuintptr_t
แต่สิ่งที่เกี่ยวptrdiff_t
และintptr_t
- จะไม่ทั้งสองเหล่านี้สามารถที่จะเก็บช่วงเดียวกันของค่าในเกือบทุกแพลตฟอร์มใด? เหตุใดจึงมีทั้งประเภทจำนวนเต็มขนาดตัวชี้ที่ลงนามและไม่ได้ลงนามโดยเฉพาะอย่างยิ่งถ้าptrdiff_t
ทำหน้าที่ตามวัตถุประสงค์ของประเภทจำนวนเต็มขนาดตัวชี้ลงนาม