<cstdint> เทียบกับ <stdint.h>


99

อะไรคือความแตกต่างระหว่างstdint.hและcstdint?

ทั้งสองมีอยู่ใน MSVC (Visual Studio 2010) และ gcc-4.5.1 ทั้งคู่ยังกำหนดintX_t/ uintX_ttypes (โดยที่Xขนาดเป็นไบต์ของชนิด)

  • หากเหตุผลในส่วนหัวทั้งสองเหมือนกัน (ประเภทพกพา) ฉันต้องตัดสินใจอะไรในการตัดสินใจอย่างใดอย่างหนึ่ง

stdint.hกำหนดแต่ละประเภทโดยไม่ต้อง namespace ใด ๆcstdintชนิดอยู่ในstdnamespace

  • มีเหตุผลใดบ้างที่จะรวมหรือไม่รวมประเภทที่กำหนดไว้ในstdเนมสเปซ อะไรคือความแตกต่างระหว่างสองส่วนหัว?

cstdintไม่มีนามสกุลไฟล์และใช้cคำนำหน้าstdint.hใช้.hนามสกุล.

  • หลักการตั้งชื่อสำหรับส่วนหัวนี้มีอะไรบ้าง? cคำนำหน้าบ่งบอกว่านี่เป็นห้องสมุด C? มีสาเหตุที่ทำให้ไม่มีนามสกุลไฟล์ในcstdint?

OS X 10.8 <cstdint>ขาด ./misc.h:7:10: fatal error: 'cstdint' file not foundต่อไปนี้เป็นข้อผิดพลาดที่ผมได้รับ:
jww

คำตอบ:


126

ความตั้งใจเดิมใน C ++ 98 คือคุณควรใช้<cstdint>ใน C ++ เพื่อหลีกเลี่ยงการสร้างมลพิษให้กับเนมสเปซทั่วโลก ( <cstdint>โดยเฉพาะอย่างยิ่งไม่ได้เพิ่มเฉพาะใน C ++ 11 แต่<c*>ส่วนหัวโดยทั่วไป)

อย่างไรก็ตามการใช้งานยังคงมีอยู่ในการใส่สัญลักษณ์ลงในเนมสเปซส่วนกลางและ C ++ 11 ให้สัตยาบันการปฏิบัตินี้ [*] โดยพื้นฐานแล้วคุณมีสามตัวเลือก:

  • ใช้<cstdint>และตรวจสอบคุณสมบัติของจำนวนเต็มแต่ละประเภทที่คุณใช้หรือไม่ก็นำมาเป็นขอบเขตด้วยusing std::int32_t;ฯลฯ (น่ารำคาญเพราะ verbose แต่เป็นวิธีที่ถูกต้องเช่นเดียวกับสัญลักษณ์อื่น ๆ ในไลบรารีมาตรฐาน C ++)
  • ใช้งาน<stdint.h>(แย่เล็กน้อยเพราะเลิกใช้งานแล้ว)
  • การใช้<cstdint>และถือว่าการนำไปใช้ของคุณจะทำให้สัญลักษณ์ในเนมสเปซส่วนกลาง (แย่มากเพราะไม่รับประกัน)

ในทางปฏิบัติฉันสงสัยว่าโค้ดจำนวนมากที่น่ารำคาญใช้ตัวเลือกสุดท้ายเพียงเพราะมันง่ายที่จะทำโดยบังเอิญในการนำไปใช้งานซึ่ง<cstdint>ทำให้สัญลักษณ์ในเนมสเปซส่วนกลาง คุณควรลองใช้ครั้งแรก ประการที่สองมีคุณธรรมประการหนึ่งคือรับประกันได้ว่าจะใส่สิ่งต่างๆลงในเนมสเปซส่วนกลางแทนที่จะทำเพียงอย่างเดียว ฉันไม่คิดว่าจะมีประโยชน์มากนัก แต่อาจช่วยประหยัดการพิมพ์ได้หากนั่นเป็นสิ่งสำคัญของคุณ

มีตัวเลือกที่สี่#include <cstdint>ตามด้วยusing namespace std;ซึ่งบางครั้งก็มีประโยชน์ แต่มีสถานที่ที่คุณไม่ควรใส่ไฟล์using namespace std;. แต่ละคนจะมีแนวคิดที่แตกต่างกันว่าสถานที่เหล่านั้นอยู่ที่ไหน แต่ "ที่ระดับบนสุดในไฟล์ส่วนหัว" แย่กว่า "ที่ระดับบนสุดในไฟล์ cpp" ซึ่งแย่กว่า "ในขอบเขตที่ จำกัด " บางคนไม่เคยเขียนusing namespace std;เลย

[*] นั่นหมายความว่าส่วนหัวมาตรฐาน C ++ ได้รับอนุญาตให้ใส่ข้อมูลในเนมสเปซส่วนกลาง แต่ไม่จำเป็นต้องใช้ ดังนั้นคุณต้องหลีกเลี่ยงการชนกับสัญลักษณ์เหล่านั้น แต่คุณไม่สามารถใช้งานได้จริงเพราะอาจไม่มีอยู่ โดยทั่วไปเนมสเปซส่วนกลางใน C ++ เป็นพื้นที่วางทุ่นระเบิดพยายามหลีกเลี่ยง อาจมีคนโต้แย้งว่าคณะกรรมการได้ให้สัตยาบันต่อการปฏิบัติโดยการนำไปใช้งานที่เกือบจะเป็นอันตรายเท่ากับการติดusing namespace std;ที่ระดับบนสุดในไฟล์ส่วนหัว - ความแตกต่างคือการใช้งานทำเพื่อสัญลักษณ์ในไลบรารีมาตรฐาน C เท่านั้นในขณะที่using namespace std;C ++ - สัญลักษณ์เท่านั้นด้วย มีส่วนในมาตรฐาน C ที่แสดงรายชื่อที่สงวนไว้สำหรับการเพิ่มเติมในอนาคตในมาตรฐาน ไม่ใช่ความคิดที่โง่อย่างสิ้นเชิงที่จะปฏิบัติต่อชื่อเหล่านั้นตามที่สงวนไว้ในเนมสเปซส่วนกลางของ C ++ เช่นกัน แต่ก็ไม่จำเป็น


คำถามเดียวที่ยังไม่มีคำตอบที่ยังคงอยู่คือเกี่ยวกับหลักการตั้งชื่อของไฟล์ส่วนหัวคุณรู้เกี่ยวกับหัวข้อนี้หรือไม่?
PaperBirdMaster

25
@PaperBirdMaster: C ++ ส่วนหัวห้องสมุดมาตรฐานไม่ได้มีนามสกุลไฟล์: <iostream>, <vector>, <cstdlib>นอกเหนือจากคนที่รวมสำหรับ C ความเข้ากันได้: ,<stdint.h> <stdlib.h>และใช่เริ่มต้นcแสดงให้เห็นว่า<cstdlib>คือ C ++ 's เทียบเท่าของส่วนหัวมาตรฐาน C <stdlib.h>แทนที่จะเป็นใหม่ทั้งหมดเพื่อ c ++ เหมือน<vector>มี มี c ++ ส่วนหัวเป็น<complex>ดังนั้นเราก็จะต้องหวังว่าไม่มีรุ่นอนาคตของ C <omplex.h>แนะนำหัวมาตรฐาน
Steve Jessop

@SteveJessop เอิ่ม C99?
SS Anne

1
@ JL2210 สังเกตว่าเขาบอกว่า<omplex.h>ไม่ใช่<complex.h>. ถ้า C เพิ่ม<omplex.h>เทียบเท่า C ++ <complex>จะเป็น
John Leuenhagen

16

รวมถึงcstdintการนำเข้าชื่อสัญลักษณ์ในเนมสเปซมาตรฐานและอาจเป็นไปได้ใน Global namespace
รวมถึงstdint.hการนำเข้าชื่อสัญลักษณ์ในเนมสเปซส่วนกลางและอาจอยู่ในเนมสเปซมาตรฐาน

คุณสมบัติของไลบรารีมาตรฐาน C ยังมีให้ในไลบรารีมาตรฐาน C ++ และตามหลักการตั้งชื่อทั่วไปพวกเขาจะถูกกำหนดไว้ล่วงหน้าโดย c กับชื่อที่เกี่ยวข้องในไลบรารีมาตรฐาน C

ใน C ++ คุณควรใช้:

#include <cstdint>

และมีคุณสมบัติครบถ้วนตามชื่อสัญลักษณ์ที่คุณใช้std::
ขณะอยู่ใน C คุณควรใช้:

#include <stdint.h>

ภาคผนวก D (ปกติ) คุณลักษณะที่เข้ากันได้ [depr]รัฐ:

D.6 C ส่วนหัวของไลบรารีมาตรฐาน

1 เพื่อความเข้ากันได้กับไลบรารีมาตรฐาน C และ C Unicode TR ไลบรารีมาตรฐาน C ++ จะมีส่วนหัว 25 C ดังแสดงในตารางที่ 151

ซึ่งรวมถึง:

<assert.h> <float.h> <math.h> <stddef.h> <tgmath.h> <complex.h> <inttypes.h> <setjmp.h> <stdio.h> <time.h> <ctype.h> <iso646.h> <signal.h> <stdint.h> <uchar.h> <errno.h> <limits.h> <stdarg.h> <stdlib.h> <wchar.h> <fenv.h> <locale.h> <stdbool.h> <string.h> <wctype.h>

และต่อไป,

2 ทุกส่วนหัวของ C ซึ่งแต่ละส่วนมีชื่อของฟอร์มname.hจะทำงานเหมือนกับว่าแต่ละชื่อที่อยู่ในเนมสเปซไลบรารีมาตรฐานcname headerจะถูกวางไว้ภายในขอบเขตเนมสเปซส่วนกลาง ไม่ได้ระบุว่าชื่อเหล่านี้ถูกประกาศหรือกำหนดเป็นครั้งแรกภายในขอบเขตเนมสเปซ (3.3.6) ของมาตรฐานเนมสเปซจากนั้นจะถูกฉีดเข้าไปในขอบเขตเนมสเปซส่วนกลางโดยการประกาศโดยใช้การประกาศ (7.3.3) อย่างชัดเจน

3 [ตัวอย่าง: ส่วนหัว<cstdlib>มีการประกาศและคำจำกัดความภายในเนมสเปซมาตรฐานอย่างแน่นอน นอกจากนี้ยังอาจระบุชื่อเหล่านี้ภายในเนมสเปซส่วนกลาง <stdlib.h>มั่นใจได้ว่าส่วนหัวจะมีการประกาศและคำจำกัดความเดียวกันภายในเนมสเปซส่วนกลางเช่นเดียวกับในมาตรฐาน C นอกจากนี้ยังอาจระบุชื่อเหล่านี้ภายในเนมสเปซมาตรฐาน - ส่งตัวอย่าง]


-1
  1. cstdintคือ C ++ 11 header stdint.hคือ C99 header (C และ C ++ เป็นคนละภาษา!)

  2. MSVC 2008 มีค่ามิได้stdint.hcstdint

  3. การใช้งานcstdintส่วนใหญ่เป็นเพียงการ#include <stdint.h>แก้ไขเนมสเปซ / ภาษาบางอย่าง


2
3. ผิด cstdintความต้องการที่จะยกการใช้งานลงในการ stdnamespace
Konrad Rudolph

1
1. ผิดเช่นกัน stdint.h ถูกกำหนดให้เป็นส่วนหนึ่งของไลบรารี C ++ ในภาคผนวก D ของมาตรฐาน C ++
ทำใจให้สบาย

@chill โปรดระบุลิงก์ไปยังภาคผนวก D ได้หรือไม่ ที่นี่en.cppreference.com/w/cpp/types/integerระบุว่าเป็นส่วนหัว C ++ 11
hate-engine

1
@ hate-engine ฉันขอแนะนำให้คุณค้นหาในสำเนามาตรฐาน C ++ ของคุณ หน้า cppreference stdint.hที่ไม่ได้พูดถึง ไม่มีอาร์กิวเมนต์ที่cstdintเป็นส่วนหัว C ++
ทำใจให้สบาย

2
ไม่มีส่วนใดของ 1. เป็นเท็จเพียงแค่นำมารวมกันดูเหมือนว่าคุณกำลังบอกว่าstdint.hไม่ใช่ส่วนหนึ่งของ C ++ 11 ในความเป็นจริง C ++ 11 ต้องการ คุณสามารถพูดได้ว่า " intอยู่ใน C ++ 11 longอยู่ใน C99 C และ C ++ เป็นภาษาที่แตกต่างกัน!" และไม่มีส่วนใดที่จะเป็นเท็จเช่นกัน ตัวอย่างของฉันจะยิ่งทำให้เข้าใจผิด แต่เนื่องจากภาษา C ++ 11 หมายถึงในส่วนที่ C99 เพื่อกำหนดเนื้อหาของทั้งสองstdint.hและcstdintแต่ไม่ได้หมายถึง C intถึงกำหนด
Steve Jessop
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.