Comprobación de los tamaños de letra en C con macros

Estoy escribiendo un programa que necesita tener tipos sin firmar con tamaños definidos. Necesito un uint8, uint16, uint32 y uint64, y los necesito definidos en types.h, de manera que siempre se definan correctamente independientemente de la plataforma.

Mi pregunta es, ¿cómo puedo verificar los tamaños de diferentes tipos en cada plataforma usando macros de preprocesador, para poder definir mis tipos personalizados correctamente en el encabezado types.h?

preguntado el 09 de enero de 11 a las 05:01

3 Respuestas

C tiene estándar typedefs para éstos. No defina el suyo. Se les llama intN_t y uintN_t dónde N es 8, 16, 32, 64, etc. Incluya <stdint.h> para conseguirlos.

Si está utilizando un compilador antiguo que carece stdint.h, simplemente puede proporcionar las suyas propias con las definiciones de tipo adecuadas para cualquier plataforma rota con la que esté trabajando. Apostaría a que en cualquier objetivo no incrustado que encuentre sin stdint.h:

  • CHAR_BIT es 8.
  • sizeof(char) es 1. <- Apostaría aún más en este ... ;-)
  • sizeof(short) es 2.
  • sizeof(int) es 4.
  • sizeof(long long), si el tipo existe, es 8.

Así que utilícelos como complementos para los sistemas rotos.

Respondido el 09 de enero de 11 a las 08:01

inttypes.h también va bien con estos tipos. Estos encabezados definitivamente están en POSIX, pero no sabía que también estaban en el estándar C. Limpio. - efímero

Si el compilador antiguo es MSVC, puede usar esto: msinttypes.googlecode.com/svn/trunk/stdint.h - Martin

Si usa los tipos de enteros estándar como complementos, también debe usar el preprocesador para verificar los rangos correctos: #if UINT_MAX != 0xFFFFFFFF␤#error "int is not 32-bit"␤#endif - Christoph

Ni siquiera puedes garantizar que todos esos tipos existe en su plataforma (digamos, puede que ni siquiera be un entero de 64 bits), por lo que no es posible escribir código independiente de la plataforma para detectarlos en tiempo de compilación.

Respondido el 09 de enero de 11 a las 08:01

Soy consciente de que el entero de 64 bits será problemático en algunas plataformas. - seisatsu

Bueno, no es solo de 64 bits, si está verdaderamente escribir código C independiente de la plataforma, todo lo que está garantizado es que sizeof(long long int) >= sizeof(long int) >= sizeof(short int)... ¡pero todos podrían, a todos los efectos prácticos, ser de 16 bits! Por lo tanto, debe asumir necesariamente algunas cosas no estándar antes de poder escribir un código como este. - user541686

No. C requiere ULONG_MAX ser al menos 2 ^ 32-1 y ULLONG_MAX ser al menos 2 ^ 64-1. - R .. GitHub DEJA DE AYUDAR A ICE

Eso es gracioso, recuerdo específicamente haber leído en mi libro C que la única garantía hecha es la que escribí. Sin embargo, parece que tienes razón; gracioso que el libro estuviera mal ... - user541686

Maldita sea, estoy usando pstdint. - seisatsu

   312 #define SDL_COMPILE_TIME_ASSERT(name, x)               \

   313        typedef int SDL_compile_time_assert_ ## name[(x) * 2 - 1]


   316 SDL_COMPILE_TIME_ASSERT(uint8, sizeof(Uint8) == 1);

   317 SDL_COMPILE_TIME_ASSERT(sint8, sizeof(Sint8) == 1);

   318 SDL_COMPILE_TIME_ASSERT(uint16, sizeof(Uint16) == 2);

   319 SDL_COMPILE_TIME_ASSERT(sint16, sizeof(Sint16) == 2);

   320 SDL_COMPILE_TIME_ASSERT(uint32, sizeof(Uint32) == 4);

   321 SDL_COMPILE_TIME_ASSERT(sint32, sizeof(Sint32) == 4);

   322 SDL_COMPILE_TIME_ASSERT(uint64, sizeof(Uint64) == 8);

   323 SDL_COMPILE_TIME_ASSERT(sint64, sizeof(Sint64) == 8);

Pagar SDL https://hg.libsdl.org/SDL/file/d470fa5477b7/include/SDL_stdinc.h#l316 afirman estáticamente el tamaño en el momento de la compilación. Como dice @Mehrdad, no puede ser independiente de la plataforma si su objetivo no tiene un entero de 64 bits.

respondido 26 nov., 19:13

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.