pisałem ten mały kod:printf z size_t zmiennej z LLD, LD i d identyfikatorów typu
#include <stdio.h>
int main() {
size_t temp;
temp = 100;
printf("lld=%lld, ld=%ld, u=%u\n", temp, temp, temp);
return 0;
}
Używam tego na i386 GNU/Linux maszynie z wersji gcc 4.1.1 20070105 (Red Hat 4.1.1-52). Jest to wyjście, które mam:
lld=429496729700, ld=100, u=7993461
mogę zrozumieć, że pierwsza (lld
) została wydrukowana jako śmieci, ponieważ printf
próbuje drukować 8 bajtów (dla signed long long
jak oznacza lld
), gdy tylko 4 bajty są dostępne od zmiennej temp
. Ale nie rozumiem, dlaczego ostatni identyfikator, u
jest drukowany jako śmieci - podczas gdy w moim rozumieniu jest to najbliższy stosowny identyfikator dla size_t
.
Tutaj założyłem, że size_t
jest unsigned int
(który jest podpisany 4 bajty dla mojego i386).
Teraz zrobiłem trochę szczypanie z linią printf
:
...
printf("ld=%ld, u=%u, lld=%lld\n", temp, temp, temp);
...
i mam perfekcyjnie odpowiedź (z wyjątkiem lld
części).
ld=100, u=100, lld=34331653576851556
Czy ktoś może mi pomóc w zrozumieniu, czego dokładnie tu brakuje?
Wielkie dzięki za pomoc!
[dygresja: Próbowałem przełączania optymalizacji przy użyciu gcc -O[0,2]
tag on/off bez jakiejkolwiek różnicy w obserwacji.]
Opcja -Wformat prawdopodobnie wykryje tę niezgodność. – Clifford
@Clifford Dzięki za wiadomość - ale celowo użyłem niewłaściwych specyfikatorów. Właściwie to chciałem wiedzieć, w jaki sposób 'printf' zużywa elementy na stosie. Właściwie myślę, że -Wall też miałby to samo. Niemniej jednak, dziękuję bardzo. – Shrey
Zdaję sobie sprawę, że to było celowe; ale moim celem było to, że jeśli intencją było obserwowanie zachowania kompilatora, opcja -Wformat demonstruje alternatywne (i bezpieczniejsze) zachowanie, które mogło być interesujące dla kogoś, nawet jeśli byłeś już tego świadomy. -Wall nie uwzględnił -Wformat na starszych wersjach GCC. – Clifford