Uploaded image for project: 'ROOT'
  1. ROOT
  2. ROOT-8367

type conversion failure in TBufferFile::ReadObjectAny

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • Critical
    • 6.26/00
    • 6.06/06
    • I/O
    • None
    • lxplus

    Description

      hi -

      The following short program attempts to demonstrate schema evolution using
      ReadObjectAny. It saves a vector<int> to a TBufferFile using WriteObjectAny
      and then tries to read it back as a vector<float> using ReadObjectAny:

      #include "TBufferFile.h"
      #include "TClass.h"
      #include <vector>
      #include <iostream>
       
      int main()
      {
        std::vector<int> v;
        for (int i=0; i<10; i++)
          v.push_back(i);
       
        TClass* cl1 = TClass::GetClass ("vector<int>");
        TClass* cl2 = TClass::GetClass ("vector<float>");
       
        TBufferFile *m_buff = new TBufferFile(TBuffer::kWrite);
        m_buff->WriteObjectAny (&v, cl1);
        m_buff->SetReadMode();
        m_buff->Reset();
        void* obj = m_buff->ReadObjectAny (cl2);
        std::vector<float>* v2 = reinterpret_cast<std::vector<float>*> (obj);
        for (float x : *v2)
          std::cout << x << " ";
        std::cout << "\n";
        
        return 0;
      }

      However, what i get when i run it is this
      (tested against /afs/cern.ch/sw/lcg/releases/LCG_85a/ROOT/6.06.06/x86_64-slc6-gcc49-dbg):

      Info in <TBufferFile::ReadObjectAny>: Using Converter StreamerInfo from vector<int> to vector<float>
      0 1.4013e-45 2.8026e-45 4.2039e-45 5.60519e-45 7.00649e-45 8.40779e-45 9.80909e-45 1.12104e-44 1.26117e-44 

      So, despite root claiming to be running a conversion, it actually does not.

      If one looks in ReadObjectAny, there is some code dealing with conversions,
      but the actual streamer call is

         TClass *clOnfile = 0;
         ...
            clRef->Streamer( obj, *this, clOnfile );

      where there are no other assignments to clOnfile. So the fact that there
      is a conversion does not get passed to the streamer.

      If i make this change:

      iff --git a/io/io/src/TBufferFile.cxx b/io/io/src/TBufferFile.cxx
      index fce860b..67b0caf 100644
      --- a/io/io/src/TBufferFile.cxx
      +++ b/io/io/src/TBufferFile.cxx
      @@ -2405,8 +2405,9 @@ void *TBufferFile::ReadObjectAny(const TClass *clCast)
                   return 0; // We better return at this point
                }
                baseOffset = 0; // For now we do not support requesting from a class that is the base of one of the class for which there is transformation to ....
      -
      -         Info("ReadObjectAny","Using Converter StreamerInfo from %s to %s",clRef->GetName(),clCast->GetName());
      +         
      +         //Info("ReadObjectAny","Using Converter StreamerInfo from %s to %s",clRef->GetName(),clCast->GetName());
      +         clOnfile = clRef;
                clRef = const_cast<TClass*>(clCast);
       
             }

      then this example works.
      (It also seems excessive to generate an Info message each time there is
      a conversion, so i commented that out.)

      Attachments

        Activity

          People

            pcanal Philippe Canal
            ssnyder Scott Snyder
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: