Jestem ciekawy - jeśli nie zamierzasz pisać programu w C, jaką to ma różnicę, jeśli typy danych C mają jeden rozmiar, a nie inny?
David Cary
7
@DavidCary Do wywoływania ABI z języka innego niż C!
Kaz
Odpowiedzi:
18
Jeśli znasz definicję typu danych, którego chcesz użyć, możesz getconfznaleźć 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.hjak i tutaj, man sysconfoprócz tego, że znajduje się na dysku. Można używać locate limits.hgo znaleźć, to często tutaj: /usr/include/linux/limits.h.
Z zastrzeżeniem, że dotyczy to tylko oficjalnego kompilatora C platformy. Mogą istnieć alternatywne kompilatory lub alternatywne konfiguracje (zazwyczaj za pomocą opcji wiersza poleceń) oficjalnego kompilatora, które prowadzą do różnych rozmiarów.
Gilles „SO- przestań być zły”
@Gilles - czy kiedykolwiek widziałeś sposób, aby faktycznie wymienić te zmienne? Szukałem i nie mogę przez całe życie znaleźć narzędzia, które mogłoby to zrobić. Wygląda na to, że będzie. Miałem też wrażenie, że przejście przez te wartości getconfbyło najbezpieczniejszym sposobem, pod warunkiem, że mówisz, że uderzam w „oficjalny” kompilator na pudełku.
slm
3
Niezawodny sposób - i sposób, w jaki ludzie korzystają, kiedy im zależy, czyli zasadniczo, gdy chcą skompilować program w języku C - to skompilować mały program w języku C. Zobacz, jak działa autoconf. getconfnie jest tak bezpieczne, chyba że wywołujesz kompilator C jako c89lub c99z (prawie) bez opcji.
Gilles „SO- przestań być zły”
11
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 cInformuje kompilator, język jest C, a -środki czytane ze standardowego wejścia.
Na przykład na moim amd64 NetBSD, /usr/include/amd64/limits.hpokaż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 */
To często działa, ale czasami różne kompilatory lub ustawienia kompilatora prowadzą do różnych rozmiarów.
Gilles „SO- przestań być zły”
Kiedy patrzę na limit.h w Ubuntu, wskazuje na zmienne takie jak -SHRT_MAX-, których wartość jest uzyskiwana przez preprocesor C. Gdzie mogę to znaleźć?
Pan Doomsbuster,
8
Jeśli masz zainstalowany Perl, możesz uzyskać to z Perla -V:
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.
Rozmiary typów danych są własnością kompilatora (lub ABI), a nie systemu. Możesz mieć wiele kompilatorów używających różnych rozmiarów dla typów danych w tym samym systemie.
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.hwięc dostaniesz to plus, czasem z wartościami, ale głównie odnosząc się do tego, co jest ustawione, w limits.hktórym możesz wygodnie przeglądać za pomocą poleceń getconf -ai ulimit -a.
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.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
.źródło
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 jakoc89
lubc99
z (prawie) bez opcji.Rodzaj.
Przy przynajmniej gcc działa to:
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:
-x c
Informuje kompilator, język jestC
, a-
środki czytane ze standardowego wejścia.W moim systemie powyższe wydruki:
Testowane w gcc i clang.
źródło
Tak. Możesz skanować
/usr/include/<arch>/limits.h
Na przykład na moim amd64 NetBSD,
/usr/include/amd64/limits.h
pokaże:źródło
Jeśli masz zainstalowany Perl, możesz uzyskać to z Perla -V:
źródło
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.
źródło
Rozmiary typów danych są własnością kompilatora (lub ABI), a nie systemu. Możesz mieć wiele kompilatorów używających różnych rozmiarów dla typów danych w tym samym systemie.
źródło
Spróbuj to przeanalizować i wypisać wiersze zawierające ciągi odwołujące się do typów danych:
Ł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, wlimits.h
którym możesz wygodnie przeglądać za pomocą poleceńgetconf -a
iulimit -a
.źródło