ทำไมทุกคนถึงพิมพ์ดีฟมากกว่าประเภท C มาตรฐาน?


103

หากคุณต้องการที่จะใช้Qtคุณต้องโอบกอดquint8, quint16และอื่น ๆ

หากคุณต้องการที่จะใช้GLibคุณต้องยินดีต้อนรับguint8, guint16และอื่น ๆ

บนลินุกซ์มีu32, s16และอื่น ๆ

UC / OSกำหนดSINT32, UINT16และอื่น ๆ

และถ้าคุณต้องใช้สิ่งเหล่านั้นผสมกันคุณควรเตรียมพร้อมสำหรับปัญหา เพราะในเครื่องของคุณu32จะได้รับtypedefวันที่มากกว่าlongและquint32จะได้รับtypedefวันที่มากกว่าintและคอมไพเลอร์จะบ่น

ทำไมทุกคนถึงทำเช่นนี้ถ้ามี<stdint.h>? นี่เป็นประเพณีสำหรับห้องสมุดหรือไม่?


8
@Mehrdad ในการเขียนโปรแกรมไมโครคอนโทรลเลอร์คุณสามารถมีได้ทุกประเภท ในตัวอย่างของ AVR Mega (และตามด้วย Arduino ที่มีชื่อเสียง) int คือ 16 บิต นั่นอาจเป็นความประหลาดใจที่น่ารังเกียจ ในความคิดของฉัน "สั้นที่ไม่ได้ลงชื่อ" ต้องใช้ความพยายามในการพิมพ์มากกว่านี้ และมันทำให้ฉันเสียใจเสมอโดยใช้ 'ถ่านที่ไม่ได้ลงชื่อ' สำหรับ <s> ไบต์ </s> อ็อกเต็ต ตัวละครไร้นามจริงเหรอ?
Amomum

2
@Mehrdad ประเด็นคือคุณไม่สามารถแน่ใจได้จริงๆ นั่นคือเหตุผลที่stdint.hถูกคิดค้นขึ้น
glglgl

1
@glglgl: นี่เป็นอีกวิธีหนึ่งในการดูปัญหา: คุณไม่ได้ถามคำถามที่ผิดหรือ? หากคุณกำหนดเป้าหมายหลายระบบทำไมต้องใส่รหัสจำนวนบิตลงในโค้ดโดยพลการ คือทำไมไม่พูดsizeof(int) * CHAR_BIT(เช่น) แล้วใช้มันล่ะ? หากคุณintมีขนาดเล็กเกินไปที่จะเป็นตัวแทนของช่วงของคุณ (เช่นดัชนีอาเรย์) แล้วคุณเกือบจะแน่นอนไม่ควรจะใช้intต่อไป size_tแต่สิ่งที่ต้องการ ทำไมจะint32เข้าท่ากว่านี้? ความกว้างคงที่เวลาเดียวที่เหมาะสมสำหรับการสื่อสารระหว่างระบบ (เช่นรูปแบบไฟล์ / เครือข่าย) ...
user541686

1
@ Mehrdad ไม่บางครั้งฉันมีค่า (เช่นจาก ADC หรืออะไรก็ตาม) ที่ฉันต้องการจัดเก็บ ฉันรู้ว่ามันกว้าง 16 บิต ดังนั้นสิ่งที่ดีที่สุดในการใช้คือuint16_t(หรืออาจจะเป็นfastหรือleastตัวแปร) ประเด็นของฉัน: ประเภทเหล่านี้ใช้งานได้สะดวกและมีเหตุผลในการดำรงอยู่
glglgl

1
@ Mehrdad: ฉันขอแนะนำว่า - สมมติว่ามันคุ้มค่ากับความพยายามของคุณในการสร้างรหัสคุณภาพ - คุณควรกำหนด typedefs ที่ใช้งานได้ของคุณเองซึ่งหมายถึงวิธีการโต้ตอบกับ API ของฉัน / ส่วนที่เหลือของรหัสของฉันและกำหนดสิ่งเหล่านี้ด้วยเหตุผลทางเทคนิคในแง่ของ “เทคนิค” typedefs ชอบและsize_t / หรือ uint64_t
PJTraill

คำตอบ:


80

stdint.hไม่มีกลับมาเมื่อมีการพัฒนาไลบรารีเหล่านี้ ห้องสมุดแต่ละแห่งจึงสร้างtypedefs ของตัวเอง


4
และโอเคฉันคิดว่าการขาด stdint.h เป็นเหตุผลที่ดี แต่ทำไมวันนี้ typedefs เหล่านี้ถึง over int ยาวและนานและไม่เกินประเภท stdint? มันจะทำให้พวกมันเปลี่ยนกันได้อย่างน้อยที่สุด
Amomum

25
@Amomum "ทำไม Glib (ที่พัฒนาบน Linux) ไม่ใช้ Linux typedefs" ในขณะที่ "ฐานบ้าน" ของคนกะล่อนแน่นอนว่าเป็นลินุกซ์ แต่ก็เป็นได้โดยการออกแบบไลบรารีแบบพกพา การกำหนดประเภทของตัวเองทำให้มั่นใจได้ว่าสามารถพกพาได้: เราต้องปรับเปลี่ยนส่วนหัวเล็ก ๆ ซึ่งตรงกับประเภทไลบรารีให้เข้ากับประเภทแพลตฟอร์มเป้าหมายที่เหมาะสม
Peter - Reinstate Monica

3
@Amomum Why Glib (ที่พัฒนาบน Linux) ...ไม่มันไม่ใช่ กะล่อนถูกสร้างขึ้นทางก่อนที่ลินุกซ์
andy256

5
@ andy256 "GLib" ไม่ได้ย่อมาจาก "glibc" เป็นห้องสมุดที่แตกแขนงมาจาก gtk มันไม่เก่าไปกว่า Linux

2
@ andy256: glib คือ 1998 linux คือ 1991 IOW, GLib ถูกสร้างขึ้นหลังจาก Linux
MSalters

40

สำหรับไลบรารีรุ่นเก่าสิ่งนี้จำเป็นเนื่องจากไม่มีส่วนหัวที่เป็นปัญหา ( stdint.h)

อย่างไรก็ตามยังมีปัญหาอยู่: ประเภทเหล่านั้น ( uint64_tและอื่น ๆ ) เป็นคุณสมบัติเสริมในมาตรฐาน ดังนั้นการใช้งานที่เป็นไปตามข้อกำหนดอาจไม่ได้มาพร้อมกับพวกเขา - ดังนั้นจึงบังคับให้ห้องสมุดยังคงรวมไว้ในปัจจุบัน


14
uintN_tประเภทเป็นตัวเลือก แต่uint_leastN_tและuint_fastN_tประเภทไม่ได้
Kusalananda

7
@Kusalananda: น่าเศร้าที่มีประโยชน์ จำกัด
Lightness Races ใน Orbit

16
แน่นอนว่าเหตุผลที่เป็นทางเลือกก็คือคุณไม่รับประกันว่าจะมีประเภทจำนวนเต็มที่มีจำนวนบิตเท่านั้น C ยังคงรองรับสถาปัตยกรรมที่มีขนาดจำนวนเต็มค่อนข้างแปลก
celtschk

5
@LightnessRacesinOrbit: พวกเขามีประโยชน์ จำกัด อย่างไร? ฉันต้องยอมรับว่านอกเหนือจากอินเทอร์เฟซฮาร์ดแวร์ฉันไม่เห็นว่าทำไมคุณถึงต้องการจำนวนบิตที่แน่นอนแทนที่จะเป็นเพียงขั้นต่ำเพื่อให้แน่ใจว่าค่าทั้งหมดของคุณพอดี
celtschk

23
@Amomum typedefs จะจำเป็นต้องใช้ถ้าการดำเนินการมีการประชุมความต้องการประเภทนี้: "แต่ถ้าการดำเนินการให้จำนวนเต็มประเภทที่มีความกว้างของ 8, 16, 32 หรือ 64 บิตไม่มีบิต padding และ (ประเภทลงนาม) ที่มี การแสดงส่วนเสริมของทั้งสองจะกำหนดชื่อ typedef ที่เกี่ยวข้อง " (อ้างจาก N1570, 7.20.1.1 "ประเภทจำนวนเต็มความกว้างที่แน่นอน") ดังนั้นหากไลบรารีมาตรฐานไม่มีไลบรารีของบุคคลที่สามก็ไม่สามารถทำได้เช่นกัน
Eric M Schmidt

13

stdint.h ได้รับมาตรฐานตั้งแต่ปี 2542 มีแนวโน้มว่าแอปพลิเคชันจำนวนมากจะกำหนดประเภท (นามแฝงอย่างมีประสิทธิภาพ) เพื่อรักษาความเป็นอิสระบางส่วนจากสถาปัตยกรรมเครื่องต้นแบบ

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

แนวปฏิบัตินี้สะท้อนให้เห็นในรูปแบบการออกแบบFaçadeเชิงวัตถุและนักพัฒนาได้รับการละเมิดอย่างมากโดยมักจะเขียนคลาส wrapper สำหรับไลบรารีที่นำเข้าทั้งหมด

เมื่อคู่ค้ามีมาตรฐานน้อยกว่ามากและสถาปัตยกรรมของเครื่องอาจแตกต่างกันไปตั้งแต่ 16 บิต18 บิตถึง36 บิตเมนเฟรมที่มีความยาวของคำสิ่งนี้เป็นสิ่งที่ต้องพิจารณามากกว่า การปฏิบัตินี้มีความเกี่ยวข้องน้อยกว่ามากในโลกที่รวมระบบฝังตัว ARM 32 บิต ยังคงเป็นข้อกังวลสำหรับไมโครคอนโทรลเลอร์ระดับล่างที่มีแผนที่หน่วยความจำแปลก ๆ


1
จริงอยู่ที่stdint.hได้รับมาตรฐานมาตั้งแต่ปี 2542 แต่มีการปฏิบัติมานานแค่ไหน? ผู้คนลากเท้าของพวกเขาในการดำเนินการและการยอมรับมาตรฐานใหม่และในช่วงการเปลี่ยนผ่านที่ยาวนานนั้นยังคงต้องใช้วิธีการเดิม ๆ
Siyuan Ren

1
gotcha ที่น่ารังเกียจอย่างหนึ่งstdint.hก็คือแม้จะอยู่บนแพลตฟอร์มที่เช่นlongและint32_tมีขนาดและการแสดงที่เท่ากัน แต่ก็ไม่มีข้อกำหนดว่าการแคสต์int32_t*to long*จะให้ตัวชี้ที่สามารถเข้าถึงไฟล์int32_t. ฉันไม่อยากจะเชื่อเลยว่าผู้เขียน Standard คิดว่ามันชัดเจนว่าประเภทที่เข้ากันได้กับเค้าโครงควรเป็นนามแฝงที่เข้ากันได้ แต่เนื่องจากพวกเขาไม่ได้กังวลว่าจะพูดดังนั้นผู้เขียนของ gcc และ IIRC clang จึงคิดว่าภาษาจะได้รับการปรับปรุงโดยการละเว้นการใช้นามแฝง ในกรณีที่เห็นได้ชัด
supercat

2
@supercat - นั่นอาจคุ้มค่าที่จะส่งข้อผิดพลาดไปยังคณะกรรมการ C ... เพราะนั่นเป็นเรื่องโง่โดยไม่จำเป็นที่จะพูดอย่างอ่อนโยน
LThode

@LThode: เพื่อให้คณะกรรมการ C รับทราบว่าหากเกิดความผิดพลาดจะต้องมีการประกาศพฤติกรรมของเสียงดังและ gcc อย่างเป็นทางการว่าเป็นป้าน คุณคิดว่าจะเกิดขึ้นหรือไม่? สิ่งที่ดีที่สุดที่สามารถคาดหวังได้ (และ IMHO เป็นวิธีดำเนินการเชิงตรรกะ) คือการกำหนดวิธีสำหรับโปรแกรมในการระบุ "โหมดนามแฝง" หากโปรแกรมระบุว่าสามารถยอมรับกฎการใช้นามแฝงที่เข้มงวดมากคอมไพลเลอร์สามารถใช้สิ่งนั้นเพื่ออนุญาตให้มีการปรับให้เหมาะสมเกินกว่าที่เป็นไปได้ในปัจจุบัน หากโปรแกรมระบุว่าต้องใช้กฎที่ค่อนข้างเป็นมิตรกับโปรแกรมเมอร์มากกว่ากฎปัจจุบัน ...
supercat

... แต่ยังคงอนุญาตให้มีการปรับให้เหมาะสมที่เป็นประโยชน์มากมายจากนั้นคอมไพเลอร์สามารถสร้างโค้ดที่มีประสิทธิภาพมากกว่าที่จะเป็นไปได้-fno-strict-aliasแต่ก็ยังใช้งานได้จริง แม้ว่าจะไม่มีฐานรหัสที่มีอยู่ แต่ก็ไม่มีกฎชุดเดียวที่สามารถสร้างสมดุลที่ดีที่สุดของการเพิ่มประสิทธิภาพและความหมายสำหรับแอปพลิเคชันทั้งหมดได้เนื่องจากแอปพลิเคชันที่แตกต่างกันมีความต้องการที่แตกต่าง เพิ่มใน codebase ที่มีอยู่และความต้องการโหมดต่างๆควรชัดเจน
supercat

3

ดังนั้นคุณจึงมีอำนาจในการพิมพ์คำสั่ง char เป็น int

"การเข้ารหัสสยองขวัญ" รายการหนึ่งกล่าวว่าส่วนหัวของ บริษัท หนึ่งมีจุดที่โปรแกรมเมอร์ต้องการค่าบูลีนและตัวอักษรเป็นประเภทเนทีฟเชิงตรรกะสำหรับงานนั้น ๆ และเขียนtypedef bool charเช่นนั้น typedef bool intแล้วต่อมามีคนพบจำนวนเต็มเพื่อเป็นทางเลือกที่มากที่สุดตรรกะและเขียน ผลลัพธ์ที่เกิดขึ้นก่อนหน้า Unicode เป็นจริงtypedef char intเป็นจริง

ฉันคิดว่าค่อนข้างคิดไปข้างหน้าความเข้ากันได้ไปข้างหน้า

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