Title: deleted Post by: BOBoMASTORAS on June 27, 2010, 23:04:27 pm deleted
Title: Re: Απροσδόκητο αποτέλεσμα προγράμματος C Post by: anonymous-root on June 27, 2010, 23:33:41 pm 0xFFFFFFFF τυπώνει.
VS 2008 SP1 1>------ Build started: Project: bobmastoras, Configuration: Debug Win32 ------ 1>Compiling... 1>bobmastoras.cpp 1>Linking... 1>Embedding manifest... 1>Build log was saved at "file://c:\Users\6\Documents\Visual Studio 2008\Projects\bobmastoras\bobmastoras\Debug\BuildLog.htm" 1>bobmastoras - 0 error(s), 0 warning(s) ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ========== Title: Re: Απροσδόκητο αποτέλεσμα προγράμματος C Post by: SolidSNK on June 27, 2010, 23:54:47 pm Χμμμ ας κάνω και 'γω μια προσπάθεια. Η "λογική" λέει 0x0. Αλλά το >> θα γεμίσει με 1 στην περίπτωση μας επειδή κρατάει το πρόσημο (http://en.wikipedia.org/wiki/Two%27s_complement) έτσι? ;)
Title: Re: Απροσδόκητο αποτέλεσμα προγράμματος C Post by: Axel on June 27, 2010, 23:56:46 pm Ο unsigned int έχει μέγεθος 32bits. Επομένως επιτρέπεται να του κάνεις shift μέχρι 31 θέσεις. Αν του πεις θέλω 32 shift το αποτέλεσμα θα είναι απλώς ότι του κάτσει.
Ο compiler έτσι όπως είναι γραμμένο δεν θα βγάλει error. Αν όμως γράψεις unsigned int integer=value>>32; θα σου πει πως δεν επιτρέπεται τόσο μεγάλο shift. Title: Re: Απροσδόκητο αποτέλεσμα προγράμματος C Post by: SolidSNK on June 28, 2010, 00:05:27 am Ο unsigned int έχει μέγεθος 32bits. Επομένως επιτρέπεται να του κάνεις shift μέχρι 31 θέσεις. Αν του πεις θέλω 32 shift το αποτέλεσμα θα είναι απλώς ότι του κάτσει. Α εγώ νόμισα ότι κάπως μπερδεύτηκε ο compiler και νόμισε πως ήταν signed η τιμή. Μάλλον όχι :???:Ο compiler έτσι όπως είναι γραμμένο δεν θα βγάλει error. Αν όμως γράψεις unsigned int integer=value>>32; θα σου πει πως δεν επιτρέπεται τόσο μεγάλο shift. Title: deleted Post by: BOBoMASTORAS on June 28, 2010, 00:09:40 am deleted
Title: deleted Post by: BOBoMASTORAS on June 28, 2010, 00:13:25 am deleted
Title: deleted Post by: BOBoMASTORAS on June 28, 2010, 00:25:21 am deleted
Title: Re: Απροσδόκητο αποτέλεσμα προγράμματος C Post by: SolidSNK on June 28, 2010, 00:28:16 am Ναι ρε συ αυτό έλεγα εγώ αλλά δεν ισχύει εδώ, ως unsigned βλέπει ο compiler τον operator. Αν είχες signed, τότε το 0xffffffff θα το γέμιζε με `1` ανεξάρτητα το πόσο right shift θα έκανε. Άρα στο %x της printf θα έβγαζε συνέχεια 0xffffffff.
Title: deleted Post by: BOBoMASTORAS on June 28, 2010, 00:55:21 am deleted
Title: Re: Απροσδόκητο αποτέλεσμα προγράμματος C Post by: Issle on January 07, 2012, 12:58:00 pm Dig up. Βρήκα και εγώ ένα περίεργο ( όχι τόσο , δεν είναι απροσδόκητο ) αλλά με παίδεψε πολύ μέχρι να καταλάβω τι παίζει.
(C++, συντακτικά λάθη και ξεχασμένα include --> ignore.) Quote class XMLParser { public: XMLParser() { read(); } virtual void readImpl() = 0; void read() { //bla bla readImpl(); } }; class MyParser: public XMLParser() { public: MyParser(): XMLParser() { } void readImpl() { cout <<" Hi from MyParser" << endl; } }; int main() { MyParser* parser = new MyParser(); return 0; } Τι τυπώνει και γιατί ? Title: deleted Post by: BOBoMASTORAS on January 07, 2012, 15:57:20 pm deleted
Title: Re: Απροσδόκητο αποτέλεσμα προγράμματος C Post by: Issle on January 07, 2012, 17:19:35 pm Περίπου σωστό. Δεν θα τυπώσει το cout αλλά για άλλο λόγο. Το παραπάνω ιδίωμα είναι η Pattern Template Method και κανονικά έπρεπε να κληθεί η impl(); π.χ. τρέξε αυτό:
Quote #include <iostream> using namespace std; class A { public: virtual void callImpl() = 0; void call() { callImpl(); } }; class B: public A { public: void callImpl() { cout << "Hi from B" << endl; } }; int main() { A* a = new B(); a->call(); } Εδώ θα δείς οτι καλεί την impl της Β αντί της abstract. More here: http://sourcemaking.com/design_patterns/template_method/cpp/1 Παρά το παραπάνω , ο κώδικας στο πρώτο post δεν θα τυπώσει το αναμενόμενο ... :) Title: deleted Post by: BOBoMASTORAS on January 07, 2012, 17:39:16 pm deleted
Title: Re: Απροσδόκητο αποτέλεσμα προγράμματος C Post by: Issle on January 07, 2012, 17:43:08 pm Περίπου σωστό. Δεν θα τυπώσει το cout αλλά για άλλο λόγο. Το παραπάνω ιδίωμα είναι η Pattern Template Method και κανονικά έπρεπε να κληθεί η impl(); π.χ. τρέξε αυτό: Αυτό είναι εντελώς διαφορετικό.... Ουσιαστικά επειδή η Α είναι abstract κλάση ο Α* που έχεις δείχνει στο αντικείμενο τύπου Β και καλείς αντικείμενα-υλοποιήσεις τύπου Β. Αντίθετα στην άλλη περίπτωση το καλείς από τον constructor. ΔΕΝ υπάρχει ακόμη το αντικείμενο Β αφού δεν έχει ολοκληρωθεί η κλήση του constuctor του. Άρα καλείς την readImpl στο scope του Α στο οποίο η readImpl είναι pure virtual και δε μπορεί να κληθεί. Yap :) Γιατί δεν περίμενες κανέναν άλλον ? ;) Ουσιαστικά το verdict είναι ότι δεν καλείς template method μέσα στον constructor της base class γιατί δεν έχει δημιουργηθεί ακόμη το αντικείμενο που υλοποιεί την pure virtual. Στη C++, γιατί στην java : Quote public class MainClass { public abstract static class A { public A() { run(); } public void run() { runImpl(); } public abstract void runImpl(); } public static class B extends A { public B() { super(); } @Override public void runImpl() { System.out.println("Hi from B"); } } public static void main(String[] args) { A a = new B(); } } Έχοντας συνηθήσει από την java όπου κάτι τέτοιο,είναι απολύτως φυσιολογικό, μου φάνηκε αρκετά στρυφνό να το χωνέψω στη C++ :) Και για να τρολλάρουμε και λίγο : Who's got a better inheritence model ? ;) Title: deleted Post by: BOBoMASTORAS on January 07, 2012, 17:50:50 pm deleted
Title: Re: Απροσδόκητο αποτέλεσμα προγράμματος C Post by: Issle on January 07, 2012, 18:25:55 pm Χμμ, δεν βλέπω κάτι περίεργο ( πέραν του delete αντί για delete[] στα int* / float* ) και δεν έχει compile-time / run-time errors. :( Κανονικά επιστρέφει το float όπως θα πρεπε ...
Επίσης δεν καλείτε ο destructor της extended ( o destructor της base πρέπει να γίνει virtual ). Title: deleted Post by: BOBoMASTORAS on January 07, 2012, 18:28:48 pm deleted
Title: Re: Απροσδόκητο αποτέλεσμα προγράμματος C Post by: Issle on January 07, 2012, 18:43:20 pm χμμ, στο debugger:
Base *base=new Derived; ---> Derived Constructor --> Base Constructor std::cout<<(*base)[3]<<std::endl; --> overloaded operator [] της Derived. Title: deleted Post by: BOBoMASTORAS on January 07, 2012, 18:57:07 pm deleted
Title: Re: Απροσδόκητο αποτέλεσμα προγράμματος C Post by: Issle on January 07, 2012, 19:03:45 pm Χωρίς virtual destructor στην base θα κληθεί ο destructor του type του pointer και όχι του type του αντικειμένου στο οποίο γίνεται point. Δηλαδή θα κληθεί ο ~Base() και δεν θα ελευθερωθεί η μνήμη που δεσμεύτηκε από το new στην Derived, οπότε έχεις Memory Leak. Αυτό εννοείς ?
Title: deleted Post by: BOBoMASTORAS on January 07, 2012, 19:10:31 pm deleted
Title: Re: Απροσδόκητο αποτέλεσμα προγράμματος C Post by: Issle on January 07, 2012, 19:25:09 pm Νομίζω ότι όταν κάνεις Compile με highest warning level στον gcc, το πετάει σαν warning : Class blabla has a virtual method foo but a non-virtual destructor.
Title: deleted Post by: BOBoMASTORAS on January 07, 2012, 19:30:05 pm deleted
Title: Re: Απροσδόκητο αποτέλεσμα προγράμματος C Post by: Issle on January 07, 2012, 19:50:01 pm std::cout<<10[a]<<std::endl;
:???: ? Πρώτη φορά το βλέπω αυτό ... Title: deleted Post by: BOBoMASTORAS on January 07, 2012, 19:52:17 pm deleted
Title: Re: Απροσδόκητο αποτέλεσμα προγράμματος C Post by: Issle on January 07, 2012, 20:07:30 pm I cheated :
By definition, the expression a\[b\] is equivalent to the expression *((a) + (b)), and, because addition is associative, it is also equivalent to b[a]. :D Thank you IBM. Title: Re: Απροσδόκητο αποτέλεσμα προγράμματος C Post by: Issle on January 07, 2012, 20:11:47 pm Και κάτι τελευταίο, που με έκανε εντύπωση όταν το διάβασα. Δεν τρέχει κάποιο πρόβλημα αλλά ο παρακάτω κώδικας τα σπάει :
Quote template<class T> class MemoryPool { private: /** * The chunk of memory that is allocated * whenever the pool gets full. Optimal * solution would need increment and decrement * of the size according to the rate at which * the application requests or releases resources. */ static const int BLOCK_SIZE = 1000; /* * Points to the head of the free objects block. */ static T* headOfFreeList; /* * Specifies the next object in the block. */ T* next; static MutexLock* lock; public: /* * Acquires a preallocated space from the memory pool. */ static void* operator new(size_t size) { if(lock == 0) lock = new MutexLock(); lock->lock(); if (size != sizeof(T)) return ::operator new(size); T* p = headOfFreeList; if (p) { headOfFreeList = p->next; } else { T* newBlock = static_cast<T*>(::operator new( BLOCK_SIZE * sizeof(T))); for (int i = 0; i < BLOCK_SIZE - 1; ++i) { newBlock[\i].next = &newBlock[i + 1]; } newBlock[ BLOCK_SIZE ].next = 0; p = newBlock; headOfFreeList = &newBlock[1]; } lock->unlock(); return p; } /* * Releases a space to the preallocated memory pool. */ static void operator delete(void *deadObject, size_t size) { lock->lock(); if (deadObject == 0) return; if (size != sizeof(T)) { ::operator delete(deadObject); return; } T* carcass = static_cast<T*>(deadObject); carcass->next = headOfFreeList; headOfFreeList = carcass; lock->unlock(); } }; template< class T > MutexLock* MemoryPool<T>::lock = 0; template< class T > T* MemoryPool<T>::headOfFreeList = 0; class AnyCoolClass: public MemoryPool<AnyCoolClass> { ... } Title: deleted Post by: BOBoMASTORAS on January 07, 2012, 20:31:15 pm deleted
|