Cách kiểm tra nếu số nguyên chiều rộng cố định được xác định


25

Trong C ++, số nguyên chiều rộng cố định được xác định là tùy chọn , nhưng tôi dường như không thể tìm thấy cách được đề xuất để kiểm tra xem chúng có thực sự được xác định hay không.

Điều gì sẽ là một cách di động để kiểm tra nếu số nguyên chiều rộng cố định có sẵn?


Dường như không có macro kiểm tra tính năng , nhưng tôi cho rằng bạn có thể làm được#if defined(INT8_MIN)
Zereges

2
Nếu thư viện std không cung cấp macro kiểm tra tính năng cho điều đó, thì bạn có thể kiểm tra xem chuỗi công cụ bạn sử dụng có cung cấp một macro cho nó hay cho phép bạn xác định một thử nghiệm riêng. CMake, ví dụ, cho phép bạn kiểm tra các tính năng ngôn ngữ nhất định bằng cách biên dịch một cpptệp được xác định và tùy thuộc vào việc biên dịch thất bại hay không một macro mà bạn có thể xác định được đặt.
t.niese

Nếu bạn thích autoconf hơn cmake, nó có các bài kiểm tra được xác định trước cho chúng. AC_TYPE_INT8_Tvv
Shawn

Nếu bất cứ ai có bất kỳ điểm thẻ nào trong stdint , IMO cstdint nên được đề cử làm từ đồng nghĩa ( stackoverflow.com/tags/stdint/synonymouss ). Tôi không nghĩ rằng chúng ta cần các thẻ C và C ++ riêng biệt cho điều tối nghĩa này; thẻ chính trong câu hỏi là đủ.
Peter Cordes

1
@PeterCordes Lần này nó hoạt động: stackoverflow.com/tags/stdint/synonymouss
Andrew Henle

Câu trả lời:


16

Để xác định xem loại số nguyên có chiều rộng cố định được cung cấp hay không, bạn có thể kiểm tra xem một trong hai loại macro [U]INT*_MAXhoặc tương ứng [U]INT*_MINcó được xác định hay không.

// may be necessary for your C++ implementation
#define __STDC_LIMIT_MACROS 
#include <cstdint>

#ifdef INT32_MAX
// int32_t must be available to get here
int32_t some32bitIntVariable;
#endif

Trên 7,20 loại Số nguyên<stdint.h> , đoạn 4 của tiêu chuẩn C11 (lưu ý các phần được in đậm):

Đối với mỗi loại được mô tả trong tài liệu này mà việc triển khai cung cấp, <stdint.h>sẽ khai báo typedeftên đó và xác định các macro liên quan . Ngược lại, đối với mỗi loại được mô tả ở đây mà việc triển khai không cung cấp, <stdint.h>sẽ không khai báo typedeftên đó cũng như không xác định các macro liên quan .

C ++ kế thừa việc thực hiện C thông qua <cstdint>. Xem <cstdint>vs<stdint.h> để biết một số chi tiết. Cũng xem những gì làm __STDC_LIMIT_MACROS__STDC_CONSTANT_MACROScó nghĩa là gì? để biết chi tiết về __STDC_LIMIT_MACROS.

Vì vậy, nếu int32_tcó sẵn, INT32_MAXINT32_MINphải là #define'd. Ngược lại, nếu int32_tkhông có sẵn, INT32_MAXcũng không INT32_MINđược phép trở thành #define'd.

Tuy nhiên, xin lưu ý, như @NicolBolas đã nêu trong một câu trả lời khác , có thể không cần thiết phải thực sự kiểm tra.


Sẽ ngắn hơn để kiểm tra [U]INT*_Cthay vì các macro tối thiểu & tối đa
phuclv

1
@phuclv Ngoại trừ đó không phải là điều tương tự. ví dụ INT64_Cđược xác định nếu int64_least_tcó sẵn, không phải nếu int64_tcó sẵn. Tham khảo tài liệu
Các cuộc đua Lightness trong quỹ đạo

19

Nói rộng ra ... bạn không.

Nếu bạn cần sử dụng các loại số nguyên có kích thước cố định, thì điều đó có nghĩa là bạn rõ ràng cần các loại đó có kích thước cụ thể. Đó là, mã của bạn sẽ không hoạt động nếu bạn không thể lấy số nguyên của các kích thước đó. Vì vậy, bạn chỉ nên sử dụng chúng; nếu ai đó sử dụng mã của bạn trên trình biên dịch thiếu các loại đã nói, thì mã của bạn sẽ không biên dịch. Điều này là tốt, bởi vì mã của bạn sẽ không hoạt động nếu nó được biên dịch.

Nếu bạn không thực sự cần số nguyên có kích thước cố định mà chỉ muốn chúng vì một số lý do khác, thì hãy sử dụng các int_least_*loại. Nếu việc thực hiện có thể cung cấp cho bạn chính xác kích thước đó, thì các least_*loại sẽ có kích thước đó.


4
Điều này không đúng. Tôi đã viết các thông báo sơ khai thực hiện toán tử = / etc cho các nền tảng không hỗ trợ uint8_t trước đây. Nhưng vì mục đích hiệu quả và gỡ lỗi, bạn không muốn sử dụng thông qua trừ khi thực sự cần thiết.
TLW

@TLW: " Tôi đã viết các thông báo sơ khai thực hiện toán tử = / etc cho các nền tảng không hỗ trợ uint8_t trước đây. " OK, nhưng ... tại sao? Bạn đã viết mã nào cần chắc chắn rằng một byte là 8 bit (có lẽ là lý do tại sao bạn đang sử dụng uint8_t), nhưng mã này bằng cách nào đó cần để chạy trên nền tảng trong đó một byte không phải là 8 bit (ngoài việc sử dụng một byte triển khai C ++ cũ, sẽ là lý do duy nhất tại sao uint8_tkhông khả dụng)? Đó là, bên ngoài khả năng tương thích ngược, tại sao bạn cần phải làm điều này?
Nicol Bolas

độc quyền vì vậy không thể nói quá nhiều. Codebase được chia sẻ cần hỗ trợ, trong số những thứ khác, một ngăn xếp phần cứng khá kỳ quặc. uint8_tđã nhiều rõ ràng hơn so với ad-hoc (và oft-chia) cách tiếp cận trước.
TLW

Nếu bạn có một thuật toán được biểu thị dưới dạng byte 8 bit, thì thông qua là thứ bạn có thể viết một lần và rất dễ kiểm tra. Trong khi sửa chữa mọi nơi là đặc biệt và dễ dàng để có được không chính xác. O(1)so với O(n)nỗ lực. Lý do tương tự tại sao mọi người sử dụng ví dụ uint16_t. Bạn đang hỏi "tại sao không sử dụng uint32_t và tự mình sử dụng nó?", Mà câu trả lời sẽ rõ ràng.
TLW

@TLW: " Lý do tương tự tại sao mọi người sử dụng, ví dụ uint16_t. " Đó không phải lý do tôi sử dụng uint16_t. Lý do của tôi là tôi đang liên lạc với một thiết bị / định dạng / vv đang mong đợi nhận được chính xác 16 bit dữ liệu được định dạng dưới dạng nhị phân, số nguyên không dấu bằng cách sử dụng endian cho máy của tôi và nếu tôi không thể có được một loại chính xác là như vậy, sau đó giao tiếp hiệu quả với nó khó khăn hơn nhiều. Chương trình của tôi (và các API mà tôi sử dụng cùng với nó) về cơ bản không thể hoạt động trên một máy không cung cấp điều đó.
Nicol Bolas
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.