<cstdint> so với <stdint.h>


95

Sự khác biệt giữa stdint.hvà là cstdintgì?

Cả hai đều có sẵn trong MSVC (Visual Studio 2010) và gcc-4.5.1. Ngoài ra, cả hai đều xác định các loại intX_t/ uintX_t(trong đó Xkích thước tính bằng byte của loại).

  • Nếu cơ sở lý luận trong cả hai tiêu đề giống nhau (loại di động), tôi phải đưa ra quyết định nào để quyết định cái này hay cái kia?

Định stdint.hnghĩa mỗi kiểu mà không có bất kỳ không gian tên nào, các cstdintkiểu nằm trong stdkhông gian tên.

  • Có bất kỳ lý do gì để bao gồm hoặc không bao gồm các kiểu đã xác định vào stdkhông gian tên? Sự khác biệt giữa hai tiêu đề là gì?

cstdintkhông có phần mở rộng tệp và sử dụng ctiền tố, stdint.hsử dụng .hphần mở rộng.

  • Quy ước đặt tên cho tiêu đề này là gì? các ctiền tố chỉ ra rằng đây là một thư viện C? có một lý do cho việc thiếu phần mở rộng tệp trong cstdint?

OS X 10.8 thiếu <cstdint>. Đây là lỗi tôi nhận được: ./misc.h:7:10: fatal error: 'cstdint' file not found.
jww

Câu trả lời:


122

Mục đích ban đầu trong C ++ 98 là bạn nên sử dụng <cstdint>trong C ++, để tránh làm ô nhiễm không gian tên chung (tốt, không phải <cstdint>cụ thể, điều đó chỉ được thêm trong C ++ 11, nhưng các <c*>tiêu đề nói chung).

Tuy nhiên, dù sao thì việc triển khai vẫn tiếp tục đưa các ký hiệu vào không gian tên chung và C ++ 11 đã phê chuẩn thực hành này [*]. Vì vậy, về cơ bản bạn có ba lựa chọn:

  • Sử dụng <cstdint>và hoàn toàn đủ điều kiện cho mỗi kiểu số nguyên bạn sử dụng hoặc nếu không thì đưa nó vào phạm vi với using std::int32_t;vv (khó chịu vì dài dòng, nhưng đó là cách đúng để làm điều đó giống như bất kỳ ký hiệu nào khác trong thư viện chuẩn C ++)
  • Sử dụng <stdint.h>(hơi tệ vì không được dùng nữa)
  • Sử dụng <cstdint>và cho rằng việc triển khai của bạn sẽ đặt các ký hiệu trong không gian tên chung (rất tệ vì không được đảm bảo).

Trong thực tế, tôi nghi ngờ rằng một lượng lớn mã gây phiền nhiễu sử dụng tùy chọn cuối cùng, đơn giản vì nó dễ thực hiện một cách tình cờ trên một triển khai nơi <cstdint>đặt các ký hiệu trong không gian tên chung. Bạn nên thử sử dụng cái đầu tiên. Điều thứ hai có một đức tính, đó là đảm bảo đưa nội dung vào không gian tên chung thay vì chỉ có thể làm điều đó. Tôi không nghĩ điều đó đặc biệt hữu ích, nhưng nó có thể tiết kiệm một số thao tác nhập nếu đó là ưu tiên của bạn.

Có một tùy chọn thứ tư, #include <cstdint>tiếp theo là tùy chọn using namespace std;này đôi khi hữu ích nhưng có những chỗ bạn không nên đặt using namespace std;. Những người khác nhau sẽ có những ý tưởng khác nhau về vị trí của những vị trí đó, nhưng "ở cấp cao nhất trong tệp tiêu đề" thì tệ hơn "ở cấp cao nhất trong tệp cpp", tệ hơn là "ở phạm vi hạn chế". Một số người không bao giờ viếtusing namespace std; gì cả.

[*] Điều đó có nghĩa là các tiêu đề chuẩn C ++ được phép đưa nội dung vào không gian tên chung nhưng không bắt buộc. Vì vậy, bạn phải tránh va chạm với những biểu tượng đó, nhưng bạn không thể thực sự sử dụng chúng vì chúng có thể không ở đó. Về cơ bản, không gian tên toàn cục trong C ++ là một bãi mìn, hãy cố gắng tránh nó. Người ta có thể tranh luận rằng ủy ban đã phê chuẩn một thực tiễn bởi các triển khai gần như có hại như việc gắn using namespace std;ở cấp cao nhất trong tệp tiêu đề - sự khác biệt là các triển khai chỉ thực hiện điều đó cho các ký hiệu trong thư viện chuẩn C, trong khi using namespace std;đó đối với C ++ -chỉ là biểu tượng quá. Có một phần trong tiêu chuẩn C liệt kê các tên được dành cho các bổ sung trong tương lai cho tiêu chuẩn. Không phải là một ý tưởng hoàn toàn ngu ngốc khi coi những tên đó là dành riêng trong không gian tên chung của C ++, nhưng nó không phải là điều cần thiết.


Câu hỏi chưa được trả lời duy nhất còn lại là về quy ước đặt tên của các tệp tiêu đề, bạn có biết về chủ đề này không?
PaperBirdMaster vào

24
@PaperBirdMaster: C ++ tiêu đề thư viện tiêu chuẩn không có phần mở rộng tập tin: <iostream>, <vector>, <cstdlib>, ngoài những người thân bao gồm cho khả năng tương thích C: <stdint.h>, <stdlib.h>. Và có, phần đầu cchỉ ra rằng <cstdlib>C ++ tương đương với tiêu đề chuẩn C <stdlib.h>, thay vì hoàn toàn mới đối với C ++ <vector>. Có một tiêu đề C ++ <complex>, vì vậy chúng ta sẽ chỉ phải hy vọng rằng không có phiên bản C trong tương lai nào giới thiệu tiêu đề chuẩn <omplex.h>.
Steve Jessop,

@SteveJessop Ơ, C99?
SS Anne

1
@ JL2210 thông báo rằng anh ấy nói <omplex.h>, không phải <complex.h>. Nếu C được thêm vào <omplex.h>, tương đương C ++ sẽ là <complex>.
John Leuenhagen

16

Bao gồm cstdintnhập các tên biểu tượng trong không gian tên std và có thể trong không gian tên toàn cầu.
Bao gồm stdint.hnhập tên biểu tượng trong không gian tên toàn cầu và có thể trong không gian tên std.

Các tính năng của Thư viện tiêu chuẩn C cũng được cung cấp trong thư viện Tiêu chuẩn C ++ và như một quy ước đặt tên chung, chúng được đặt trước bằng chữ c với các tên tương ứng trong thư viện tiêu chuẩn C.

Trong C ++, bạn nên sử dụng:

#include <cstdint>

và đủ điều kiện cho các tên ký hiệu bạn sử dụng std::
trong khi ở C, Bạn nên sử dụng:

#include <stdint.h>

Phụ lục D (quy chuẩn) Các tính năng tương thích [depr] nêu rõ:

D.6 Tiêu đề thư viện tiêu chuẩn C

1 Để tương thích với thư viện chuẩn C và C Unicode TR, thư viện chuẩn C ++ cung cấp 25 tiêu đề C, như thể hiện trong Bảng 151.

Bao gôm:

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

Và xa hơn,

2 Mọi tiêu đề C, mỗi tiêu đề có tên của biểu mẫu name.h, hoạt động như thể mỗi tên được đặt trong không gian tên thư viện chuẩn bởicname header được đặt trong phạm vi không gian tên chung.Không xác định được liệu các tên này có được khai báo hay định nghĩa lần đầu trong phạm vi không gian tên (3.3.6) của std không gian tên hay không và sau đó được đưa vào phạm vi không gian tên chung bằng cách sử dụng khai báo rõ ràng (7.3.3).

3 [Ví dụ: Tiêu đề <cstdlib>cung cấp một cách chắc chắn các khai báo và định nghĩa của nó trong không gian tên std. Nó cũng có thể cung cấp những tên này trong không gian tên chung. Tiêu đề <stdlib.h>chắc chắn cung cấp các khai báo và định nghĩa giống nhau trong không gian tên chung, giống như trong Tiêu chuẩn C. Nó cũng có thể cung cấp những tên này trong std không gian tên. —Gửi ví dụ]


-1
  1. cstdintlà tiêu đề C ++ 11, stdint.hlà tiêu đề C99 (C và C ++ là các ngôn ngữ khác nhau!)

  2. MSVC 2008 chứa không phải stdint.hvà cũng không cstdint.

  3. Việc triển khai cstdinthầu hết chỉ đơn giản #include <stdint.h>với một số bản sửa lỗi không gian tên / ngôn ngữ.


2
3. là sai. cstdintcần đưa các triển khai vào không gian tên std.
Konrad Rudolph

1
1. cũng sai, stdint.h được định nghĩa là một phần của thư viện C ++ trong Phụ lục D quy chuẩn của tiêu chuẩn C ++.
lạnh vào

@chill, bạn có thể vui lòng cung cấp liên kết đến Phụ lục D không? Ở đây en.cppreference.com/w/cpp/types/integer đã nói rằng đó là tiêu đề C ++ 11.
ghét động cơ

1
@ hate-engine, tôi khuyên bạn nên tra cứu nó trong bản sao của tiêu chuẩn C ++. Trang cppreference đó không đề cập đến stdint.h. Không có đối số nào cstdintlà tiêu đề C ++.
thư giãn

2
Không có phần nào của 1. là sai, chỉ là khi kết hợp lại với nhau thì có vẻ như bạn đang nói stdint.hkhông phải là một phần của C ++ 11. Trên thực tế, nó được yêu cầu bởi C ++ 11. Bạn có thể nói, " intlà trong C ++ 11; longlà trong C99; C và C ++ là các ngôn ngữ khác nhau!", Và không phần nào trong số đó là sai. Ví dụ của tôi thậm chí còn gây hiểu lầm hơn, vì C ++ 11 một phần tham chiếu đến C99 để xác định nội dung của cả stdint.hcstdint, nhưng không tham chiếu đến C để định nghĩa int.
Steve Jessop,
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.