VC++ error C2440



  • Hallo,

    ich habe null Erfahrung ,it VC++ und habe folgendes Problem: Ich möchte eine Application Note von ATMEL benutzen, in em ein Programm enthalten ist, das mit VC++ 6.0 übersetzt wurde und wohl auch lief.

    Ich bräuchte ein Idiotensicheres Feedback. Weil meine C-Kenntnisse nutzen mir gar nichts, wenn ich den Code anschaue.

    Ich habe die Express Edition 2005 und das SDK installiert. Zum Teil kann ich die Programme der Appl.-Note übersetzen, aber eines bringt Fehlermeldungen. Die tausend Warnungen habe ich mal weggelassen

    Vielen Dank vorab.

    1>d:\wolfi\tmp\avr230\source code\create\memorymap.cpp(148) : error C2440: 'Initialisierung': 'std::_Vector_iterator<_Ty,_Alloc>' kann nicht in 'MemoryChunk *' konvertiert werden
    1> with
    1> [
    1> _Ty=MemoryChunk,
    1> _Alloc=std::allocator<MemoryChunk>
    1> ]
    1> Kein benutzerdefinierter Konvertierungsoperator verfügbar, der diese Konvertierung durchführen kann, oder der Operator kann nicht aufgerufen werden
    1>d:\wolfi\tmp\avr230\source code\create\memorymap.cpp(148) : error C2679: Binärer Operator '!=': Es konnte kein Operator gefunden werden, der einen rechtsseitigen Operanden vom Typ 'std::_Vector_iterator<_Ty,_Alloc>' akzeptiert (oder keine geeignete Konvertierung möglich)
    1> with
    1> [
    1> _Ty=MemoryChunk,
    1> _Alloc=std::allocator<MemoryChunk>
    1> ]
    1> kann 'eingebauter C++ Operator!=(MemoryChunk *, MemoryChunk *)' sein
    1> bei Anpassung der Argumentliste '(MemoryChunk *, std::_Vector_iterator<_Ty,_Alloc>)'
    1> with
    1> [
    1> _Ty=MemoryChunk,
    1> _Alloc=std::allocator<MemoryChunk>
    1> ]
    1>d:\wolfi\tmp\avr230\source code\create\memorymap.cpp(161) : error C2440: 'Initialisierung': 'std::_Vector_iterator<_Ty,_Alloc>' kann nicht in 'MemoryChunk *' konvertiert werden
    1> with
    1> [
    1> _Ty=MemoryChunk,
    1> _Alloc=std::allocator<MemoryChunk>
    1> ]
    1> Kein benutzerdefinierter Konvertierungsoperator verfügbar, der diese Konvertierung durchführen kann, oder der Operator kann nicht aufgerufen werden
    1>d:\wolfi\tmp\avr230\source code\create\memorymap.cpp(161) : error C2679: Binärer Operator '!=': Es konnte kein Operator gefunden werden, der einen rechtsseitigen Operanden vom Typ 'std::_Vector_iterator<_Ty,_Alloc>' akzeptiert (oder keine geeignete Konvertierung möglich)
    1> with
    1> [
    1> _Ty=MemoryChunk,
    1> _Alloc=std::allocator<MemoryChunk>
    1> ]
    1> kann 'eingebauter C++ Operator!=(MemoryChunk *, MemoryChunk *)' sein
    1> bei Anpassung der Argumentliste '(MemoryChunk *, std::_Vector_iterator<_Ty,_Alloc>)'
    1> with
    1> [
    1> _Ty=MemoryChunk,
    1> _Alloc=std::allocator<MemoryChunk>
    1> ]
    1>OutputWriter.cpp

    1>d:\wolfi\tmp\avr230\source code\create\outputwriter.cpp(299) : error C2440: 'Initialisierung': 'std::_String_iterator<_Elem,_Traits,_Alloc>' kann nicht in 'unsigned char *' konvertiert werden
    1> with
    1> [
    1> _Elem=unsigned char,
    1> _Traits=std::char_traits<unsigned char>,
    1> _Alloc=std::allocator<unsigned char>
    1> ]
    1> Kein benutzerdefinierter Konvertierungsoperator verfügbar, der diese Konvertierung durchführen kann, oder der Operator kann nicht aufgerufen werden
    1>d:\wolfi\tmp\avr230\source code\create\outputwriter.cpp(299) : error C2679: Binärer Operator '!=': Es konnte kein Operator gefunden werden, der einen rechtsseitigen Operanden vom Typ 'std::_String_iterator<_Elem,_Traits,_Alloc>' akzeptiert (oder keine geeignete Konvertierung möglich)
    1> with
    1> [
    1> _Elem=unsigned char,
    1> _Traits=std::char_traits<unsigned char>,
    1> _Alloc=std::allocator<unsigned char>
    1> ]
    1> kann 'eingebauter C++ Operator!=(unsigned char *, unsigned char *)' sein
    1> bei Anpassung der Argumentliste '(unsigned char *, std::_String_iterator<_Elem,_Traits,_Alloc>)'
    1> with
    1> [
    1> _Elem=unsigned char,
    1> _Traits=std::char_traits<unsigned char>,
    1> _Alloc=std::allocator<unsigned char>
    1> ]

    Ich füge noch die Codestellen ein, die ich für relevant halte (eine Möglichkeit Dateien anzuhängen habe ich nicht gefunden):

    //=============================================================================
    // Copyright (C) 2003 Atmel Corporation
    //
    // File:			MemoryMap.h
    // Compiler:		Microsoft Visual C++ 6.0
    // Output Size:
    // Created:			4-Feb-2003	JP (Atmel Finland)
    // Modified:
    //
    // Support Mail:	avr@atmel.com
    //
    // Description:		MemoryMap is a list (vector) of MemoryChunks that together
    //					constitute the contents of a certain memory, e.g. AVR flash
    //					memory contents. It is possible to access the MemoryMap
    //					as an array, so the internal structure is that way hidden
    //					from the user.
    //
    // Other Info:		
    //=============================================================================
    
    #ifndef MEMORYMAP_H
    #define MEMORYMAP_H
    
    #include "MemoryChunk.h"
    #include "DataBuffer.h"
    #include <vector>
    
    typedef std::vector<MemoryChunk, std::allocator<MemoryChunk> > MemoryChunkVector;
    
    class MemoryMap : private MemoryChunkVector
    {
    public:
    	MemoryMap(unsigned char emptyFill = 0x00);
    	MemoryMap(const char *filename, unsigned int start = 0x00000000,
    		unsigned int end = 0xffffffff, unsigned char emptyFill = 0x00);
    
    	virtual ~MemoryMap();
    
    	bool in(unsigned int address);
    	unsigned char operator [] (unsigned int address);
    	unsigned char at(unsigned int address);
    	void insert(MemoryChunk& chunk);
    	void insert(unsigned int address, const DataBuffer& buffer);
    	unsigned int getLowestAddress();
    	unsigned int getHighestAddress();
    
    private:
    	unsigned char emptyFillM;			// byte that is used as the fill of
    										// empty areas in the memory
    	unsigned int loLimitM;				// Lowest address containing data
    	unsigned int hiLimitM;				// Highest address containing data
    };
    
    #endif // MEMORYMAP_H
    
    //=============================================================================
    // Copyright (C) 2003 Atmel Corporation
    //
    // File:			MemoryMap.cpp
    // Compiler:		Microsoft Visual C++ 6.0
    // Output Size:
    // Created:			4-Feb-2003	JP (Atmel Finland)
    // Modified:
    //
    // Support Mail:	avr@atmel.com
    //
    // Description:		MemoryMap is a list (vector) of MemoryChunks that together
    //					constitute the contents of a certain memory, e.g. AVR
    //					flash memory contents. It is possible to access the
    //					MemoryMap as an array, so the internal structure is that
    //					way hidden from the user.
    //
    // Other Info:		
    //=============================================================================
    
    #include "MemoryMap.h"
    #include "CreateException.h"
    
    //=============================================================================
    // Basic constructor
    
    MemoryMap::MemoryMap(unsigned char emptyFill) : loLimitM(0xffffffff),
    	hiLimitM(0x00000000), emptyFillM(emptyFill)
    {
    	// empty
    }
    
    //=============================================================================
    // Constructor, that reads the contents from an Intel Hex formatted file.
    
    MemoryMap::MemoryMap(const char *filename, unsigned int start,
    					 unsigned int end, unsigned char emptyFill)
    	: loLimitM(0xffffffff), hiLimitM(0x00000000), emptyFillM(emptyFill)
    {
    	if (!filename) return;
    
    	FILE *inFile = fopen(filename, "r");
    
    	if (!inFile)
    		throw new CreateException(ERROR_FILE_NOT_FOUND, filename);
    
    	int highAddress = 0;
    
    	while (!feof(inFile))
    	{
    		char line[300];
    		unsigned char length, type;
    		int address;
    
    		if (fscanf(inFile, ":%s\n", line) != 1)
    			throw new CreateException(ERROR_HEX_FORMAT, filename);
    
    		// Read the first 5 bytes from the current line of in_file (including
    		// the ':') into length, addr and type.
    		DataBuffer data(line);
    
    		// Count checksum and make sure that the file is not damaged
    		unsigned char chksum = 0;
    
    		for (unsigned int i = 0; i < data.size(); i++)
    			chksum += data[i];
    
    		if (chksum != 0)
    			throw new CreateException(ERROR_FILE_DAMAGED, filename);
    
    		length = data[0];
    		address = (data[1] << 8) | data[2];
    		type = data[3];
    
    		// Remove header and crc from the data
    		data = data.substr(4, length);
    
    		switch (type)
    		{
    			// Data Record (8-, 16-, 32-bit formats)
    			case 0:
    				try
    				{
    					insert(address + highAddress, data);
    				}
    
    				catch (CreateException *e)
    				{
    					if (e->getCode() == ERROR_OVERLAPPING_DATA)
    					{
    						ErrorCode code = e->getCode();
    						delete e;
    
    						throw new CreateException(code, filename);
    					}
    					else
    						throw e;
    				}
    				break;
    
    			// End of File Record (8-, 16-, 32-bit formats)
    			case 1:
    				return;
    
    			// Extended Segment Address Record (16- or 32-bit formats)
    			case 2:
    				highAddress = (data[0] << 12) + (data[1] << 4);
    				break;
    
    			// Start Segment Address Record (16- or 32-bit formats)
    			case 3:
    				break;
    
    			// Extended Linear Address Record (32-bit format)
    			case 4:
    				highAddress = (data[0] << 24) + (data[1] << 16);
    				break;
    
    			// Start Linear Address Record (32-bit format)
    			case 5:
    				break;
    
    			// Unknown type
    			default:
    				throw new CreateException(ERROR_FILE_DAMAGED, filename);
    		}
    	}
    }
    
    //=============================================================================
    // Destructor
    
    MemoryMap::~MemoryMap()
    {
    	// empty
    }
    
    //=============================================================================
    // Returns true, if some data resides in the indexed memory location
    
    bool MemoryMap::in(unsigned int address)
    {
    	for (MemoryChunk *i = begin(); i != end(); i++)
    		if (i->in(address))
    			return true;
    
    	return false;
    };
    
    //=============================================================================
    // Accesses memory by address index
    
    unsigned char MemoryMap::operator [] (unsigned int address)
    {
    	for (MemoryChunk *i = begin(); i != end(); i++)
    		if (i->in(address))
    			return (*i)[address];
    
    	return emptyFillM;
    }
    
    //=============================================================================
    // Same as 'operator []', except easier to use with pointers to objects
    // i.e. in cases like MemoryMap->at().
    // (otherwise user would need to (*MemoryMap)[] which looks clumsy).
    
    unsigned char MemoryMap::at(unsigned int address)
    {
    	return (*this)[address];
    }
    
    //=============================================================================
    // Insert a MemoryChunk to MemoryMap
    
    void MemoryMap::insert(MemoryChunk& chunk)
    {
    	unsigned int address;
    
    	for (address = chunk.getStartAddress();
    		address <= chunk.getEndAddress(); address++)
    		if (in(address))
    			throw new CreateException(ERROR_OVERLAPPING_DATA, "");
    
    	push_back(chunk);
    
    	if (loLimitM > chunk.getStartAddress())
    		loLimitM = chunk.getStartAddress();
    
    	if (hiLimitM < chunk.getEndAddress())
    		hiLimitM = chunk.getEndAddress();
    }
    
    //=============================================================================
    // Insert a DataBuffer (associated with an address) to MemoryMap
    
    void MemoryMap::insert(unsigned int address, const DataBuffer& buffer)
    {
    	insert(MemoryChunk(address, buffer, emptyFillM));
    }
    
    //=============================================================================
    // Find the lowest used address in the MemoryMap
    
    unsigned int MemoryMap::getLowestAddress()
    {
    	return loLimitM;
    }
    
    //=============================================================================
    // Find the highest used address in the MemoryMap
    
    unsigned int MemoryMap::getHighestAddress()
    {
    	return hiLimitM;
    }
    
    //=============================================================================
    // Copyright (C) 2003 Atmel Corporation
    //
    // File:			MemoryChunk.h
    // Compiler:		Microsoft Visual C++ 6.0
    // Output Size:
    // Created:			4-Feb-2003	JP (Atmel Finland)
    // Modified:
    //
    // Support Mail:	avr@atmel.com
    //
    // Description:		MemoryChunk is inherited from DataBuffer. Additionally,
    //					DataBuffer is associated to a memory location using
    //					'addressM' member.
    //
    // Other Info:		
    //=============================================================================
    
    #ifndef MEMORYCHUNK_H
    #define MEMORYCHUNK_H
    
    #include "DataBuffer.h"
    
    class MemoryChunk : public DataBuffer  
    {
    public:
    	MemoryChunk(int address, const DataBuffer& data, unsigned char emptyFill);
    	MemoryChunk(unsigned char emptyFill = 0x00);
    	MemoryChunk(const MemoryChunk& chunk);
    	virtual ~MemoryChunk();
    
    	MemoryChunk& operator =(const MemoryChunk& rvalue);
    	bool in(unsigned int address);
    	unsigned char operator[] (int address);
    
    	unsigned int getStartAddress();
    	unsigned int getEndAddress();
    
    private:
    	unsigned int addressM;
    	unsigned char emptyFillM;
    };
    
    #endif	// MEMORYCHUNK_H
    
    //=============================================================================
    // Copyright (C) 2003 Atmel Corporation
    //
    // File:			MemoryChunk.cpp
    // Compiler:		Microsoft Visual C++ 6.0
    // Output Size:
    // Created:			4-Feb-2003	JP (Atmel Finland)
    // Modified:
    //
    // Support Mail:	avr@atmel.com
    //
    // Description:		MemoryChunk is inherited from DataBuffer. Additionally,
    //					there is an association to a memory location using
    //					'addressM' member.
    //
    // Other Info:		
    //=============================================================================
    
    #include "MemoryChunk.h"
    
    //=============================================================================
    // Basic constructor
    
    MemoryChunk::MemoryChunk(unsigned char emptyFill) : addressM(0),
    	emptyFillM(emptyFill), DataBuffer()
    {
    	// empty
    }
    
    //=============================================================================
    // Constructor, that associates a DataBuffer to an address.
    
    MemoryChunk::MemoryChunk(int address, const DataBuffer& data,
    	unsigned char emptyFill) : addressM(address), emptyFillM(emptyFill),
    	DataBuffer(data)
    {
    	// empty
    }
    
    //=============================================================================
    // Copy constructor
    
    MemoryChunk::MemoryChunk(const MemoryChunk& chunk) : DataBuffer(chunk), 
    	addressM(chunk.addressM)
    {
    	// empty
    }
    
    //=============================================================================
    // Destructor
    
    MemoryChunk::~MemoryChunk()
    {
    	// empty
    }
    
    //=============================================================================
    // Assignment, rvalue of type MemoryChunk. Just makes a copy of rvalue.
    
    MemoryChunk& MemoryChunk::operator =(const MemoryChunk& rvalue)
    {
    	if (this != &rvalue)
    	{
    		DataBuffer::operator = (rvalue);
    		addressM = rvalue.addressM;
    		emptyFillM = rvalue.emptyFillM;
    	}
    
    	return *this;
    }
    
    //=============================================================================
    // Returns true, if the address is inside the MemoryChunk area.
    
    bool MemoryChunk::in(unsigned int address)
    {
    	return (address >= getStartAddress()) && (address <= getEndAddress());
    }
    
    //=============================================================================
    // Get a byte from the MemoryChunk, if the address is inside the MemoryChunk.
    // If MemoryChunk is 'missed', returns 'emptyFillM'.
    
    unsigned char MemoryChunk::operator [] (int address)
    {
    	return in(address) ?
    		DataBuffer::operator [](address - addressM) : emptyFillM;
    }
    
    //=============================================================================
    // Returns the start address of the chunk
    
    unsigned int MemoryChunk::getStartAddress()
    {
    	return addressM;
    }
    
    //=============================================================================
    // Returns the end address of the chunk
    
    unsigned int MemoryChunk::getEndAddress()
    {
    	return addressM + size() - 1;
    }
    


  • @Mods: Copyright Geschützter Source-Code abzudrucken scheint mir illegal...



  • Jochen Kalmbach schrieb:

    @Mods: Copyright Geschützter Source-Code abzudrucken scheint mir illegal...

    Der Code kann von jedem bei Atmel heruntergeladen werden. Insofern ist das sicher erlaubt zu zeigen.

    Wolfgang



  • Wolfgang Weinmann schrieb:

    Der Code kann von jedem bei Atmel heruntergeladen werden. Insofern ist das sicher erlaubt zu zeigen.

    Wolfgang

    Aber selbst wenn, wird sich hier niemand die Mühe machen, sich 448 Zeilen (ja, ich hab' nachgezählt :D) unformatierten Code anzusehen auf der Suche nach einem möglichen Fehler. Frag doch lieber die Mitarbeiter von Atmel, ob die eine VC2005-taugliche Version davon haben.



  • CStoll schrieb:

    Aber selbst wenn, wird sich hier niemand die Mühe machen, sich 448 Zeilen (ja, ich hab' nachgezählt :D) unformatierten Code anzusehen auf der Suche nach einem möglichen Fehler. Frag doch lieber die Mitarbeiter von Atmel, ob die eine VC2005-taugliche Version davon haben.

    Das habe ich versucht. Die Antwort war, daß das Programm mit der Version 6.0 übersetzt worden ist und daß eine übersetzte Variante dabei sei.
    Das nutzt mir aber nichts, da ich für meine Anwendung eine Kleinigkeit abändern muß.

    Den Aufwand für einen C++ Experten habe ich als gering vermutet. Die Fehlermeldungen habe ich ja mit eingefügt. Man muß ja nicht einen komplizierten Algorithmus durcharbeiten - es geht ja um eine Typinkompatibilität.

    Wolfgang



  • Da wäre es wenigstens hilfreich gewesen, wirklich nur die relevanten Teile des Programms hierher zu stellen - und das Syntax-Highlighting des Boards zu nutzen.

    Zu deinem Problem: vector<>::iterator kann als simpler Pointer implementiert sein, aber der Standard garantiert das nicht. Und allen Anschein nach nutzt das Prgramm die Eigenheit aus, daß VC6 es so gelöst hat. Der standardkonforme Weg wäre es, die MemoryChunk* i s zu ersetzen durch MemoryChunkVector::iterator i (oder kürzer iterator i ).

    (was für Probleme die "OutputWriter.cpp" hat, kann ich nicht beurteilen, aber vermutlich läuft es auf das selbe hinaus - verwende string::iterator anstelle von char* )



  • Hallo,

    tausend Dank - genau das war es. Das mit dem Formatieren habe ich auf die Schnelle nach bestem Wissen und Gewisssen gemacht - sorry, wenn es nicht so übersichtlich war.

    Noch eine kurze abschließende Frage: was hat es mit dem iterator auf sich - ist das eine Art Typecast oder wie kann man das verstehen. In der Hilfe kommen zu Iterator gleich x Einträge, die ich kaum verstehe.

    Gruß

    Wolfgang



  • In Kurzfassung: Die STL hat ein ca. halbes Dutzend (*nachzählt* genau gesagt sieben) verschiedene Containerklassen, die sich jeweils etwas unterschiedlich verhalten können, und eine große Sammlung an Algorithmen, die mit Datensequenzen umgehen können. Um beides zusammenfügen zu können, gibt es Iteratoren - spezielle zeiger-ähnliche Klassen, die wissen, wie sie durch IHREN Container durchlaufen können.

    (wenn du es ausführlicher haben willst, lies mal meine Artikelserie "Aufbau der STL" im Magazin)


Log in to reply