Le costanti architetturali, in linguaggio C, sono esplicitate in appositi header: in particolare limits.h e float.h. Dopo il 1999 (con la promulgazione del nuovo standard, ultimo del millennio scorso), quasi tutti i compilatori mainstream supportano anche header aggiuntivi come stdint.h e inttypes.h, come ho dettagliatamente spiegato qui.
Circolano in letteratura innumerevoli esempi in merito, e io stesso negli anni ne ho implementati al volo numerosi, in varie salse, disseminati in svariati forum. Uno degli esempi più didattici e semplificati può essere il seguente:
codice:
#include <stdio.h>
#include <limits.h>
#include <float.h>
#if defined(__ICC) || defined(__INTEL_COMPILER)
const char Compiler[] = "** Compiled with Intel C/C++"
" **";
#endif
#if defined(__TURBOC__) || defined(__BORLANDC__)
const char Compiler[] = "** Compiled with Borland C++"
" **";
#endif
#if defined(_MSC_VER)
const char Compiler[] = "** Compiled with Visual C/C++"
" **";
#endif
#if defined(__DMC__)
#include <inttypes.h>
#define _UI64_MAX ULLONG_MAX
const char Compiler[] = "** Compiled with Digital Mars"
" **";
#endif
#if defined(__WATCOMC__)
#include <inttypes.h>
const char Compiler[] = "** Compiled with Open Watcom"
" **";
#endif
#define H_SEP_STAR "************************************************************"
#define H_SEP_LINE "------------------------------------------------------------"
#if !defined(PRIu64)
#define PRIu64 "I64u"
#endif
int main(void)
{
char fmt[64];
printf("\n%s\n%s\n%s\n", H_SEP_STAR, Compiler, H_SEP_STAR);
printf("- unsigned:\n"
"char...........: [0, %u] (%d bits per char)\n",
UCHAR_MAX, CHAR_BIT);
printf("short int......: [0, %u]\n", USHRT_MAX);
printf("int............: [0, %u]\n", UINT_MAX);
printf("long int.......: [0, %lu]\n", ULONG_MAX);
#if defined(_UI64_MAX)
sprintf(fmt, "long int 64....: [0, %%%s]\n", PRIu64);
printf(fmt, _UI64_MAX);
#endif
puts(H_SEP_LINE);
printf("- signed:\n"
"char...........: [%d, %d]\n", SCHAR_MIN, SCHAR_MAX);
printf("short int......: [%d, %d]\n", SHRT_MIN, SHRT_MAX);
printf("int............: [%d, %d]\n", INT_MIN, INT_MAX);
printf("long int.......: [%ld, %ld]\n", LONG_MIN, LONG_MAX);
puts(H_SEP_LINE);
printf("float..........: [%g, %g]\n", FLT_MIN, FLT_MAX);
printf("double.........: [%g, %g]\n", DBL_MIN, DBL_MAX);
printf("long double....: [%Lg, %Lg]\n", LDBL_MIN, LDBL_MAX);
puts(H_SEP_LINE);
printf("FLT_EPSILON....: %g\n", FLT_EPSILON);
printf("DBL_EPSILON....: %g\n", DBL_EPSILON);
printf("LDBL_EPSILON...: %Lg\n", LDBL_EPSILON);
puts(H_SEP_STAR);
return 0;
}
Vale forse la pena di ricordare ai più distratti che tale esempio, specifico per Windows, non prevede la compilazione con derivati del GCC.