Yanıtlar:
Time_t Wikipedia makalesi makale bu konuda bazı ışık tutuyor. Sonuç time_tolarak, C spesifikasyonunda tipinin garanti edilmemesi.
time_tVeri türü sistem zamanı değerleri depolamak için tanımlandığı ISO C kütüphanesinde bir veri türüdür. Bu değerler standarttime()kütüphane işlevinden döndürülür . Bu tür, standart üstbilgide tanımlanan bir typedef'tir. ISO C, time_t öğesini aritmetik bir tür olarak tanımlar, ancak bunun için belirli bir tür , aralık, çözünürlük veya kodlama belirtmez. Ayrıca zaman değerlerine uygulanan aritmetik işlemlerin anlamları da belirtilmemiş.Unix ve POSIX uyumlu sistemler,
time_ttürüsigned integer, Unix döneminin başlamasından bu yana geçen saniye sayısını temsil eden (genellikle 32 veya 64 bit genişliğinde) olarak uygular : 1 Ocak 1970 gece yarısı UTC (artık saniye saymaz). Bazı sistemler negatif zaman değerlerini doğru işlerken, diğerleri yapmaz. 32 bittime_ttürü kullanan sistemler , 2038 Yılı sorununa duyarlıdır .
time_tdisk üzerinde veri yapısında kullanılabilir. Ancak, dosya sistemleri genellikle diğer işletim sistemleri tarafından okunduğundan, dosya sistemini bu tür uygulamaya bağlı türlere göre tanımlamak saçma olur. Örneğin, aynı dosya sistemi hem 32 bit hem de 64 bit sistemlerde kullanılabilir ve time_tboyutu değişebilir. Bu nedenle, dosya sistemlerinin tam olarak tanımlanması gerekir ("1970 bitinin başlangıcından bu yana UTC sayısını saniye cinsinden veren 32 bit işaretli tam sayı") time_t.
time.hiçerik listesine yönlendirilmektedir . Bu makale cppreference.com sitesine bağlantı veriyor, ancak belirtilen içerik hiçbir yerde bulunamadı…
time_timzalanmış olduğunu garanti ettiği iddia yanlıştır. pubs.opengroup.org/onlinepubs/9699919799/basedefs/… , çeşitli şeylerin "işaretli tam sayı türü" veya "işaretsiz tam sayı türü" olması gerektiğini belirtir, ancak time_tyalnızca "tamsayı türü" olacağını belirtir . Bir uygulama time_timzasız olabilir ve yine de POSIX uyumlu olabilir.
[root]# cat time.c
#include <time.h>
int main(int argc, char** argv)
{
time_t test;
return 0;
}
[root]# gcc -E time.c | grep __time_t
typedef long int __time_t;
Şununla tanımlanır $INCDIR/bits/types.h:
# 131 "/usr/include/bits/types.h" 3 4
# 1 "/usr/include/bits/typesizes.h" 1 3 4
# 132 "/usr/include/bits/types.h" 2 3 4
typedef __int32_t __time_t;ve typedef __time_t time_t;bir de FreeBSD freebsd-test 8.2-RELEASE-p2 FreeBSD 8.2-RELEASE-p2 #8: Sun Aug 7 18:23:48 UTC 2011 root@freebsd-test:/usr/obj/usr/src/sys/MYXEN i386. Sonuçlarınız açıkça Linux'ta bu şekilde ayarlanmıştır (en azından Debian'dan 2.6.32-5-xen-amd64 üzerinde).
__time_tve değil ? Bir adımı atlıyor musunuz? time_ttime_t
typedef __time_t time_t;, yalnızca koşullu bir derlemenin bir parçası değil, typedef'in gerçekten kullanıldığından emin olmak için çevre kodunun incelenmesi de endişemi hatırlıyorum . typedef long time_t;olabilir de.
Standartlar
William Brendel Wikipedia'dan alıntı yaptı, ama atın ağzından tercih ederim.
C99 N1256 standart taslak 7.23.1 / 3 "Zamanın bileşenleri" diyor:
Bildirilen türler, zamanları temsil edebilen aritmetik türler olan size_t (7.17'de açıklanmıştır) clock_t ve time_t şeklindedir.
ve 6.2.5 / 18 "Türler" diyor:
Tam sayı ve kayan türlere toplu olarak aritmetik türler denir.
POSIX 7 sys_types.h diyor ki:
[CX] time_t bir tamsayı türü olmalıdır.
burada [CX]şu şekilde tanımlanır :
[CX] ISO C standardına genişletildi.
Bu bir uzantıdır çünkü daha güçlü bir garanti verir: kayan noktalar dışarıda.
gcc tek astarlı
Quassnoi tarafından belirtildiği gibi bir dosya oluşturmaya gerek yok :
echo | gcc -E -xc -include 'time.h' - | grep time_t
Ubuntu 15.10 GCC 5.2'de ilk iki satır:
typedef long int __time_t;
typedef __time_t time_t;
Bazı alıntılarla komut dökümü man gcc:
-E: "Önişleme aşamasından sonra durun; derleyiciyi düzgün çalıştırmayın."-xc: Girdi dosya uzantısı olmayan stdin'den geldiğinden, C dilini belirtin.-include file: "Dosyayı birincil kaynak dosyasının ilk satırı olarak" #include "file" "gibi görünüyor."-: stdin'den girdigcc -E -xc -include time.h /dev/null | grep time_t
Cevap kesinlikle uygulamaya özeldir. Platformunuz / derleyiciniz için kesin olarak öğrenmek için, bu çıktıyı kodunuzda bir yere eklemeniz yeterlidir:
printf ("sizeof time_t is: %d\n", sizeof(time_t));
Cevap 4 (32 bit) ise ve verileriniz 2038'in ötesine geçecekse , kodunuzu taşımak için 25 yılınız vardır.
Aşağıdaki gibi basit bir şey olsa bile verilerinizi dize olarak saklarsanız verileriniz iyi olur:
FILE *stream = [stream file pointer that you've opened correctly];
fprintf (stream, "%d\n", (int)time_t);
Sonra aynı şekilde tekrar okuyun (int, fscanf, vb. İnt) ve dönem ofset zamanınız var. Benzer bir çözüm .Net. 64-bit dönem sayılarını Win ve Linux sistemleri arasında sorunsuz bir şekilde iletiyorum (bir iletişim kanalı üzerinden). Bu, bayt sıralaması sorunlarını gündeme getiriyor, ancak bu başka bir konu.
Paxdiablo'nun sorgusunu cevaplamak için, programın bu şekilde yazıldığı için "19100" yazdığını söyleyebilirim (ve bunu 80'lerde kendim yaptığımı itiraf ediyorum):
time_t now;
struct tm local_date_time;
now = time(NULL);
// convert, then copy internal object to our object
memcpy (&local_date_time, localtime(&now), sizeof(local_date_time));
printf ("Year is: 19%02d\n", local_date_time.tm_year);
printf"1900 yılından bu yana yıllar" ile sıfır dolgulu dize izledi (tanımı: deyim sabit dize "19 Yıl ise" yazdırır tm->tm_year). 2000 yılında bu değer 100'dür. "%02d"iki sıfırla doldurur, ancak iki basamaktan uzunsa kesilmez.
Doğru yol (yalnızca son satıra geç):
printf ("Year is: %d\n", local_date_time.tm_year + 1900);
Yeni soru: Bu düşüncenin mantığı nedir?
%zu, biçimlendiriciyi size_tdeğerleri ( biçimlendirildiği gibi sizeof) biçimlendirmek için, işaretsiz ( u) ve uzunluk_t ( z) · uzunluğunda olduğu için kullanmalısınız
printf ("sizeof time_t is: %d\n", (int) sizeof(time_t));da zsorunu kullanın ve önleyin .
Visual Studio 2008 altında, __int64siz tanımlamadığınız sürece varsayılan olarak bir _USE_32BIT_TIME_T. Platformdan platforma değişebileceği (ve değişeceği) için ne olarak tanımlandığını bilmiyormuş gibi davranmanız daha iyi olur.
time_tlong int64 bit makinelerde tip , aksi halde long long int.
Bunu aşağıdaki başlık dosyalarında doğrulayabilirsiniz:
time.h: /usr/include
types.hve typesizes.h:/usr/include/x86_64-linux-gnu/bits
(Aşağıdaki ifadeler birbiri ardına değildir. Ctrl + f araması kullanılarak ilgili başlık dosyasında bulunabilirler.)
1) 'de time.h
typedef __time_t time_t;
2) 'de types.h
# define __STD_TYPE typedef
__STD_TYPE __TIME_T_TYPE __time_t;
3) 'de typesizes.h
#define __TIME_T_TYPE __SYSCALL_SLONG_TYPE
#if defined __x86_64__ && defined __ILP32__
# define __SYSCALL_SLONG_TYPE __SQUAD_TYPE
#else
# define __SYSCALL_SLONG_TYPE __SLONGWORD_TYPE
#endif
4) Yine types.h
#define __SLONGWORD_TYPE long int
#if __WORDSIZE == 32
# define __SQUAD_TYPE __quad_t
#elif __WORDSIZE == 64
# define __SQUAD_TYPE long int
#if __WORDSIZE == 64
typedef long int __quad_t;
#else
__extension__ typedef long long int __quad_t;
long intyerde değil . Bkz. Stackoverflow.com/questions/384502/…
Çoğu eski platformda 32 bit imzalı bir tamsayı türüdür. Ancak, bu kod 2038 yıl hata muzdarip neden olur . Bu yüzden modern C kütüphaneleri, bunun yerine 64 milyar int imzalı bir 64 bit int olarak tanımlanmalıdır.
Genellikle gcc için uygulamaya özel bu typedef'leri bitsveya asmheader dizininde bulabilirsiniz. Benim için öyle /usr/include/x86_64-linux-gnu/bits/types.h.
Hangi üstbilgiyi görmek için sadece Quassnoi tarafından önerilen gibi bir önişlemci çağrısı kullanabilir veya kullanabilirsiniz .
Sonuçta bir time_t typedef nedir?
Sağlam kod, türün ne olduğunu umursamıyor.
C türleri gibi gerçektime_t bir tür olmak vb. double, long long, int64_t, int
Hatta unsignedhata olmadığını gösteren birçok zaman fonksiyonunun dönüş değerleri gibi olabilir -1, ama (time_t)(-1)- Bu uygulama seçimi nadirdir.
Mesele şu ki, "bilinmesi gerekenler" türü nadirdir. İhtiyaçtan kaçınmak için kod yazılmalıdır.
Ancak, kod ham yazdırmak istediğinde yaygın bir "bilinmesi gerek" oluşur time_t. En geniş tamsayı türüne döküm, en modern vakaları barındırır.
time_t now = 0;
time(&now);
printf("%jd", (intmax_t) now);
// or
printf("%lld", (long long) now);
Bir doubleveya 'ya yayınlamak da long doubleişe yarar , ancak hatalı ondalık çıktı sağlayabilir
printf("%.16e", (double) now);
double difftime(time_t time1, time_t time0) muntazam bir çıkarma yaklaşımı sağlar.
time_ttüm derleyicilerin ve işletim sistemlerinin anladığı sadece typedef8 bayt ( long long/__int64) içindir. Eskiden, sadece long int(4 bayt) içindi ama şimdi değil. Eğer bakarsanız time_tiçinde crtdefs.hsize iki uygulamaları bulacaksınız ama OS kullanacak long long.
long int.