Seite 1 von 1

Compilerfehler MinGW,gcc ???

Verfasst: 24. Juli 2009 13:35
von graythornAK
Hallo,
kennt einer folgendes Problem?
Der Fehler tritt auf in einer Windows XP, MinGW, gcc Umgebung, c++ code

Code: Alles auswählen

typedef   long double             ldbl;
typedef   ldbl                        rgbType_t;

rgbType_t    Func1()
{
   ...
   rgbType_t    i = RechneEtwas();    // ist hier ungleich 0!!!!
   ...

   return i;                                      // i ist immer noch ungleich 0 !!!
}


void Func2()
{
    rgbType_t    wert = Func1();      // wert ist immer == 0 !!!

    
}

Es sieht so aus, als ob long double als Rückgabewert nicht funktioniert! Ich bekomme als Rückgabewert der Func1() stets 0 zurück.

Ändere ich die Zeile:

Code: Alles auswählen

typedef   long double             ldbl;
in

Code: Alles auswählen

typedef   double             ldbl;
Funktioniert alles.

Kann das jemand erklären? Ich tippe auf einen Compilerfehler...

Gruß
Andreas

Verfasst: 24. Juli 2009 14:36
von RHBaum
Also so wie du es erzaehlst, waer es wirklich ein gravierender fehler im compiler ....

Ich denk mal der Fehler liegt irgendwo im Detail ....

wie chekcst du wert== 0 ab ? immer mit der selben methode ....

Anmerkung: long double kann greosser sein als wie es bits verwendet.
Das kann bei unterschiedlichen checks zu unterschiedlichen ergebnissen fuehren ...
debuggst du ? wie kommst auf die werte, welchen debugger verwendets du ? Kann der debugger ueberhaupt verneunftige werte fuer long double dasrstellen ?

ist der hier gepostete code wirklich aequivalent zu dem, welchen du laufen laesst ? ned irgendwo nen vertipper drin ?

sind die beiden funktionen in der selben uebersetzungseinheit, oder exportierst du long double ueber dll/exe grenzen ???


Ciao ...

Verfasst: 24. Juli 2009 14:55
von graythornAK
wie chekcst du wert== 0 ab ? immer mit der selben methode ....
ich schaue mir den Wert im gdb an. Dort ist er immer 0!
Aber:
Das Laufzeitverhalten des Programms ist das, was es hätte, wenn der Rückgabewert immer 0 ist. Deshalb kam ich überhaupt darauf. Egal was der Debugger anzeigt (ich weiß nicht ob er das immer richtig anzeigt, weiß das jemand?)
Jedenfalls wird das i in Func1() mit 0.52... angezeigt, das entspricht dem erwarteten Wert. Nach der Zuweisung in Func2() zeigt gdb 0 an.
DER RÜCKGABEWERT ist 0!
ist der hier gepostete code wirklich aequivalent zu dem, welchen du laufen laesst ? ned irgendwo nen vertipper drin ?
KEIN VERTIPPER! Der Code entspricht genau dem Programmcode!
sind die beiden funktionen in der selben uebersetzungseinheit, oder exportierst du long double ueber dll/exe grenzen ???
Func1() wird als bibliothek übersetzt.
Func2() ist im Hauptprogramm und linkt die Bibliothek von Func1() statisch hinzu.

Verfasst: 26. Juli 2009 21:02
von Christian81
Wie RHBaum schon sagte - hier hat der Compiler unter Garantie keine Schuld und der Fehler sitzt vor dem Bildschirm.
Schreib uns ein Testcase und wir werden den Fehler finden.

Verfasst: 27. Juli 2009 11:59
von RHBaum
Das Laufzeitverhalten des Programms ist das, was es hätte, wenn der Rückgabewert immer 0 ist.
wie checkst du bitte auf "0" bei long double ?
im programm den Nullwert (0.0 in float schreibweisse) zu checken macht doch keinen sinn ? eigentlich kann nen flieskommawert immer nur annaehernd null werden aber nie ganz ....

was willst du mit 0 darstellen ? das nicht vorhandensein eines wertes ? dann solltest lieber nen 2.ten parameter zu hilfe nehmen !

long double x = func();

if(x == 0.0) <- sollte dir haufenweisse warnings oder gar errors bescheren ! Selbst wenn man die warnings wegcastet, ist der vergleich mega unsicher ...

if(x) <- genau so ... iss soweiso der falsche weg ....

Ciao .....

Verfasst: 28. Juli 2009 08:39
von graythornWW
wie checkst du bitte auf "0" bei long double ?
Natürlich teste ich nicht auf 0 sondern auf |x|<epsilon, wobei epsilon eine Konstante im Program nahe 0 ist. In meinem Fall teste ich allerdings gegen eine andere Variable - siehe unteres Listing...
Wie RHBaum schon sagte - hier hat der Compiler unter Garantie keine Schuld und der Fehler sitzt vor dem Bildschirm.
Das sage ich auch immer, und hoffe das das auch hier der Fall ist :-)
Schreib uns ein Testcase und wir werden den Fehler finden.

Hier mein Code:

Es gibt eine Library in der steht folgende Klasse mit folgender Funktion:

Code: Alles auswählen

	class RgbNorm : public RefObj
	{
		public:
			RgbNorm_t  r;
			RgbNorm_t  g;
			RgbNorm_t  b;

			RgbNorm();

			RgbNorm(const RgbNorm &_rhs);

			RgbNorm(const RgbNorm_t 	_r,
					const RgbNorm_t 	_g,
					const RgbNorm_t 	_b);

			RgbNorm&				operator=(const RgbNorm &_rgb);
			bool					operator==(const RgbNorm &_rgb) const;
			bool					operator!=(const RgbNorm &_rgb) const;

			void					SetRgb(const RgbNorm_t 	_r,
										   const RgbNorm_t 	_g,
										   const RgbNorm_t 	_b);

			RgbNorm_t			  	GetAverage() const;
			RgbNorm_t				GetDistanceQuad(const RgbNorm 	&_rhs) const;

			void					Invert();													 // invert the rgb-values (rgb_new = 255 - rgb_old)

		public:
			virtual enumArchive		Stream(Archive 	&_a);
	}; // class RgbNorm
die Basisklasse RefObj implementiert einen Referenzzähler und kann hier ignoriert werden.

Hier interessiert die Methode:
GetDistanceQuad

Code: Alles auswählen

	///////////////////////////////////////////////////////////////////////////////
	// RgbNorm::GetDistanceQuad
	///////////////////////////////////////////////////////////////////////////////
	RgbNorm_t RgbNorm::GetDistanceQuad(const RgbNorm 	&_rgb) const
	{
		RgbNorm_t fDist = (_rgb.r - r) * (_rgb.r - r) +
				 (_rgb.g - g) * (_rgb.g - g) +
				 (_rgb.b - b) * (_rgb.b - b);             // != 0

		return fDist;                    // nach Rückgabe == 0
	} // RgbGetDistanceQuad
Hier gibts es das Problem, siehe auch weiter unten für die Erläuterung dessen, was die Klassen machen sollen.
Zu Testzwecken weise ich das Quadrat der Farbabweichung, einem Wert zu. Dieser ist an dieser Stelle != 0, nach Rückgabe == 0

------------------------------------------------------------------------------
In einer weiteren Bibliothek steht folgende Klasse:


Code: Alles auswählen

	class Palette : public RefObj
	{
		protected:
			u16			m_u16Colors;								// no. of the colors in this palette
			RgbNorm		*m_pRgb;									// pointer to the rgb-values

		public:
			Palette();												// creates an empty palette
			Palette(enumPalType  _ePalType);						// creates the palette from PalType

			Palette(const u16				_u16ColorCount,			// for optimized palettes
					const enumForceColor	_eForceColor,
					const Pic				*_pPic);

			//Palette(i16				_u16ColorCount,
			//		structRgbQuad	*_pRgbQuad);

			Palette(const Palette &_rhs);

			virtual ~Palette();

		/////////////////////////////////////////////////////////////////////////////
		// operators
		/////////////////////////////////////////////////////////////////////////////
		public:
			Palette&				operator=(const Palette &_rhs);


		/////////////////////////////////////////////////////////////////////////////
		// access
		/////////////////////////////////////////////////////////////////////////////
		public:
			u16						GetColorCount() const;							// number of the colors in this palette

			bool					AddColor(const RgbNorm_t   	_r,					// new color r-value to add
											 const RgbNorm_t   	_g,					// new color g-value to add
	                                         const RgbNorm_t   	_b,					// new color b-value to add
	                                         const bool			_bCheck4Double);	// True => check, whether the color is always in the palette
																					// return: true=> color was added or already in the palette
																					// 		   false => always 0xffff colors in the palette => no color was added

			bool					AddColor(const RgbNorm		&_rgbNew,			// new color to add
											 const bool			_bCheck4Double);	// True => check, whether the color is always in the palette
																					// return: true  => color was added or already in the palette
																					//         false => always 0xffff colors in the palette => no color was added

			const RgbNorm&			GetRgb(const u16 _u16Index) const;				// no check, _u16Index must not be greater than m_u16Colors-1

			const RgbNorm&			GetRgbCheck(const u16  _u16Index) const;		// with check, _slIndex<0 || _slIndex>=m_u16Colors => return rgbBlack

			void					GetRgb(const u16	_u16Index,					// no check, _u16Index must not be greater than m_u16Colors-1
										   RgbNorm		&_rgb) const;

			void					GetRgb(const u16   	_u16Index,					// no check, _u16Index must not be greater than m_u16Colors-1
										   RgbNorm_t	&_r,
										   RgbNorm_t	&_g,
										   RgbNorm_t	&_b) const;

			virtual void			GetNearestRgb(const RgbNorm	&_rgbShut,			// return the CRgb::GetDistanceQuad of the two rgb´s
												  RgbNorm		&_rgbIs) const;		// no color found => black

			virtual RgbNorm_t		GetNearestRgbDistQuad(const RgbNorm	&_rgbShut,		// return the CRgb::GetDistanceQuad of the two rgb´s
													      RgbNorm		&_rgbIs) const;	// no color found => black
																					// return: the distance to the shut-color

			void					SetRgb(const u16		_u16Index,				// no check, _s32Index must not be greater than m_s32Colors-1
										   const RgbNorm	&_rgb);

			void					SetRgb(const u16			_u16Index,					// no check, _s32Index must not be greater than m_s32Colors-1
										   const RgbNorm_t		_r,
										   const RgbNorm_t		_g,
										   const RgbNorm_t		_b);

		private:
			void 					AddWebPalette();

			void					MedianCut(s16			_s16Colors,
											  const Pic		*_pPic);

		/////////////////////////////////////////////////////////////////////////////
		// modifying
		/////////////////////////////////////////////////////////////////////////////
		public:
			void					Invert();									// invert the rgb-values (rgb_new = 255 - rgb_old)


		/////////////////////////////////////////////////////////////////////////////
		// member from CBaseObj
		/////////////////////////////////////////////////////////////////////////////
		//public:
			//	// I/O-subroutines
	    	//virtual enumArchive       Archive(CArchiveAK &_a);

		//protected:
			//virtual void              DeleteContents();               // default: does nothing
	}; // class Palette

Hier interessiert die Methode:
GetNearestRgbDistQuad

Code: Alles auswählen

//////////////////////////////////////////////////////////////////////////
// Palette::GetNearestRgbDistQuad
//////////////////////////////////////////////////////////////////////////
RgbNorm_t Palette::GetNearestRgbDistQuad(const RgbNorm   &_rgbShut,
										 RgbNorm         &_rgbIs) const
{
	CHECK_PRE_CONDITION(m_u16Colors > 0, 0)

	u16      	u;
	s16			s16Index   	= 0;
	RgbNorm_t  	fMinDist	= m_pRgb[0].GetDistanceQuad(_rgbShut);	// mit erstem Rgb-Wert-Abstand initialisieren
	RgbNorm_t   fDist;

	for (u=1; u<m_u16Colors; u++)
	{
		fDist = m_pRgb[u].GetDistanceQuad(_rgbShut);   // hier kommt 0 zurück!
		if (fDist < fMinDist)
		{
			fMinDist = fDist;
			s16Index   = (s16) u;
		}
	} // for (si=0; si<m_u16Colors; si++)

	return fMinDist;
} // Palette::GetNearestRgbDistQuad
-----------------------------------------------------
Was macht die Methode?

vorab:
Die Bibliotheken haben aus Kompatibilitätsgründen eigene Datentypen:
u16 ist unsigned mit 16 bit
s16 ist signed mit 16 bit

Code: Alles auswählen

typedef	short				s16;
typedef	unsigned short		u16;
außerdem:

Code: Alles auswählen

typedef	double				dbl;
typedef	dbl						RgbNorm_t;
Ich suche den zu einem gegebenen RGB-Wert nächsten Paletteneintrag.
Dazu iteriere ich über die Einträge der Palette, berechne mir den quadratischen Abstand. Ist dieser Abstand kleiner als das bisherige Minimum, wird dieses gespeichert als potentiell nächste Farbe, usw.
Am Ende gebe ich diesen Abstand zurück, der ist aber natürlich dann 0.

Ach ja, der Fehler tritt auch mit RgbNorm_t = double auf!

Beide Bibliotheken (also die mit RgbNorm und die mit Palette) werden statisch zum Hauptprogramm gelinkt.

Ich hoffe, das diese Angaben helfen. Wie gesagt, auch ich gehe von einem Fehler VOR dem Bildschirm aus, allerdings sehe ich keinen, und soooo komplex ist das Programm ja nicht!

Danke und Gruß
[/code]

Verfasst: 28. Juli 2009 09:17
von solarix
Du verstehst sicher: solche Kleinigkeiten wie "Ach ja, der Fehler tritt auch mit RgbNorm_t = double auf!" machen natürlich misstrauisch.. ich fürchte daher, du wirst nicht um einen vollständigen Testcase herumkommen. Der Source sollte
* möglichst klein sein (main/RgbNorm/Palette/RefObj)
* mit "qmake;make" generierbar sein
* mit "qDebug()" und evt. "Q_ASSERTS" versehen sein, damit wir das Problem sofort nach dem Start sehen.

Problem gelöst...

Verfasst: 28. Juli 2009 09:50
von graythornWW
Ich habe das Problem gelöst, allerdings nicht lokalisiert...

Dazu sei gesagt, daß das Programm auf einer Ubuntu-c++ Umgebung und unter Microsoft Visual-Studio compiliert einwandfrei läuft. Also habe ich den Fehler in der Umgebung und nicht im Programmcode gesucht (falls es jemand interessiert, ich kann tatsächlich sehr sicher C++ und gebe sogar Schulungen...). Allerdings habe ich Arbeit für den Test-case etwas gescheut, daher erst mal auf die schnelle die Mail von eben :oops:

Allerdings hatte ich neben dem genannten Problem auch merkwürdiges Verhalten von Eclipse und nicht reproduzierbare Abstürze während des Comilierens.

Also habe ich - aus lauter Verzweiflung - die komplette Arbeitumgebung incl. MinGW neu installiert.
Jetzt läuft alles einwandfrei. :-) :-) :-)

Ich habe keine Ahnung, was nicht in Ordnung war, allerdings gingen die Probleme los, als ich mit dem GDB anfing zu arbeiten. Dieser stürzte dann während des debuggens erst manchmal, dann immer öfters ab. Aber das kann purer Zufall sein, und nichts mit meinem Problem zu tun haben.

In diesem Zusammenhang habe ich eine andere Frage, da ich im Open-Source Umfeld noch nicht so sicher bin.

:?: :?: :?:
Wo finde ich Informationen, Anleitngen zum Compiler und Libraries, insbesondere gcc in der MinGW-Umgebung
:?: :?: :?:

Ich habe ein gcc-Handbuch gefunden (googlen ist nicht meine Stärke), aber da steht leider nichts zu der Genauigkeit der Datentypen drin. Ist es IEEE-Standard? Das vermute ich zwar, weiß es aber nicht...

Danke an alle, die sich Zeit genommen haben