web-dev-qa-db-fra.com

uint128_t ne nomme pas de type

Je porte du code de C vers C++. Lors de la conversion, j'ai rencontré:

uint128_t ne nomme pas de type

Mon compilateur: gcc version 5.2.1
Mon système d'exploitation: Ubuntu 15.1

Cela s'est bien compilé en C et j'ai pensé qu'il serait résolu en incluant stdint.h mais ce n'est pas le cas. Jusqu'à présent, je n'ai rien essayé d'autre car il ne semble pas y avoir beaucoup d'informations sur cette erreur ( exemple ). uint128_t est utilisé tout au long de ce programme et est essentiel pour la construction, donc je ne peux pas le supprimer, et je ne suis pas sûr d'utiliser un type entier différent.

Vous trouverez ci-dessous un exemple où et comment il est utilisé.

union {
    uint16_t  u16;
    uint32_t  u32;
    uint128_t u128;
} value;

Serait-il correct de définir un uint128_t ou devrais-je regarder mon compilateur?

12
Zimano

GCC a un support intégré pour les types __int128, unsigned __int128 , __int128_t Et __uint128_t (Les deux derniers ne sont pas documentés). Utilisez-les pour définir vos propres types:

typedef __int128 int128_t;
typedef unsigned __int128 uint128_t;

Alternativement, vous pouvez utiliser __mode__(TI):

typedef int int128_t __attribute__((mode(TI)));
typedef unsigned int uint128_t __attribute__((mode(TI)));

Citant le documentation :

TImode

Le mode "Tetra Integer" (?) Représente un entier de seize octets.

Seize octets = 16 * CHAR_BIT> = 128.

17
Andrea Corbellini

Je pensais que cela serait résolu en incluant stdint.h mais ce n'est pas le cas.

Eh bien, peut-être pas.

Tout d'abord pour vérifier l'en-tête C++, cstdint, de C++ 14, chapitre § 18.4.1,

namespace std {.....

typedef unsigned integer type uint8_t; // optional
typedef unsigned integer type uint16_t; // optional
typedef unsigned integer type uint32_t; // optional
typedef unsigned integer type uint64_t; // optional
.....

et,

L'en-tête définit toutes les fonctions, types et macros de la même manière que 7.18 dans la norme C. [..]

Citez ensuite le C11 standard, chapitre §7.20.1.1 ( accent mine )

  1. Le nom du typedef uintN_t désigne un type entier non signé de largeur N et sans bits de remplissage. Donc, uint24_t désigne un tel type entier non signé avec une largeur d'exactement 24 morceaux.

  2. Ces types sont facultatifs. Cependant, si une implémentation fournit des types entiers avec des largeurs de 8, 16, 32 ou 64 bits, pas de bits de remplissage et (pour les types signés) qui ont une représentation complémentaire à deux, elle doit définir les noms de typedef correspondants.

Donc, ici, nous remarquons deux choses.

  1. Une implémentation n'est pas mandatée pour prendre en charge les ints à largeur fixe.

  2. La norme limite la largeur jusqu'à 64, comme nous le voyons. avoir une largeur supérieure à celle-ci n'est pas une fois de plus obligatoire dans la norme. Vous devez vérifier la documentation de l'environnement utilisé.

5
Sourav Ghosh

Comme indiqué par d'autres réponses, la norme C++ ne nécessite pas la disponibilité d'un entier de 128 bits, ni d'être typedefed comme uint128_t même s'il est présent. Si votre compilateur/architecture ne prend pas en charge les entiers 128 bits et que vous en avez besoin, vous pouvez utiliser boost pour les émuler:

http://www.boost.org/doc/libs/1_58_0/libs/multiprecision/doc/html/boost_multiprecision/tut/ints/cpp_int.html

Je pense que la bibliothèque boost utilisera automatiquement le type natif si disponible

2
pqnet