Sabit genişlikli tamsayıların tanımlanıp tanımlanmadığı nasıl kontrol edilir


25

C ++, sabit genişlik tamsayıları isteğe bağlı olarak tanımlanır , ancak gerçekten tanımlanmış olup olmadığını denetlemek için önerilen yolu bulamıyorum.

Sabit genişlikli tamsayıların mevcut olup olmadığını kontrol etmenin taşınabilir bir yolu ne olabilir?


Özellik testi makrosu gibi görünmüyor , ancak bunu yapabilirsiniz#if defined(INT8_MIN)
Zereges

2
Std kütüphanesi bunun için bir özellik testi makrosu sağlamazsa, kullandığınız araç zincirinin bir tane sağlayıp sağlamadığını veya kendi testinizi tanımlamanıza izin verip vermediğini kontrol edebilirsiniz. CMake, örneğin, tanımlı bir cppdosyayı derleyerek ve derlemenin başarısız olup olmamasına bağlı olarak tanımlayabileceğiniz bir makro ayarlanmış olmasına bağlı olarak belirli dil özelliklerini test etmenizi sağlar .
t.niese

Autoconf'un cmake olmasını tercih ederseniz, onlar için önceden tanımlanmış testler vardır. AC_TYPE_INT8_Tvb.
Shawn

Stdint'te herhangi bir etiket puanı varsa , IMO cstdint eş anlamlı olarak atanmalıdır ( stackoverflow.com/tags/stdint/synonyms ). Bu belirsiz şey için ayrı C ve C ++ etiketlerine ihtiyacımız olduğunu düşünmüyorum; sorudaki ana etiket yeterlidir.
Peter Cordes

1
@PeterCordes Bu sefer çalıştı: stackoverflow.com/tags/stdint/synonyms
Andrew Henle

Yanıtlar:


16

Sabit genişlikli bir tamsayı türü sağlanmış olup olmadığını belirlemek için, karşılık gelen [U]INT*_MAXveya [U]INT*_MINmakrolardan birinin tanımlanıp tanımlanmadığını kontrol edebilirsiniz .

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

Başına 7.20 Tamsayı tipleri<stdint.h> , C11 standardının paragrafında 4 (kalın parçalar dikkat edin):

Burada açıklanan her tip için uygulamanın <stdint.h>belirttiği typedefad ve ilgili makrolar tanımlanmalıdır . Tersine, burada tarif edilen ve uygulamanın sağlamadığı her tip için, <stdint.h>bu typedefismi beyan etmemeli veya ilişkili makroları tanımlamamalıdır .

C ++, C uygulamasını üzerinden devralır <cstdint>. Bkz <cstdint>vs<stdint.h> bazı detaylar için. Ayrıca bakınız ne yapıyoruz __STDC_LIMIT_MACROSve __STDC_CONSTANT_MACROSortalama? ayrıntılar için __STDC_LIMIT_MACROS.

Bu nedenle, eğer int32_tkullanılabilir, INT32_MAXve INT32_MINolmalıdır #defined'. Tersine, eğer int32_tmevcut değilse, ne INT32_MAXde ne de INT32_MINizin verilmez #define'd.

Yine de, @NicolBolas'ın başka bir cevapta belirttiği gibi , gerçekten kontrol etmek gerekmeyebilir.


[U]INT*_CMin & max makrolar yerine kontrol etmek daha kısa olacak
Phuclv

1
@phuclv Ancak bu aynı şey değil. örneğin INT64_C, eğer mevcutsa tanımlanır, eğer int64_least_tmevcut değilse tanımlanır int64_t. Belgelere
Orbit'teki Hafiflik Yarışları

19

Genel olarak ... bilmiyorsun.

Sabit boyutlu tamsayı türlerini kullanmanız gerekiyorsa, bu türlerin açıkça belirli boyutlarında olmaları gerektiği anlamına gelir . Yani, bu boyutların tam sayılarını alamazsanız kodunuz işlevsel olmayacaktır. Yani onları kullanmalısınız; birisi kodunuzu belirtilen türlerden yoksun bir derleyicide kullanırsa, kodunuz derlenmez. Hangi iyi, çünkü kod derleme olsaydı işe yaramazdı.

Aslında sabit boyutlu tamsayılara ihtiyacınız yoksa, ancak başka bir nedenden dolayı bunları istiyorsanız, int_least_*türleri kullanın . Uygulama tam olarak bu boyutu verebilirse, least_*türlerin bu boyutu olacaktır.


4
Bu doğru değil. Daha önce uint8_t desteklemeyen platformlar için operatör = / etc uygulayan saplama geçişleri yazdım. Ancak verimlilik ve hata ayıklama amacıyla, gerçekten gerekli olmadıkça geçidi kullanmak istemezsiniz.
TLW

@TLW: " Daha önce uint8_t özelliğini desteklemeyen platformlar için operatör = / etc uygulayan saplama geçişleri yazdım. " Tamam, ama ... neden? Hangi kodu bir baytın 8 bit olduğundan emin olmanız gereken hangi kodu yazıyordunuz (muhtemelen neden kullanıyorsunuz uint8_t), ancak bu kodun bir şekilde baytın 8 bit olmadığı bir platformda çalışması gerekiyordu ( eski C ++ uygulaması, neden uint8_tmevcut olmamasının tek nedeni olabilir)? Yani geriye dönük uyumluluk dışında bunu neden yapmanız gerekiyordu?
Nicol Bolas

tescilli çok fazla diyemeyiz. Diğer şeylerin yanı sıra, oldukça ilginç bir donanım yığınını desteklemesi gereken paylaşılan kod tabanı. önceki geçici (ve çoğu zaman kırılmış) yaklaşımdan çok daha uint8_taçıktı .
TLW

Örneğin, 8-bit bayt cinsinden ifade edilen bir algoritmanız varsa, bir geçiş bir kez yazabileceğiniz ve test edilmesi kolay bir şeydir. Oysa her yeri düzeltmek ad-hoc ve kolay anlaşılır bir şekilde yanlış. çabaya O(1)karşı O(n). İnsanların kullanmasının aynı nedeni örn uint16_t. "Neden uint32_t kullanmıyorsunuz ve kendiniz mi dökmüyorsunuz?"
TLW

@TLW: " İnsanların örneğin uint16_t kullanmasının aynı nedeni. " Bu benim kullanım nedenim değil uint16_t. Benim nedenim, makinem için endian kullanarak ikili, işaretsiz bir tamsayı olarak biçimlendirilmiş 16 bit veriyi tam olarak almayı bekleyen bir cihaz / format / vb. İle iletişim kurmam ve tam olarak , o zaman etkili bir şekilde iletişim kurmak çok daha zordur. Programım (ve onunla birlikte kullandığım API'ler) temelde bunu sağlamayan bir makinede çalışamaz.
Nicol Bolas
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.