Thread: Wierd POD type error

  1. #1
    Registered User
    Join Date
    Aug 2003
    Posts
    12

    Wierd POD type error

    ../Source/Game/Fleet.cpp: In member function `const bool Fleet::Save(FILE*)':
    ../Source/Game/Fleet.cpp:82: warning: cannot pass objects of non-POD type `
    const struct std::string' through `...'; call will abort at runtime

    I have no clue what a POD type struct is or a `...' call.
    I'm asumming the ... call is the %-substitution in printf()
    I might be wrong..

    Code:
    const bool Fleet::Save( FILE *fd )
    {
            fprintf( fd ,
                                    "\n[%s-Fleet_%s]\n"
                          "posx = %f\n"
                                    "posy = %f\n"
                                    "origin = %s\n"
                          "destx = %f\n"
                                    "desty = %f\n"
            , species.c_str() , name.c_str() , position.x , position.y , origin.c_str() , dest.x , dest.y );
            if( !destination.empty() )
                    fprintf( fd , "destination = %s\n" , destination.c_str() );
    
            int     i = 0;
            for( vector<Vessel *>::iterator it = begin() ; it != end() ; ++it )
                    for( int j = 0 ; j < (*it)->GetCount() ; j++ )
                            fprintf( fd , "%d = %s\n" , i++ , (*it)->vesselClass ); //LINE 82 with the error
    
            return true;
    }
    Any clue what's happining?
    I can provide any part of the code..and if you want you can get it from sourceforge.. Borqueror is GPLed (I'm porting it back to Linux, even though it's supposed to work)

    Thanks

  2. #2
    Registered User
    Join Date
    Aug 2003
    Posts
    12
    Thank you

    That worked
    Could you tell me why though?
    I hate leeching, and want to understand what actually happened there

    Thanks

  3. #3
    Registered User
    Join Date
    May 2002
    Posts
    66
    The printf and friends (like fprintf, scanf, sprintf and others) use the elipsis operator to pass parameters. This means that things are parsed using vargs macros (or however the compiler has it implemented).

    Function declaration is something like
    Code:
    fprintf(FILE *fp, char *format, ...) { /* important stuff */ }
    This way it can read the format string and depending on content, read more from the stack. This, IMHO, is horrible and very error prone.

    You can accidently do this:
    printf("%s%s%s%s", foo) and then function will try to read 4 pointers on the stack and without safety check can easily behave in a very bad way causing all sorts of maladies.

    This is useful when you do not know how many parameters are being passed to a function. It expects simply types and passing it a class (std::string in this case) gets it confusied when it was looking for a pointer to convert to char* in this case.

    This is mixing old C and C++ and, depending which language diety you follow, can be considered very bad form.

    However if taking care and calling the correct conversion functions like .c_str() in case of std::string, you can use old-school C functions with C++ classes.

    Ideally you should open an ofstream and pipe things out using << operator. But that is just a suggestion.

  4. #4
    Registered User
    Join Date
    Aug 2003
    Posts
    12
    Hmm.. that makes sens.. But I'm stuck with the same error in a different part of the code.
    ofstream doesn't exist in Linux I beleive

    Code:
    #include "stdafx.h"
    
    #include "include.h"
    #include "extreal.h"
    #include "newran.h"
    
    #ifdef use_namespace
    using namespace NEWRAN;
    #endif
    using namespace std;
    
    #define al_trace printf
    
    void Histogram(Random* rx, int n)          // draw histogram with n obsv
    {
       int i,j; int count[20];
       Real* a = new Real[n];
       for (i = 0; i < n; i++) a[i] = rx->Next();
       Real amax = a[0]; Real amin = a[0]; Real mean = a[0]; Real sd = 0;
       for (i = 1; i < n; i++)
       {
          if (amin > a[i]) amin = a[i]; else if (amax < a[i]) amax = a[i];
          mean += a[i];
       }
       mean /= n;
       for (i = 0; i < 20; i++) count[i]=0;
       for (i = 0; i < n; i++)
       {
         Real rat= (amax != amin) ? (a[i] - amin)/(amax - amin) : 1.0;
         j = (int)( 19.999 * rat ); count[j]++;
         Real diff = a[i] - mean; sd += diff*diff;
       }
       sd = sqrt(sd/(n-1));
       j = 0;
       for (i = 0; i < 20; i++) { if (j < count[i]) j = count[i]; }
       if (j > 70) { for (i = 0; i < 20; i++) count[i] = (int)((70L*count[i])/j); }
    
       al_trace( "\n" );
       for (i = 0; i < 20; i++)
            {
                    al_trace( "\n|" );
                    for (j = 1; j < count[i]; j = j+1)
                            al_trace( "*" );
            }
       al_trace( "\n%s\np. mean = %9f, p. var = %9f\ns. mean = %9f, s. var = %9f\n" ,
                    rx->Name() , rx->Mean() , rx->Variance() , mean , sd * sd ); //LINE 50
    
       delete a;
    }
    
    void Hist(Random* rx, int n , const int cnt )          // draw histogram with n obsv
    {
       int i,j; int *count = new int[cnt];
       Real* a = new Real[n];
       for (i = 0; i < n; i++) a[i] = rx->Next();
       Real amax = a[0]; Real amin = a[0]; Real mean = a[0]; Real sd = 0;
       for (i = 1; i < n; i++)
       {
          if (amin > a[i]) amin = a[i]; else if (amax < a[i]) amax = a[i];
          mean += a[i];
       }
       mean /= n;
       for (i = 0; i < cnt ;  i++) count[i]=0;
       for (i = 0; i < n; i++)
       {
         Real rat= (amax != amin) ? (a[i] - amin)/(amax - amin) : 1.0;
         j = (int)( (cnt - 0.001) * rat ); count[j]++;
         Real diff = a[i] - mean; sd += diff*diff;
       }
       sd = sqrt(sd/(n-1));
       j = 0;
       for (i = 0; i < cnt; i++) { if (j < count[i]) j = count[i]; }
       if (j > 70) { for (i = 0; i < cnt; i++) if( count[i] )       count[i] = (int)((70L*count[i])/j); }
    
       al_trace( "\n" );
       for (i = 0; i < cnt; i++)
            {
                    al_trace( "\n%02d|" , i );
                    for (j = 1; j < count[i] ; j = j+1)
                            al_trace( "*" );
            }
       al_trace( "\n%s\np. mean = %9f, p. var = %9f\ns. mean = %9f, s. var = %9f\n" ,
                    rx->Name() , rx->Mean() , rx->Variance() , mean , sd * sd );//LINE 87
    
            delete count;
       delete a;
    }
    The code that makes the ExtReal class is

    Code:
    // extreal.h ----------------------------------------------------------
    
    
    #ifndef EXTREAL_LIB
    #define EXTREAL_LIB 0
    
    #ifdef use_namespace
    namespace NEWRAN { using namespace RBD_COMMON; }
    namespace RBD_LIBRARIES { using namespace NEWRAN; }
    namespace NEWRAN {
    #endif
    
    /************************ extended real class ***************************/
    
    enum EXT_REAL_CODE
       { Finite, PlusInfinity, MinusInfinity, Indefinite, Missing };
    
    class ExtReal   {
       Real value;
       EXT_REAL_CODE c;
    public:
       ExtReal operator+(const ExtReal&) const;
       ExtReal operator-(const ExtReal&) const;
       ExtReal operator*(const ExtReal&) const;
       ExtReal operator-() const;
       friend ostream& operator<<( ostream&, const ExtReal& );
       ExtReal(Real v) { c=Finite; value=v; }
       ExtReal(const EXT_REAL_CODE& cx) { c = cx; }
       ExtReal() { c = Missing; }
       Real Value() const { return value; }
       bool IsReal() const { return c==Finite; }
       EXT_REAL_CODE Code() const { return c; }
    };
    
    #ifdef use_namespace
    }
    #endif
    
    
    #endif
    That's the header tell me if you want the source too

    The errors I get are

    Code:
    ../Source/Distribution/hist.cpp: In function `void Histogram(Random*, int)':
    ../Source/Distribution/hist.cpp:50: warning: cannot pass objects of non-POD
       type `class ExtReal' through `...'; call will abort at runtime
    ../Source/Distribution/hist.cpp:50: warning: cannot pass objects of non-POD
       type `class ExtReal' through `...'; call will abort at runtime
    ../Source/Distribution/hist.cpp: In function `void Hist(Random*, int, int)':
    ../Source/Distribution/hist.cpp:87: warning: cannot pass objects of non-POD
       type `class ExtReal' through `...'; call will abort at runtime
    ../Source/Distribution/hist.cpp:87: warning: cannot pass objects of non-POD
       type `class ExtReal' through `...'; call will abort at runtime
    No clue what to do with that

    Thanks

  5. #5
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    > ofstream doesn't exist in Linux I beleive

    Yes it does. Perhaps you just have an outdated library. Try the <fstream> header. If that doesn't work, then you might want to check out STLPort (www.stlport.org) - a fairly good STL implementation.
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  2. Errors including <windows.h>
    By jw232 in forum Windows Programming
    Replies: 4
    Last Post: 07-29-2008, 01:29 PM
  3. How to monitor process creation?
    By markiz in forum Windows Programming
    Replies: 31
    Last Post: 03-17-2008, 02:39 PM
  4. Post...
    By maxorator in forum C++ Programming
    Replies: 12
    Last Post: 10-11-2005, 08:39 AM
  5. ras.h errors
    By Trent_Easton in forum Windows Programming
    Replies: 8
    Last Post: 07-15-2005, 10:52 PM