<cstdint> vs <stdint.h>

95

Apa perbedaan antara stdint.hdan cstdint?

Keduanya tersedia dalam MSVC (Visual Studio 2010) dan gcc-4.5.1. Juga keduanya menentukan intX_t/ uintX_ttypes (di mana Xukuran dalam byte tipe).

  • Jika alasan di kedua tajuk sama (tipe portabel), keputusan apa yang harus saya ambil untuk memutuskan salah satunya?

The stdint.hmendefinisikan setiap jenis tanpa namespace, yang cstdintjenis terletak pada stdnamespace.

  • Apakah ada alasan untuk menyertakan atau tidak menyertakan tipe yang ditentukan ke dalam stdnamespace? Apa perbedaan antara kedua tajuk?

cstdinttidak memiliki ekstensi file dan menggunakan cawalan, stdint.hmenggunakan .hekstensi.

  • Apa konvensi penamaan untuk header ini? yang cawalan menunjukkan bahwa ini adalah sebuah perpustakaan C? ada alasan kurangnya ekstensi file di cstdint?
PaperBirdMaster
sumber
OS X 10.8 kurang <cstdint>. Berikut kesalahan saya terima: ./misc.h:7:10: fatal error: 'cstdint' file not found.
jww

Jawaban:

122

Maksud asli di C ++ 98 adalah agar Anda menggunakan <cstdint>C ++, untuk menghindari pencemaran namespace global (yah, tidak <cstdint>secara khusus, itu hanya ditambahkan di C ++ 11, tetapi <c*>header secara umum).

Namun, implementasi tetap dilakukan dengan meletakkan simbol ke dalam namespace global, dan C ++ 11 meratifikasi praktik ini [*]. Jadi, pada dasarnya Anda memiliki tiga opsi:

  • Gunakan <cstdint>dan baik sepenuhnya memenuhi syarat setiap jenis bilangan bulat yang Anda gunakan atau bawa ke ruang lingkup dengan using std::int32_t;dll (mengganggu karena verbose, tapi itu cara yang tepat untuk melakukannya seperti untuk simbol lain di pustaka standar C ++)
  • Gunakan <stdint.h>(sedikit buruk karena tidak digunakan lagi)
  • Gunakan <cstdint>dan asumsikan implementasi Anda akan menempatkan simbol di namespace global (sangat buruk karena tidak dijamin).

Dalam praktiknya, saya menduga bahwa sejumlah besar kode yang mengganggu menggunakan opsi terakhir, hanya karena mudah dilakukan secara tidak sengaja pada implementasi di mana <cstdint>meletakkan simbol di namespace global. Anda harus mencoba menggunakan yang pertama. Yang kedua memiliki satu keunggulan, yaitu dijamin untuk meletakkan barang-barang di namespace global daripada hanya mungkin melakukannya. Saya tidak berpikir itu sangat berguna, tetapi mungkin menghemat beberapa pengetikan jika itu prioritas Anda.

Ada opsi keempat, #include <cstdint>diikuti oleh using namespace std;yang terkadang berguna tetapi ada tempat yang tidak boleh Anda letakkan using namespace std;. Orang yang berbeda akan memiliki ide yang berbeda di mana tempat-tempat itu berada, tetapi "di tingkat teratas dalam file header" lebih buruk daripada "di tingkat teratas dalam file cpp", yang lebih buruk daripada "dalam lingkup terbatas". Beberapa orang tidak pernah menulis using namespace std;sama sekali.

[*] Artinya, header standar C ++ diizinkan untuk meletakkan barang-barang di namespace global tetapi tidak diharuskan. Jadi, Anda harus menghindari bertabrakan dengan simbol-simbol itu, tetapi Anda tidak dapat benar-benar menggunakannya karena mungkin tidak ada. Pada dasarnya, namespace global di C ++ adalah ladang ranjau, cobalah untuk menghindarinya. Orang mungkin berpendapat bahwa komite telah meratifikasi praktik dengan implementasi yang hampir sama berbahayanya dengan menempel using namespace std;di tingkat atas dalam file header - perbedaannya adalah bahwa implementasi hanya melakukannya untuk simbol di pustaka standar C, sedangkan using namespace std;melakukannya untuk C ++ simbol -hanya juga. Ada bagian dalam standar C yang mencantumkan nama yang dicadangkan untuk penambahan standar di masa mendatang. Bukan ide yang sepenuhnya bodoh untuk memperlakukan nama-nama itu sebagai yang dicadangkan di namespace global C ++ juga, tapi itu tidak penting.

Steve Jessop
sumber
Satu-satunya pertanyaan yang belum terjawab yang tersisa adalah tentang konvensi penamaan file header, apakah Anda tahu tentang topik ini?
PaperBirdMaster
24
@PaperBirdMaster: C ++ header perpustakaan standar tidak memiliki ekstensi file: <iostream>, <vector>, <cstdlib>, selain dari yang termasuk untuk kompatibilitas C: <stdint.h>, <stdlib.h>. Dan ya, awal cmenunjukkan bahwa <cstdlib>C ++ setara dengan header standar C <stdlib.h>, bukan sepenuhnya baru untuk C ++ seperti <vector>itu. Ada header C ++ <complex>, jadi kita hanya perlu berharap bahwa tidak ada versi C yang akan datang yang memperkenalkan header standar <omplex.h>.
Steve Jessop
@SteveJessop Erm, C99?
SS Anne
1
@ JL2210 perhatikan bahwa dia berkata <omplex.h>, tidak <complex.h>. Jika C ditambahkan <omplex.h>, padanan C ++ akan menjadi <complex>.
John Leuenhagen
16

Termasuk cstdintmengimpor nama simbol di namespace std dan mungkin di namespace Global.
Termasuk stdint.hmengimpor nama simbol di namespace Global dan mungkin di namespace std.

Fitur Pustaka standar C juga disediakan di pustaka Standar C ++ dan sebagai konvensi penamaan umum, fitur tersebut diawali oleh c ke nama yang sesuai di pustaka standar C.

Di C ++, Anda harus menggunakan:

#include <cstdint>

dan sepenuhnya memenuhi syarat nama simbol yang Anda gunakan std::
saat berada di C, Anda harus menggunakan:

#include <stdint.h>

Lampiran D (normatif) Fitur kompatibilitas [depr] menyatakan:

Header perpustakaan standar D.6 C

1 Untuk kompatibilitas dengan pustaka standar C dan C Unicode TR, pustaka standar C ++ menyediakan header 25 C, seperti yang ditunjukkan pada Tabel 151.

Yang termasuk:

<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>

Dan selanjutnya,

2 Setiap C header, yang masing-masing memiliki nama form name.h, berperilaku seolah-olah setiap nama ditempatkan di namespace perpustakaan standar dengan yang sesuai cname headerditempatkan dalam lingkup namespace global. Tidak ditentukan apakah nama-nama ini pertama kali dideklarasikan atau ditentukan dalam lingkup namespace (3.3.6) dari namespace std dan kemudian dimasukkan ke dalam cakupan namespace global dengan menggunakan deklarasi eksplisit (7.3.3).

3 [Contoh: Header <cstdlib>pasti menyediakan deklarasi dan definisinya di dalam namespace std. Ini juga dapat memberikan nama-nama ini dalam namespace global. Header <stdlib.h>pasti memberikan deklarasi dan definisi yang sama dalam namespace global, seperti di C Standard. Ini juga dapat memberikan nama-nama ini dalam namespace std. —Dan contoh]

Alok Save
sumber
-1
  1. cstdintadalah header C ++ 11, stdint.hadalah header C99 (C dan C ++ adalah bahasa yang berbeda!)

  2. MSVC 2008 tidak mengandung stdint.hnor cstdint.

  3. Implementasi cstdintsebagian besar hanya #include <stdint.h>dengan beberapa perbaikan namespace / bahasa.

mesin kebencian
sumber
2
3. salah. cstdintperlu mengangkat implementasi ke dalam namespace std.
Konrad Rudolph
1
1. salah juga, stdint.h didefinisikan sebagai bagian dari pustaka C ++ dalam Lampiran normatif D standar C ++.
dinginkan
@ dingin, dapatkah Anda memberikan tautan ke Lampiran D? Di sini en.cppreference.com/w/cpp/types/integer menyatakan bahwa itu adalah header C ++ 11.
mesin kebencian
1
@ hate-engine, saya sarankan Anda mencarinya di salinan standar C ++ Anda. Halaman cppreference tidak menyebutkan stdint.h. Tidak ada argumen yang cstdintmerupakan header C ++.
dinginkan
2
Tidak ada bagian dari 1. yang salah, hanya saja jika digabungkan sepertinya Anda mengatakan stdint.hbukan bagian dari C ++ 11. Sebenarnya itu dibutuhkan oleh C ++ 11. Anda bisa mengatakan, " intdalam C ++ 11; longdalam C99; C dan C ++ adalah bahasa yang berbeda!", Dan tidak ada bagian darinya yang salah. Contoh saya bahkan lebih menyesatkan, karena C ++ 11 merujuk sebagian ke C99 untuk mendefinisikan konten keduanya stdint.hdan cstdint, tetapi tidak mengacu pada C untuk mendefinisikan int.
Steve Jessop