Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

  • Απαντ. 36
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Δημοφιλείς Ημέρες

Δημοσ.

Αν ο int είναι 16 bits, τότε 2 και 1 αντίστοιχα. Τώρα το ξεκαθάρισα. Το πρόβλημά

μου είναι πως το σκεφτόμουν με τα bytes και όχι με τα ranges. Μάθαμε και κάτι

σήμερα! Το sizeof επιστρέφει "C bytes" ή όπως ανέφερε κι ο migf1, char units.

Αυτή την απάντηση περίμενα για αυτό το έγραψα το quiz :)

 

Γιατί να επιστρέψει 2 και 1 αντίστοιχα (αν και στη πράξη αυτό θα κάνει) ? Γιατί να μην επιστρέψει 4 ?

 

Πολλές φορές βλέπουμε sizeof(int) == 2 και λέμε "άρα ο int έχει 16bits και τιμές -32768 - 32767". Στην πράξη και ειδικά σε x86 όντως ισχύει αυτό αλλά γενικά δεν είναι σωστό συμπέρασμα.

 

Όπως είδαμε μπορεί να έχουμε μεγαλύτερο char και η sizeof(int) να είναι 1 ενώ να έχει και πάλι τις παραπάνω τιμές. Κάποιος θα πει ότι μπορούμε να πάρουμε την CHAR_BIT και να υψώσουμε το 2 σε αυτή τη δύναμη δηλαδή κάτι σαν 2^(CHAR_BIT*sizeof(τύπος)) οπότε θα έχουμε 2^(16*1) και έτσι θα μπορούμε να υπολογίσουμε το range του τύπου.

 

Ούτε αυτό είναι σωστό συμπέρασμα γιατί η sizeof δεν είναι για αυτή τη δουλειά. Την sizeof την χρησιμοποιείς στην malloc και τέτοιες περιπτώσεις. Όταν θέλεις να δεις το εύρος της μεταβλητής, τότε το μόνο σίγουρο είναι τα τύπος_MIN, τύπος_MAX. Αυτό γίνεται γιατί μπορεί, όπως ανέφερε πριν ο migf1, να υπάρχουν padding bits. Δηλαδή μπορεί ο int να υποστηρίζει 16bits εύρος αλλά να υλοποιείται με 24bits και τα υπόλοιπα να είναι "άχρηστα" οπότε σε αυτή την περίπτωση να έχει sizeof(int)==3. Στην πράξη δεν είναι και τόσο σύνηθες αλλά υπάρχουν περιπτώσεις που ισχύει.

 

Με άλλα λόγια:

 

* Για την c ένα byte είναι αυτή η ποσότητα που μπορεί να αναπαραστήσει όλους τους απαραίτητους χαρακτήρες. Ως απαραίτητοι χαρακτήρες ορίζονται τα A-Z, a-z, 0-9, και οι αγκύλες, παρενθέσεις, κτλ δηλαδή σύνολο γύρω στους 90 χαρακτήρες. Αυτό είναι το ελάχιστο που πρέπει να υποστηρίζεται (δηλαδή θα μπορούσαμε να είχαμε και υλοποιήσεις chars των 7bit αν δεν υπήρχε ο περιορισμός ότι το char_bit πρέπει να είναι τουλάχιστον 8). Στην συνήθη περίπτωση που ως "basic character set" υλοποιείται το ascii έχουμε το κλασικό byte των 8bits. Αν ο compiler υλοποιεί το unicode τότε θα bytes των 32bits (και CHAR_BIT == 32).

 

* Ο char ορίζεται ως μεταβλητή ενός byte (με byte κατά τον παραπάνω ορισμό) κατά συνέπεια έχει πάντα sizeof(char) == 1

 

* Κανένα άλλο συμπέρασμα δεν μπορεί να βγει από την sizeof

 

Αυτά ως άχρηστη πληροφορία 2 ημερών :P. Ξανά δεν γράφω nitpicks γιατί πιανόμαστε με αυτά και εκτροχιάζω το νήμα :P

  • Like 3
Δημοσ. (επεξεργασμένο)

...

Δεν ξέρω κατά πόσο compliant είναι οι compilers αλλά πολλοί DSP χάριν απλότητας του hardware υλοποιούν τον char όπως και τον int. Σελίδα 122.

...

Επανέρχομαι γιατί μόλις έριξα μια ματιά στο παραπάνω λινκ που έδωσες, αλλά δεν βρήκα αυτό που έψαχνα (εντάξει, μη φανταστείς πως το ξεκοκκάλισα κιόλας).

 

Τα επιτρεπόμενα εύρη τιμών και τα sizes σε bits για char και int είναι ίδια. Άρα no padding/trap bits πουθενά. Πώς κάνει cope με το EOF αυτός ο compiler; Αν τον έχεις, μπορείς να δεις πως το ορίζει;

 

Έτσι όπως τα έχει ο πίνακας, δεν βλέπω πως μπορεί το EOF να αναπαρασταθεί ως αρνητικός int ως αποτέλεσμα cast από unsigned char χωρίς να αντιστοιχεί σε κάποια από τις υποστηριζόμενες τιμές των unsigned char (δηλαδή αυτό που έγραψα σε ένα προηγούμενο ποστ με την fgetc() ως παράδειγμα).

 

Εκτός αν δεν αποτελεί απαίτηση του προτύπου για την fgetc(), οπότε αλλάζει το πράγμα (αλλά και πάλι παραμένει η περιέργειά μου να δω πως ορίζεται το EOF σε αυτόν τον compiler, γιατί αν δεν με απατάει η μνήμη μου το πρότυπο το θέλει να είναι ένας αρνητικός int χωρίς αντιστοίχιση σε uchar... αν έχει κανείς πρόχειρο το πρότυπο κι έχει όρεξη ας ρίξει plz μια ματιά να μας πει).

 

...

Αυτά ως άχρηστη πληροφορία 2 ημερών :P. Ξανά δεν γράφω nitpicks γιατί πιανόμαστε με αυτά και εκτροχιάζω το νήμα :P

Θα ήταν πολύ βαρετό το φόρουμ χωρίς περιστασιακό nitpicking (σοβαρά το λέω) :)

Επεξ/σία από migf1
Δημοσ.

Τα επιτρεπόμενα εύρη τιμών (και τα bits) για char και int είναι ίδια. Άρα no padding/trap bits πουθενά. Πώς κάνει cope με το EOF αυτός ο compiler; Αν τον έχεις, μπορείς να δεις πως το ορίζει;

 

Έτσι όπως τα έχει ο πίνακας, δεν βλέπω πως μπορεί το EOF να αναπαρασταθεί ως αρνητικός int ως αποτέλεσμα cast από unsigned char χωρίς να αντιστοιχεί σε κάποια από τις υποστηριζόμενες τιμές των unsigned char (δηλαδή αυτό που έγραψα σε ένα προηγούμενο ποστ με την fgetc() ως παράδειγμα).

 

Εκτός αν δεν αποτελεί απαίτηση του προτύπου για την fgetc(), οπότε αλλάζει το πράγμα (αλλά και πάλι παραμένει η περιέργειά μου να δω πως ορίζεται το EOF σε αυτόν τον compiler, γιατί αν δεν με απατάει η μνήμη μου το πρότυπο το θέλει να είναι ένας αρνητικός int χωρίς αντιστοίχιση σε uchar... αν έχει κανείς πρόχειρο το πρότυπο κι έχει όρεξη ας ρίξει plz μια ματιά να μας πει).

Ο compiler που έχουμε συνηθίσει αποτελεί μία "hosted" υλοποίηση. Όπως είπε και ο defacer πριν, το πρότυπο αφήνει πάρα πολλά πράγματα στην υλοποίηση αλλά οι hosted υλοποιήσεις δεσμεύονται για ένα κάρο βασικά πράγματα. Εκτός από αυτό το είδος όμως υπάρχει και η freestanding υλοποίηση η οποία έχει ακόμη πιο λίγες δεσμεύσεις (να φανταστείς ούτε καν το stdio.h δεν είναι mandatory).

 

Πολλοί τέτοιοι επεξεργαστές είναι τόσο "ειδικού σκοπού" που πολλές υποδομές που έχουμε συνηθίσει, δεν έχουν νόημα εκεί και έτσι ο compiler τους παρέχει τα απολύτως βασικά ξεφεύγοντας σε πολλά σημεία από το κλασικό.

 

Όσον αφορά συγκεκριμένα το EOF, δεν μπορείς να είσαι σίγουρος ελέγχοντας μια μεταβλητή (είτε τύπου char ή int) αλλά πρέπει να χρησιμοποιήσεις την feof. Το EOF είναι το μικρότερό σου πρόβλημα πάντως. Το πιο σπαστικό είναι τι γίνεται με το integer promotion. Κώδικες που το εκμεταλλεύονται και παίζουν τζάμι στη κλασική περίπτωση του char < int μπορεί να έχουν πρόβλημα εδώ.

 

Θα ήταν πολύ βαρετό το φόρουμ χωρίς περιστασιακό nitpicking (σοβαρά το λέω) :)

Ε καλά ποιον κοροϊδεύω άλλωστε που δεν θα ξαναγράψω. Όταν πέφτει ένα θέμα στο τραπέζι, ακόμη και η πιο ασήμαντη λεπτομέρεια να έχει παραληφθεί, θα σκάσω αν δεν την αναφέρω. :)
Δημοσ.

Γνωρίζω τις διαφορές μεταξύ hosted & freestand implementation, αλλά το λινκ που έδωσες κάνει claim πως είναι ISO compliant με support στην stdio, εξού και η απορία μου περί EOF.

 

Υπάρχει και η stdio στο λινκ που έδωσες, αλλά π.χ. στην fgetc() αποφεύγει να μιλήσει για unsigned char που γίνεται converted σε int. Το EOF δεν το αποφεύγει, αλλά δεν το εξηγεί και πουθενά πως το κάνει implement.

 

Σωστό και το ότι πρέπει να ελέγχουμε παράλληλα feof() και ferror(), αλλά και πάλι παραμένει η απορία μου για το πως κάνει cope με το EOF ο συγκεκριμένος compiler.

Δημοσ.

Γνωρίζω τις διαφορές μεταξύ hosted & freestand implementation, αλλά το λινκ που έδωσες κάνει claim πως είναι ISO compliant με support στην stdio, εξού και η απορία μου περί EOF.

 

Υπάρχει και η stdio στο λινκ που έδωσες, αλλά π.χ. στην fgetc() αποφεύγει να μιλήσει για unsigned char που γίνεται converted σε int. Το EOF δεν το αποφεύγει, αλλά δεν το εξηγεί και πουθενά πως το κάνει implement.

 

Σωστό και το ότι πρέπει να ελέγχουμε παράλληλα feof() και ferror(), αλλά και πάλι παραμένει η απορία μου για το πως κάνει cope με το EOF ο συγκεκριμένος compiler.

Ψάχνοντας στο ti.com για λεπτομέρειες, βρήκα το wiki άρθρο C89 Support το οποίο μεταξύ πολλών άλλων αναφέρει:

 

On targets where sizeof(char)==sizeof(int) (C2700, C2800, C5400, C5500), you still can't reliably use the return value of getc() to check for end of file, because 0xffff will be mistaken for the end of file. Use feof() instead.

Αν το ερμηνεύω σωστά, δεν κάνει cope όπως είναι και το λογικό :P. Το EOF θα ορίζεται κανονικά ως -1 αλλά πρέπει να χρησιμοποιήσεις την feof όπως είπα πριν.

  • Like 1
Δημοσ.

Λύθηκε το μυστήριο :)

 

ΥΓ. Δεν υπήρχε άλλη λογική εξήγηση (απλά δεν ξέρω αν είναι compliant με το πρότυπο αυτή η προσέγγιση).

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα

  • Δημιουργία νέου...