THMMY.gr

Ηλεκτρονικοί Υπολογιστές και Τεχνικά Θέματα => C / C++ / C# => Topic started by: BOBoMASTORAS on June 27, 2010, 23:04:27 pm



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 έτσι όπως είναι γραμμένο δεν θα βγάλει error. Αν όμως γράψεις unsigned int integer=value>>32; θα σου πει πως δεν επιτρέπεται τόσο μεγάλο shift.
Α εγώ νόμισα ότι κάπως μπερδεύτηκε ο compiler και νόμισε πως ήταν signed η τιμή. Μάλλον όχι  :???:


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