ฉันจะหาคำจำกัดความของ size_t ได้ที่ไหน


123

ฉันเห็นตัวแปรที่กำหนดด้วยประเภทนี้ แต่ฉันไม่รู้ว่ามันมาจากไหนหรือจุดประสงค์ของมันคืออะไร ทำไมไม่ใช้ int หรือไม่ได้ลงนาม int? (ประเภทที่ "คล้ายกัน" อื่น ๆ ล่ะ void_t ฯลฯ )


คำถามที่ถูกต้อง: stackoverflow.com/questions/502856/…
kjfletch

@kjfletch: อืมมันแปลกที่การค้นหาคำว่า 'size_t' (เหมือนที่เคยทำก่อนหน้านี้) กลับไม่ตอบคำถามนั้น
Eliseo Ocampos

1
@Eliseo - ฟังก์ชันการค้นหาของ Stackoverflow นั้นแย่มาก ใช้ Google กับพารามิเตอร์ "site: stackoverflow.com" แทน
Michael Burr

8
OP ถามเป็นพิเศษฉันจะหาคำจำกัดความของ size_t ได้ที่ไหน? ฉันมาที่นี่เพื่อค้นหาสิ่งเดียวกัน สิ่งที่อ้างถึงไม่ได้กล่าวถึงว่าจะหาคำประกาศได้จากที่ใด
jww

9
เห็นได้ชัดว่าคำถามนี้ไม่ใช่คำถามเดียวกับคำถามที่เชื่อมโยง "ฉันพบบางสิ่งอยู่ที่ไหน"ไม่ใช่สิ่งเดียวกับ"ความแตกต่างระหว่างอะไร" (แม้ว่าคำตอบของคำตอบหนึ่งจะให้คำตอบแก่อีกข้อก็ตาม) การค้นหาของ Google ของฉันสำหรับ 'C ++ ที่เป็นความหมาย size_t' เอาฉันตรงที่นี่และผมจะได้คิดถึงคำถามอื่น ๆ เพราะมันแตกต่างกัน
Dan Nissenbaum

คำตอบ:


122

จากWikipedia

stdlib.hและstddef.hไฟล์ส่วนหัวกำหนดประเภทข้อมูลที่เรียกว่าsize_t1ซึ่งจะใช้เพื่อแสดงขนาดของวัตถุ ฟังก์ชันไลบรารีที่ใช้ขนาดคาดว่าจะเป็นประเภทsize_tและตัวดำเนินการ sizeof จะประเมินเป็นsize_tและประเมินผู้ประกอบการที่จะ

ประเภทที่แท้จริงขึ้นsize_tอยู่กับแพลตฟอร์ม เป็นความผิดพลาดที่พบบ่อยคือการสมมติsize_tเป็นเช่นเดียวกับ int ไม่ได้ลงนามซึ่งสามารถนำไปสู่ข้อผิดพลาดของการเขียนโปรแกรม2โดยเฉพาะอย่างยิ่งเป็น 64 บิตสถาปัตยกรรมกลายเป็นที่แพร่หลายมากขึ้น

จากC99 7.17.1 / 2

ประเภทและมาโครต่อไปนี้กำหนดไว้ในส่วนหัวมาตรฐาน stddef.h

<snip>

size_t

ซึ่งเป็นประเภทจำนวนเต็มที่ไม่ได้ลงชื่อของผลลัพธ์ของตัวดำเนินการ sizeof


2
ตัวอย่างเช่นใน Win64 intและunsigned intประเภทคือ 32 บิตในขณะที่ size_t คือ 64 บิต
Michael Burr

7
โปรดดูมาตรฐาน ISO C (99) (ซึ่งรวมถึงมาตรฐาน C ++) ส่วน 7.17 และ 7.18.3
Martin York

3
@LokiAstari ทำไมคุณไม่แก้ไขคำตอบเพราะคุณรู้ว่ามันเขียนไว้ที่ไหนในมาตรฐาน?
Hi-Angel

คำตอบ C ++ อยู่ที่ไหน?
Lothar

@Lothar ฉันคิดว่าความแตกต่างเพียงอย่างเดียวคือ size_t อาจเป็นคำหลักและมีความหมายเหมือนกัน
Paul Stelian

30

ตามคำอธิบาย size_t บน en.cppreference.com size_tกำหนดไว้ในส่วนหัวต่อไปนี้:

std::size_t

...    

Defined in header <cstddef>         
Defined in header <cstdio>      
Defined in header <cstring>         
Defined in header <ctime>       
Defined in header <cwchar>

2
นี่คือสิ่งที่ฉันต้องการคำตอบนี้ควรได้รับการโหวต
neodelphi

27

size_t คือประเภทจำนวนเต็มที่ไม่ได้ลงชื่อของผลลัพธ์ของตัวดำเนินการ sizeof (ISO C99 มาตรา 7.17)

ตัวsizeofดำเนินการให้ขนาด (เป็นไบต์) ของตัวถูกดำเนินการซึ่งอาจเป็นนิพจน์หรือชื่อในวงเล็บของชนิด ขนาดถูกกำหนดจากประเภทของตัวถูกดำเนินการ ผลลัพธ์คือจำนวนเต็ม ค่าของผลลัพธ์คือการนำไปใช้งานและประเภท (ประเภทจำนวนเต็มที่ไม่ได้ลงชื่อ) คือsize_t(ISO C99 มาตรา 6.5.3.4)


คำตอบที่ดีที่สุดเมื่ออ้างอิงถึงมาตรฐาน
Martin York

1
@Martin - จริงพอ แต่ฉันคิดว่าส่วน 'ทำไมไม่ใช้ int ไม่ได้ลงนาม' นั้นน่าสนใจ (หรือมากกว่า) เท่ากับส่วน 'size_t' คืออะไรและคุณจะไม่พบสิ่งนั้นในมาตรฐาน .
Michael Burr

ใช่ยกเว้นไม่มี 'มาตรา17.17 ': p. หายากไม่มีใครพูดอะไรเกี่ยวกับ Void_t
Eliseo Ocampos

ฉันยอมรับคำตอบนี้เนื่องจากตอบคำถามโดยตรง แต่จะดีมากหากได้รับคำตอบจาก Michael
Eliseo Ocampos

58
สงสารคำตอบของคุณไม่ได้บอกฉันว่าจะรวมไฟล์ส่วนหัวอะไร
Matt

6

การพูดจริงsize_tแสดงถึงจำนวนไบต์ที่คุณสามารถระบุได้ ในสถาปัตยกรรมสมัยใหม่ส่วนใหญ่ในช่วง 10-15 ปีที่ผ่านมานั้นมีขนาด 32 บิตซึ่งมีขนาดเท่ากับ int ที่ไม่ได้ลงนาม อย่างไรก็ตามเรากำลังย้ายไปใช้ที่อยู่ 64 บิตในขณะที่uintส่วนใหญ่จะอยู่ที่ 32 บิต(ไม่รับประกันขนาดในมาตรฐาน c ++) ในการสร้างรหัสของคุณที่ขึ้นอยู่กับขนาดหน่วยความจำแบบพกพาในสถาปัตยกรรมต่างๆคุณควรใช้ไฟล์size_t. ตัวอย่างเช่นสิ่งต่างๆเช่นขนาดอาร์เรย์ควรใช้size_t's เสมอ หากคุณดูที่คอนเทนเนอร์มาตรฐาน::size()ผลตอบแทนเสมอ a size_t.

โปรดทราบว่า Visual Studio มีตัวเลือกการคอมไพล์ที่สามารถตรวจสอบข้อผิดพลาดประเภทนี้ที่เรียกว่า "ตรวจหาปัญหาการพกพา 64 บิต"


2

ด้วยวิธีนี้คุณจะทราบได้เสมอว่าขนาดคือเท่าใดเนื่องจากชนิดเฉพาะเจาะจงสำหรับขนาด คำถามของตัวเองแสดงให้เห็นว่าอาจเป็นปัญหาได้: เป็นintหรือunsigned int? นอกจากนี้สิ่งที่เป็นขนาด ( short, int, longฯลฯ )?

เนื่องจากมีการกำหนดประเภทเฉพาะคุณจึงไม่ต้องกังวลเกี่ยวกับความยาวหรือการเซ็นชื่อ

คำจำกัดความที่แท้จริงสามารถพบได้ในไลบรารีอ้างอิง C ++ซึ่งระบุว่า:

ประเภท: size_t(ประเภทอินทิกรัลที่ไม่ได้ลงชื่อ)

หัวข้อ: <cstring>

size_tสอดคล้องกับชนิดข้อมูลที่ส่งคืนโดยตัวดำเนินการภาษาsizeofและกำหนดไว้ในไฟล์<cstring>ไฟล์ส่วนหัว (ในกลุ่มอื่น ๆ ) เป็นชนิดอินทิกรัลที่ไม่ได้ลงชื่อ

ใน<cstring>นั้นจะถูกใช้เป็นชนิดของพารามิเตอร์numในฟังก์ชั่นmemchr, memcmp, memcpy, memmove, memset, strncat, strncmp, strncpyและstrxfrmซึ่งในทุกกรณีจะใช้ในการระบุจำนวนสูงสุดของไบต์หรือตัวอักษรที่ฟังก์ชั่นที่มีการส่งผลกระทบต่อ

นอกจากนี้ยังใช้เป็นประเภทผลตอบแทนสำหรับstrcspn, strlen, strspnและstrxfrmขนาดผลตอบแทนและความยาว


2

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


1

ฉันไม่คุ้นเคยกับการvoid_tยกเว้นเป็นผลมาจากการค้นหาของ Google (มันใช้ในห้องสมุดโดย Kiem-ษ์ Vo ที่ AT & T วิจัยvmalloc - ฉันแน่ใจว่ามันใช้ในห้องสมุดอื่น ๆ เช่นกัน)

xxx_t typedefs ต่างๆใช้เพื่อสร้างนามธรรมประเภทหนึ่งจากการใช้งานที่แน่นอนเฉพาะเนื่องจากประเภทคอนกรีตที่ใช้สำหรับบางสิ่งอาจแตกต่างกันไปในแต่ละแพลตฟอร์ม ตัวอย่างเช่น:

  • size_t เป็นนามธรรมประเภทที่ใช้ในการเก็บขนาดของวัตถุเนื่องจากในบางระบบค่านี้จะเป็นค่า 32 บิตในบางระบบอาจเป็น 16 บิตหรือ 64 บิต
  • Void_tนามธรรมประเภทของตัวชี้ที่ส่งคืนโดยรูทีนvmallocไลบรารีเนื่องจากถูกเขียนขึ้นเพื่อทำงานบนระบบที่กำหนด ANSI / ISO C ไว้ล่วงหน้าโดยที่voidอาจไม่มีคีย์เวิร์ด อย่างน้อยนั่นคือสิ่งที่ฉันคาดเดา
  • wchar_t บทคัดย่อประเภทที่ใช้สำหรับอักขระแบบกว้างเนื่องจากในบางระบบจะเป็นประเภท 16 บิตส่วนประเภทอื่นจะเป็นประเภท 32 บิต

ดังนั้นหากคุณเขียนโค้ดการจัดการอักขระแบบกว้างเพื่อใช้wchar_tประเภทแทนกล่าวunsigned shortว่าโค้ดนั้นน่าจะพกพาไปยังแพลตฟอร์มต่างๆได้มากขึ้น


นี่คือสิ่งที่ฉันกำลังมองหาบางส่วน ดังที่ฉันได้กล่าวไว้ในความคิดเห็นในคำตอบของ fpmurphy มันจะดีมากที่สามารถเติมเต็มด้วยคำตอบนี้ได้ (ถ้าคุณไม่รังเกียจคุณสามารถแก้ไขได้) :)
Eliseo Ocampos

1

ในโปรแกรมมินิมัลลิสต์ที่size_tคำจำกัดความไม่ได้โหลด "โดยบังเอิญ" ในบางโปรแกรมมี แต่ฉันยังต้องการใช้ในบางบริบท (เช่นเพื่อเข้าถึงstd::vector<double>) ฉันจึงใช้บริบทนั้นเพื่อแยกประเภทที่ถูกต้อง ตัวอย่างเช่นtypedef std::vector<double>::size_type size_t .

(ล้อมรอบด้วยnamespace {...}ถ้าจำเป็นเพื่อให้ขอบเขต จำกัด )


1

สำหรับ "ทำไมไม่ใช้ int หรือไม่ได้ลงนาม int" เพียงเพราะมันมีความหมายมากกว่าที่จะไม่ มีเหตุผลในทางปฏิบัติที่สามารถพูดtypedefd เป็นintและอัพเกรดเป็นlongรุ่นหลังได้โดยไม่ต้องมีใครเปลี่ยนรหัสแน่นอน แต่โดยพื้นฐานแล้วประเภทควรจะมีความหมาย เพื่อให้ง่ายขึ้นอย่างมากตัวแปรประเภทsize_tจึงเหมาะสำหรับและใช้สำหรับซึ่งมีขนาดของสิ่งต่างๆเช่นเดียวกับtime_tที่เหมาะสำหรับการบรรจุค่าเวลา วิธีการนำไปใช้จริงควรเป็นงานของการนำไปใช้งาน เมื่อเทียบกับการเรียกทุกอย่างการintใช้ชื่อประเภทที่มีความหมายเช่นนี้จะช่วยชี้แจงความหมายและเจตนาของโปรแกรมของคุณเช่นเดียวกับชุดประเภทที่หลากหลาย

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