Czy można znaleźć rozmiary typów danych (int, float, double, ...) w systemie Linux, bez pisania programu w języku C.
Czy wyniki dla C będą takie same jak dla C ++ i innych języków programowania w tym samym systemie Linux?
Czy można znaleźć rozmiary typów danych (int, float, double, ...) w systemie Linux, bez pisania programu w języku C.
Czy wyniki dla C będą takie same jak dla C ++ i innych języków programowania w tym samym systemie Linux?
Odpowiedzi:
Jeśli znasz definicję typu danych, którego chcesz użyć, możesz getconf
znaleźć te wartości w większości systemów uniksowych.
$ getconf CHAR_BIT
8
Lista zmiennych jest zdefiniowana zarówno na stronie man, man limits.h
jak i tutaj, man sysconf
oprócz tego, że znajduje się na dysku. Można używać locate limits.h
go znaleźć, to często tutaj: /usr/include/linux/limits.h
.
getconf
było najbezpieczniejszym sposobem, pod warunkiem, że mówisz, że uderzam w „oficjalny” kompilator na pudełku.
getconf
nie jest tak bezpieczne, chyba że wywołujesz kompilator C jako c89
lub c99
z (prawie) bez opcji.
Rodzaj.
Przy przynajmniej gcc działa to:
$ cpp -dD /dev/null | grep __SIZEOF_LONG__
W każdym razie, dlaczego nie chcesz napisać programu C, aby to zrobić? Możesz wysłać mały kompilator C do swojego kompilatora z powłoki coś takiego:
binary=$(mktemp)
cat <<\EOF | cc -o $binary -x c -
#include <stdio.h>
int main() {
printf("int=%lu bytes\n", sizeof(int));
printf("long=%lu bytes\n", sizeof(long));
}
EOF
$binary
rm $binary
-x c
Informuje kompilator, język jest C
, a -
środki czytane ze standardowego wejścia.
W moim systemie powyższe wydruki:
int=4 bytes
long=8 bytes
Testowane w gcc i clang.
Tak. Możesz skanować/usr/include/<arch>/limits.h
Na przykład na moim amd64 NetBSD, /usr/include/amd64/limits.h
pokaże:
#define CHAR_BIT 8 /* number of bits in a char */
#define SCHAR_MAX 0x7f /* max value for a signed char */
#define SCHAR_MIN (-0x7f-1) /* min value for a signed char */
#define UCHAR_MAX 0xff /* max value for an unsigned char */
#define CHAR_MAX 0x7f /* max value for a char */
#define CHAR_MIN (-0x7f-1) /* min value for a char */
#define USHRT_MAX 0xffff /* max value for an unsigned short */
#define SHRT_MAX 0x7fff /* max value for a short */
#define SHRT_MIN (-0x7fff-1) /* min value for a short */
#define UINT_MAX 0xffffffffU /* max value for an unsigned int */
#define INT_MAX 0x7fffffff /* max value for an int */
#define INT_MIN (-0x7fffffff-1) /* min value for an int */
#define ULONG_MAX 0xffffffffffffffffUL /* max value for an unsigned long */
#define LONG_MAX 0x7fffffffffffffffL /* max value for a long */
#define LONG_MIN (-0x7fffffffffffffffL-1) /* min value for a long */
Jeśli masz zainstalowany Perl, możesz uzyskać to z Perla -V:
intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=8, prototype=define
No ... to jest możliwe uruchamianie plików binarnych z różnymi ideami wielkości podstawowych typów, szczególnie w przypadku 64-bitowych architektur. Najnowsze jądra Linuksa na x86_64 mogą uruchamiać natywne 32-bitowe pliki binarne, a także x32 ABI z 32-bitowymi typami.
Rozmiary typów danych są częściowo tym, czego używa kompilator. Jest jednak wyraźnie korzystne (1) używanie typów obsługiwanych przez maszynę efektywnie i (2) używanie typów konsekwentnie z bibliotek niskiego poziomu poprzez aplikacje użytkownika. Konieczność obsługi kilku wariantów to po prostu bałagan.
Spróbuj to przeanalizować i wypisać wiersze zawierające ciągi odwołujące się do typów danych:
{ shopt -s globstar; for i in /usr/include/**/*.h; do grep -HE '\b(([UL])|(UL)|())LONG|\bFLOAT|\bDOUBLE|\bINT' $i; done; }
Łapie to oczywiście definicje, /usr/include/limits.h
więc dostaniesz to plus, czasem z wartościami, ale głównie odnosząc się do tego, co jest ustawione, w limits.h
którym możesz wygodnie przeglądać za pomocą poleceń getconf -a
i ulimit -a
.