web-dev-qa-db-fra.com

Dois-je utiliser long long ou int64_t pour le code portable?

J'ai une base de code open source qui est écrite à la fois en C et C++. Je recherche un type entier qui est garanti au moins 64 bits de large, qui peut être compilé de manière fiable sur la plupart des boîtes OS X (Intel, 64 bits) et Linux avec C open-source et les compilateurs C++, sans trop de travail supplémentaire de la part de l'utilisateur final. La prise en charge de Windows et des clients 32 bits n'est pas importante pour le moment.

J'ai fait quelques tests sur OS X, et le dernier GCC fourni avec les outils de développement ne prend pas en charge le mode C + 11 (et ne semble donc pas garantir la disponibilité de long long). Clang ne prend pas cela en charge non plus, mais il prend en charge long long si le mode C99 est activé, après une certaine version.

La suggestion générale est-elle d'utiliser int64_t au lieu de long long, quand la portabilité est un objectif important? L'utilisation des spécificateurs de format semble pénible.

Puis-je lancer de manière fiable un int64_t à long long (et de même à l'équivalent unsigned avec uint64_t) pour l'utiliser avec les fonctions et bibliothèques existantes qui prennent long long comme paramètres? (Et encore une fois, bien sûr.)

Dans cet état d'esprit, si j'expédie du code qui nécessite une fonctionnalité Clang pas dans GCC, Clang va-t-il remplacer GCC comme compilateur de choix sous Linux? Est-ce que ce compilateur est quelque chose à quoi je peux m'attendre, pour la plupart, en offrant du code source aux utilisateurs finaux?

Fondamentalement, je voudrais demander des conseils à d'autres développeurs qui ont utilisé les deux types de code C et C++ portable, qui pourraient avoir des suggestions sur la meilleure façon de procéder à long terme, compte tenu de l'objectif ci-dessus. .

39
Alex Reynolds

Les types long long et unsigned long long sont des types C standard et C++ standard contenant chacun au moins 64 bits. Tous les compilateurs que je connais fournissent ces types, sauf éventuellement dans un -pedantic mode mais dans ce cas int64_t ou uint64_t ne sera pas non plus disponible avec les compilateurs pré-C++ 2011. Sur tous les systèmes <stdint.h> est également disponible. Autrement dit, pour autant que je sache, peu importe la façon dont vous épelez le type. L'objectif principal de <stdint.h> est de fournir la meilleure correspondance pour un nombre spécifique de bits. Si vous avez besoin d'au moins 64 bits mais que vous souhaitez également profiter de l'implémentation rapide d'un tel type, vous utiliserez int_least64_t ou uint_least64_t de <stdint.h> ou <cstdint> (dans ce dernier cas, les noms sont définis dans l'espace de noms std).

32
Dietmar Kühl

La suggestion générale est-elle d'utiliser int64_t au lieu de long long, quand la portabilité est un objectif important?

Je serais très surpris si un compilateur offrait int64_t mais non long long.

Si long long est présent, il doit avoir au moins 64 bits, donc la conversion à partir de (u)int64_t à (unsigned) long long préserve la valeur.

Si vous avez besoin d'un type avec exactement 64 bits, utilisez (u)int64_t, si vous avez besoin de au moins 64 bits, (unsigned) long long est parfaitement bien, comme le serait (u)int_least64_t.

25
Daniel Fischer