2013-01-16 10 views
13

W Windows mogę zadzwonić:Czy istnieje jakiś sposób, aby uzyskać 64-bitowego time_t w programie 32-bitowego Linuksa

_time32(__time32_t); // to get 32bit time_t 
_time64(__time64_t); // to get 64bit time_t 

(zarówno 32 jak i 64 programy bit)

Czy jest jakiś sposób, zrobić to w Linuksie (kompilując z GCC)?

+0

@Benoit To pytanie nie jest duplikatem, jest zupełnie inne. – interjay

+1

Niezupełnie ... w 32-bitowym systemie Linux, 'time_t' to tradycyjna 32-bitowa ilość podpisana, z pozostałymi 25 latami użyteczności. W 64-bitowych systemach uniksowych jest to już 64-bitowa ilość. Jeśli chcesz mieć przenośny typ, będziesz musiał zdefiniować swój własny, który odpowiednio mapuje lub po prostu ostrożnie użyjesz 'time_t'. Inne zadane pytanie zawiera istotne informacje (ale zgadzam się, że nie jest to duplikat). –

+1

zobacz także ** [64-bitowy UNIX Timestamp Conversion] (http://stackoverflow.com/questions/7914368/64-bit-unix-timestamp-conversion) ** –

Odpowiedz

10

Wygląda na to, że nie jest to możliwe. Na początek jest tylko jedna funkcja time() w systemie Linux, nie time32() lub time64().

Po chwili szukania, widzę, że to nie wina libc, ale winowajcą jest w rzeczywistości jądro.

Aby libc celu pobrania aktualny czas niezbędny dla wykonania połączenia system komputerowy: (Source)

time_t time (t) time_t *t; 
{ 
    // ... 
    INTERNAL_SYSCALL_DECL (err); 
    time_t res = INTERNAL_SYSCALL (time, err, 1, NULL); 
    // ... 
    return res; 
} 

Połączenie systemu jest zdefiniowany jako: (Source)

SYSCALL_DEFINE1(time, time_t __user *, tloc) 
{ 
    time_t i = get_seconds(); 
    // ... 
    return i; 
} 

funkcja get_seconds() zwraca unsigned long, tak jak poniżej: (Source)

unsigned long get_seconds(void) 
{ 
    struct timekeeper *tk = &timekeeper; 

    return tk->xtime_sec; 
} 

I timekeeper.xtime_sec jest rzeczywiście 64-bitowe: (Source)

struct timekeeper { 
    // ... 
    /* Current CLOCK_REALTIME time in seconds */ 
    u64      xtime_sec; 
    // ... 
} 

Teraz, jeśli znasz C, wiesz, że wielkość unsigned long jest w rzeczywistości zależna od implementacji . Na moim 64-bitowym komputerze jest to 64-bitowy; ale na moim 32-bitowym komputerze tutaj jest 32-bitowy. Może on być w wersji 64-bitowej w niektórych implementacjach 32-bitowych, ale nie ma żadnej gwarancji.

Z drugiej strony, u64 jest zawsze 64-bitowy, więc na samym poziomie jądro śledzi czas w typie 64-bitowym. Dlaczego następnie zwraca go jako unsigned long, który nie ma gwarancji, że jest 64-bitowy, jest poza mną.

W końcu, nawet jeśli libc wymusiłoby time_t zachowanie 64-bitowej wartości, nie zmieniłoby to niczego.

Możesz umieścić swoją aplikację głęboko w jądrze, ale nie sądzę, że warto.

+0

Napisz więc łatkę i opublikuj ją. Zarówno dla libc (typedef long long int time_t), jak i jądra long long int get_seconds (void) – user877329

6

Funkcja nr time64()/time32() jest dołączana do standardowych bibliotek.

Brak definicji time32_t/time64_t są uwzględniane w standardowych nagłówkach.

time_t jest zdefiniowany jako jako typedef __time_t time_t;

Po długim łańcuchu na nowo definiuje się, że __time_t jest zdefiniowany jako 32-bitowy na maszynach 32-bitowych i 64-bitowy na maszynach 64-bitowych.

0

Jeśli naprawdę tego potrzebujesz, może rzucić własną?

typedef int32_t my_time32; 
typedef int64_t my_time64; 


my_time32 get_mytime32() { 
    if (sizeof(time_t) == sizeof(my_time32)) 
     return time(NULL); 
    else { 
     /* Check for overflow etc. here... */ 
     return (my_time32)(time(NULL)); 
    } 
} 

i podobnie dla get_mytime64().

Jeśli nie dbasz o przepełnienie, prosty return time(NULL); będzie działać dla obu funkcji dzięki niejawnym konwersjom numerycznym C.

+0

Nie sądzę, że prosty czas powrotu (NULL); będzie działać dla get_mytime64() na platformach 32-bitowych - po prostu obcina. – rsaxvc

+0

@rsaxvc Tak stąd komentarz "sprawdź za przepełnienie itp. Tutaj". Generalnie masz problem z 32-bitowymi czasami – Nemo

Powiązane problemy