<cstdint> ve <stdint.h>


99

Arasındaki fark nedir stdint.hve cstdint?

Her ikisi de MSVC (Visual Studio 2010) ve gcc-4.5.1'de mevcuttur. Ayrıca her ikisi de intX_t/ uintX_ttürlerini tanımlar (burada türün Xbayt cinsinden boyutu).

  • Her iki başlıktaki mantık aynıysa (taşınabilir türler), birine veya diğerine karar vermek için hangi kararları almalıyım?

stdint.hHerhangi bir ad, olmadan her türünü tanımlar cstdintiçinde türleri yalan stdad.

  • Tanımlanan türleri stdad alanına dahil etmek veya dahil etmemek için herhangi bir neden var mı ? İki başlık arasındaki fark nedir?

cstdintdosya uzantısı yoktur ve cöneki stdint.hkullanır, .huzantıyı kullanır .

  • Bu başlıklar için adlandırma kuralları nelerdir? cönek bu C kütüphanesi olduğunu gösterir? içinde dosya uzantısı olmamasının bir nedeni var cstdintmı?

OS X 10.8 eksiktir <cstdint>. İşte aldığım hata var: ./misc.h:7:10: fatal error: 'cstdint' file not found.
jww

Yanıtlar:


126

C ++ 98'deki asıl amaç <cstdint>, küresel ad alanını kirletmekten kaçınmak için C ++ 'da kullanmanız gerektiğiydi ( <cstdint>özellikle değil , bu yalnızca C ++ 11'e eklenmiştir, ancak <c*>genel olarak başlıklar).

Bununla birlikte, uygulamalar yine de sembolleri global ad alanına koymaya devam etti ve C ++ 11 bu uygulamayı onayladı [*]. Yani, temelde üç seçeneğiniz var:

  • Kullandığınız <cstdint>her bir tamsayı türünü kullanın ve tam olarak nitelendirin ya da using std::int32_t;etc ile kapsama getirin (ayrıntı çünkü sinir bozucu, ancak C ++ standart kitaplığındaki diğer herhangi bir sembol için olduğu gibi bunu yapmanın doğru yolu)
  • Kullanım <stdint.h>(kullanımdan kaldırıldığı için biraz kötü)
  • Kullanın <cstdint>ve uygulamanızın sembolleri genel ad alanına koyacağını varsayın (çok kötü çünkü garanti edilmez).

Uygulamada, can sıkıcı büyük miktarda kodun son seçeneği kullandığından şüpheleniyorum, çünkü <cstdint>sembolleri küresel ad alanına koyan bir uygulamada tesadüfen yapılması kolaydır . İlkini kullanmayı denemelisin. İkincisinin bir erdemi vardır, sadece bunu yapmak yerine global isim alanına bir şeyler koymanın garantilidir . Bunun özellikle yararlı olduğunu sanmıyorum, ancak önceliğiniz buysa, biraz yazmayı kurtarabilir.

Dördüncü bir seçenek var, #include <cstdint>ardından using namespace std;bazen yararlı olan, ancak koymamanız gereken yerler var using namespace std;. Bu yerlerin olduğu yerde farklı insanların farklı fikirleri olacaktır, ancak "bir başlık dosyasında en üst düzeyde", "sınırlı bir kapsamda" dan daha kötü olan "bir cpp dosyasında en üst düzeyde" den daha kötüdür. Bazı insanlar asla yazmaz using namespace std;.

[*] Bu, C ++ standart başlıklarının genel ad alanına bir şeyler koymasına izin verildiği ancak zorunlu olmadığı anlamına gelir. Yani bu sembollerle çarpışmaktan kaçınmalısınız, ancak onları gerçekten kullanamazsınız çünkü orada olmayabilirler. Temel olarak, C ++ 'daki global ad alanı bir mayın tarlasıdır, bundan kaçınmaya çalışın. Komitenin bir uygulamayı using namespace std;bir başlık dosyasında en üst seviyeye yapıştırmak kadar neredeyse zararlı uygulamalarla onayladığı iddia edilebilir - fark, uygulamaların bunu yalnızca C standart kütüphanesindeki semboller için yapması, oysa using namespace std;C ++ için yapmasıdır. -sadece semboller. C standardında, standarda ileride yapılacak eklemeler için ayrılmış isimleri listeleyen bir bölüm vardır. Bu adları C ++ global ad alanında da ayrılmış olarak ele almak tamamen aptalca bir fikir değil, ancak gerekli değil.


Geriye kalan tek cevaplanmamış soru başlık dosyalarının adlandırma kurallarıyla ilgili, bu konuyu biliyor musunuz?
PaperBirdMaster

25
@PaperBirdMaster: C ++ standart kitaplık başlıkları dosya uzantısı yok: <iostream>, <vector>, <cstdlib>, birbirinden C uyumluluk için dahil olanlardan: <stdint.h>, <stdlib.h>. Ve evet, başlangıç C ++ ' cda <cstdlib>olduğu gibi C ++' <stdlib.h>da tamamen yeni olmaktan ziyade C standart başlığının eşdeğeri <vector>olduğunu gösterir. Bir C ++ başlığı var <complex>, bu yüzden C'nin gelecekteki hiçbir sürümünün standart bir başlık sunmayacağını ummalıyız <omplex.h>.
Steve Jessop

@SteveJessop Erm, C99?
SS Anne

1
@ JL2210 <omplex.h>değil dedi dikkat edin <complex.h>. C eklenirse <omplex.h>, C ++ eşdeğeri olacaktır <complex>.
John Leuenhagen

16

Dahil cstdintetmek, std ad alanındaki ve muhtemelen Global ad alanındaki sembol adlarını içe aktarır .
Dahil stdint.hetmek, Global ad alanındaki ve muhtemelen std ad alanındaki sembol adlarını içe aktarır .

C standart Kitaplığının özellikleri, C ++ Standart kitaplığında da sağlanır ve genel bir adlandırma kuralı olarak, C standart kitaplığındaki karşılık gelen adların başına bir c ile eklenir.

C ++ 'da şunları kullanmanız gerekir:

#include <cstdint>

ve C'deyken kullandığınız sembol adlarını tam olarak nitelendirin, std::
kullanmalısınız:

#include <stdint.h>

Ek D (normatif) Uyumluluk özellikleri [depr] şunları belirtir:

D.6 C standart kitaplık başlıkları

1 C standart kitaplığı ve C Unicode TR ile uyumluluk için, C ++ standart kitaplığı Tablo 151'de gösterildiği gibi 25 C başlığı sağlar.

İçeren:

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

Ve Ötesi,

2 Her biri form adına sahip olan her C başlığı, name.hstandart kitaplık ad alanına karşılık gelen tarafından yerleştirilen her ad cname header, genel ad alanı kapsamına yerleştirilmiş gibi davranır . Bu adların ilk olarak std ad alanının ad alanı kapsamı (3.3.6) dahilinde bildirilip tanımlanmadığı ve daha sonra açık kullanım-bildirimleri (7.3.3) ile genel ad alanı kapsamına enjekte edilip edilmediği belirtilmemiştir.

3 [Örnek: Başlık <cstdlib>, tanımlarını ve tanımlarını kesinlikle std ad alanı içinde sağlar. Ayrıca bu adları genel ad alanı içinde sağlayabilir. Başlık <stdlib.h>, C Standardında olduğu gibi, küresel ad alanı içinde kesinlikle aynı bildirimleri ve tanımları sağlar. Bu isimleri std ad alanı içinde de sağlayabilir. —Son örnek]


-1
  1. cstdintC ++ 11 başlığı, stdint.hC99 başlığıdır (C ve C ++ farklı dillerdir!)

  2. MSVC 2008 ne içerir ne stdint.hde cstdint.

  3. Uygulamaları cstdintçoğunlukla sadece #include <stdint.h>bazı ad alanı / dil düzeltmeleriyle yapılır.


2
3. yanlış. cstdintuygulamaları ad alanına taşıması gerekiyor std.
Konrad Rudolph

1
1. de yanlıştır, stdint.h, C ++ standardının normatif Ek D'sinde C ++ kütüphanesinin bir parçası olarak tanımlanmıştır.
Chill

@chill, Ek D'ye bağlantı verebilir misiniz? Burada en.cppreference.com/w/cpp/types/integer bunun C ++ 11 başlığı olduğunu belirtmiştir.
hate-engine

1
@ hate-engine, C ++ standardı kopyanıza bakmanızı öneririm. Bu cppreference sayfası bahsetmiyor stdint.h. cstdintC ++ başlığı olan bir argüman yok .
Chill

2
1'in hiçbir parçası yanlış değildir, sadece birlikte ele alındığında stdint.hC ++ 11'in bir parçası olmadığını söylüyormuşsunuz gibi görünür . Aslında C ++ 11 için gereklidir. " intC ++ 11'de; longC99'da; C ve C ++ farklı diller!" Diyebilirsiniz ve bunun hiçbir parçası da yanlış olmaz. Benim örnek C ++ 11 hem de içeriğini tanımlamak için C99 kısmen gelir çünkü daha olsa da, yanıltıcı stdint.hve cstdintfakat tanımlamak C belirtmemektedir int.
Steve Jessop
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.