Seite 1 von 1
C++... ich seh den Fehler nicht!
Verfasst: 13.01.2014, 18:10
von Niki
Zu Hülf!
Das ist mir jetzt echt peinlich das hier zu posten... Wahrscheinlich bin ich nur schon blind, weil heute ein anstrengender Tag war... Oder ist hier mal wieder was das mir bei C/C++ nie bewusst war?!
In beiden Code-Beispielen hat "actual size" eine Höhe von 100. Der Unterschied ist hoffentlich nur, dass (1) über eine temporäre Kopie geht.
(1) Code 1
Code: Alles auswählen
double y = 0.0;
Size2d actualSize = pChild->getActualSize();
y += actualSize.height();
Das Ergebnis ist erwartungsgemäß
y=100.
(2) Code 2
Code: Alles auswählen
double y = 0.0;
y += pChild->getActualSize().height();
Das Ergebnis ist unerwarteterweise
y=-9.2559631349317831e+061
EDIT: Klammen setzen habe ich schon probiert. Threads fummeln auch nicht dazwischen, weil keine sekundären aktiv sind. Solution cleanen habe ich auch schon mehrfach getan.
Re: C++... ich seh den Fehler nicht!
Verfasst: 13.01.2014, 18:57
von gdsWizard
Das sieht alles sehr nach gleicher Funktionalität aus. Entweder hast du einen Compilerfehler gefunden oder aber bei dem 2.Fall ist die Höhe noch nicht initialisiert. Der Return-Wert -9.2559631349317831e+061 deutet darauf hin. Werden denn die beiden Code-Schnipsel an der selben Stelle ausgeführt ? Schau dir mal im Debugger den Assemblercode an und die Register.
Edit: Es könnte auch ein Fehler beim Kopieren des size2D-Objects sein, also der Klasse. Ich nehme an das du diese Klasse selbst geschrieben hast.
Re: C++... ich seh den Fehler nicht!
Verfasst: 13.01.2014, 19:01
von Niki
gdsWizard hat geschrieben:Das sieht alles sehr nach gleicher Funktionalität aus. Entweder hast du einen Compilerfehler gefunden oder aber bei dem 2.Fall ist die Höhe noch nicht initialisiert.
Der 1. und der 2. Fall sind an der gleichen Stelle. Den 1. Fall habe ich nur implementiert weil ich den 2. Fall nicht verstanden habe.
Irgendwie kann ich mir nicht vorstellen, dass das ein Compiler-Fehler sein soll. Ich suche mal weiter... Womöglich muss ich mal den Assembler-Code ansehen, und beten dass ich den verstehe.
Re: C++... ich seh den Fehler nicht!
Verfasst: 13.01.2014, 19:04
von gdsWizard
Ich hatte den Post nochmal geändert da hast du schon wieder geantwortet.
Es könnte auch ein Fehler beim Kopieren des size2D-Objects sein, also der Klasse. Ich nehme an das du diese Klasse selbst geschrieben hast.
Re: C++... ich seh den Fehler nicht!
Verfasst: 13.01.2014, 19:08
von Niki
gdsWizard hat geschrieben:Es könnte auch ein Fehler beim Kopieren des size2D-Objects sein, also der Klasse. Ich nehme an das du diese Klasse selbst geschrieben hast.
Jepp. Hier ist der Quelltext. Dazu gibt's noch ein
using Size2d = TSize2<double>;. Die Klasse macht aber an tausend anderen Stellen keine Problem.
Code: Alles auswählen
template <class _TType>
class TSize2
{
public:
TSize2()
: m_width((_TType)0)
, m_height((_TType)0)
{
}
template <class _TType2>
TSize2(const TSize2<_TType2> & rOther)
: m_width(static_cast<_TType>(rOther.width()))
, m_height(static_cast<_TType>(rOther.height()))
{
}
TSize2(_TType width, _TType height)
: m_width(width)
, m_height(height)
{
}
public:
template <class _TType2>
TSize2<_TType> & operator = (const TSize2<_TType2> & rOther)
{
m_width = static_cast<_TType>(rOther.width());
m_height = static_cast<_TType>(rOther.height());
return *this;
}
TSize2<_TType> & operator += (const TSize2<_TType> & rSize)
{
m_width += rSize.m_width;
m_height += rSize.m_height;
return *this;
}
TSize2<_TType> & operator -= (const TSize2<_TType> & rSize)
{
m_width -= rSize.m_width;
m_height -= rSize.m_height;
return *this;
}
TSize2<_TType> operator + (const TSize2<_TType> & rSize) const
{
return TSize2<_TType>(m_width + rSize.m_width, m_height + rSize.m_height);
}
TSize2<_TType> operator - (const TSize2<_TType> & rSize) const
{
return TSize2<_TType>(m_width - rSize.m_width, m_height - rSize.m_height);
}
_TType operator [] (int index) const
{
return m_array[index];
}
_TType & operator [] (int index)
{
return m_array[index];
}
operator const _TType * () const
{
return m_array;
}
operator _TType * ()
{
return m_array;
}
public:
_TType width() const
{
return m_width;
}
_TType & width()
{
return m_width;
}
_TType height() const
{
return m_height;
}
_TType & height()
{
return m_height;
}
bool hasZeroArea() const
{
return m_width <= ((_TType)0) && m_height <= ((_TType)0);
}
private:
union
{
struct
{
_TType m_width;
_TType m_height;
};
_TType m_array[2];
};
};
Re: C++... ich seh den Fehler nicht!
Verfasst: 13.01.2014, 19:18
von Niki
Ok, also in einer separaten Konsolenanwendung funktioniert es. Und überall anders im Projekt habe ich damit auch keine Problem. Der Fehler muss irgendwie im Kontext der folgenden Methode auftreten, die ich leider nicht mal eben zum posten versimplifizieren kann. Aber vielleicht sieht ja doch jemand was. Fall 1 und 2 sind in dem Präprozessor-Teil im
else Zweig.
Code: Alles auswählen
void StackLayout::onLayoutChildren(View * pParentView, const Rectangle2d & paddedParentRect)
{
Size2d contentSize(0.0, 0.0);
if (m_orientation == StackLayoutOrientation::Horizontal)
{
contentSize.height() = paddedParentRect.height();
size_t numChildren = pParentView->getNumChildren();
for (size_t i = 0; i < numChildren; i++)
{
View * pChild = pParentView->getChild(i);
updateActualRect(pChild, Rectangle2d(contentSize.width(), 0.0, Mathd::MaxValue, paddedParentRect.height()));
contentSize.width() += pChild->getActualSize().width();
//@@@ spacing
}
}
else // if (m_orientation == StackLayoutOrientation::Vertical)
{
contentSize.width() = paddedParentRect.width();
size_t numChildren = pParentView->getNumChildren();
for (size_t i = 0; i < numChildren; i++)
{
View * pChild = pParentView->getChild(i);
Rectangle2d actualRect = updateActualRect(pChild, Rectangle2d(0.0, contentSize.height(), paddedParentRect.width(), Mathd::MaxValue));
double y = 0.0;
#if 0
Size2d actualSize = pChild->getActualSize();
y+= actualSize.height();
#else
y += pChild->getActualSize().height();
#endif
contentSize.height() += /*actualRect.height();/*/ (pChild->getActualSize()).height();
//@@@ spacing
}
}
//@@@ set content size
}
Re: C++... ich seh den Fehler nicht!
Verfasst: 13.01.2014, 19:23
von gdsWizard
Gibt die Funktion getActualSize() vllt eine Referenz auf ein TSize2 Objekt zurück ?
Ein Beispiel wäre:
TSize2<double> &Test()
{
TSize2<double> a(100,200);
return a;
}
Das erzeugt einen ähnlichen Fehler.
Re: C++... ich seh den Fehler nicht!
Verfasst: 13.01.2014, 19:28
von Niki
In
pChild->getActualSize() ist
pChild vom Typ
View *. Die Klasse
View enthält eine Member-Variable
Rectangle2d m_actualRect;. Die Method
getActualSize() sieht so aus:
Code: Alles auswählen
QX_INLINE const Size2d & View::getActualSize() const
{
return m_actualRect.size();
}
Ach, ja, gesetzt wird
m_actualRect innerhalb von
updateActualRect. (siehe letzte Post von mir)
Vielen dank, dass du dir so viel Zeit nimmst :-) Sag Bescheid wenn du Rectangle2d auch noch brauchst.
Re: C++... ich seh den Fehler nicht!
Verfasst: 13.01.2014, 19:34
von gdsWizard
Im folgendem Code solltest du das Referenzzeichen '&' entfernen. Dann sollte es gehen.
QX_INLINE const Size2d & View::getActualSize() const
{
return m_actualRect.size();
}
die size() Methode baut auf dem Stack ein Size2d Object auf und die Methode getActualSize() referenziert dies. Das ist ein Bug. Ändere es in:
QX_INLINE const Size2d View::getActualSize()
{
return m_actualRect.size();
}
dann sollte es gehen.
Re: C++... ich seh den Fehler nicht!
Verfasst: 13.01.2014, 19:45
von Niki
gdsWizard hat geschrieben:Im folgendem Code solltest du das Referenzzeichen '&' entfernen.
Das da eine
const-Referenz steht ist schon ok, da
Rectangle2d::size() wiederum eine
const-Referenz zurückgibt. Oder besser gesagt, sie hätte das tun sollen, aber ich hatte in
Rectangle2d::size() einen Bug, den du mir gerade geholfen hast zu finden. Vielen lieben Dank!!! :-)
Und damit du auch siehst, wobei du geholfen hast... (das StackLayout rechts oben mit den grünen Zellen):
Re: C++... ich seh den Fehler nicht!
Verfasst: 13.01.2014, 19:51
von gdsWizard
Schön das ich dir helfen konnte. Ich benutze nur selten das Schlüsselwort const. Deshalb hatte ich es entfernt, macht ja hauptsächlich bei Referenzen Sinn.
Re: C++... ich seh den Fehler nicht!
Verfasst: 15.01.2014, 02:28
von dot
gdsWizard hat geschrieben:Schön das ich dir helfen konnte. Ich benutze nur selten das Schlüsselwort const. Deshalb hatte ich es entfernt, macht ja hauptsächlich bei Referenzen Sinn.
Vielleicht solltest du dich doch mal etwas tiefgehender mit const beschäftigen. const correctness ist in C++ von fundamentaler Bedeutung... ;)
Re: C++... ich seh den Fehler nicht!
Verfasst: 15.01.2014, 08:31
von gdsWizard
Vielleicht solltest du dich doch mal etwas tiefgehender mit const beschäftigen. const correctness ist in C++ von fundamentaler Bedeutung... ;)
Als ich angefangen habe in C++ zu programmieren hatte ich mir auch const angesehen. Ist ein const parameter einmal const müsste man ihn extra casten um ihn ändern zu können. Ich habe eben nochmal gegoogelt. Im obigen Beispiel wäre es natürlich richtig gewesen const bei zu belassen, zumal es sich hier um die const deklaration für this handelt. Ich gebe bei Return-Werten fast immer (außer bei meinen array templates) normale Objekte zurück, also keine Referenzen. Wenn nötig gebe ich Zeiger zurück. Aber nachdem ich jetzt wieder mein Wissen diesbezüglich erneuert habe werde ich in Zukunft wieder const benutzen. Man lernt eben nie aus. :)
Eine andere Frage: warum funktioniert der Benutzername in quote bei mir nicht ? Kann mir da jemand helfen ? Ich hatte folgendes probiert:
dot hat geschrieben: Vielleicht ...
Re: C++... ich seh den Fehler nicht!
Verfasst: 15.01.2014, 08:58
von Niki
gdsWizard hat geschrieben:Eine andere Frage: warum funktioniert der Benutzername in quote bei mir nicht ? Kann mir da jemand helfen ?
Wenn du den Benutzernamen in Gänsefüßchen packst, dann funktioniert es.
Re: C++... ich seh den Fehler nicht!
Verfasst: 15.01.2014, 09:26
von gdsWizard
Niki hat geschrieben:Wenn du den Benutzernamen in Gänsefüßchen packst, dann funktioniert es.
Danke für den wertvollen Hinweis. Ich dachte ich hätte das schon probiert. Scheinbar doch nicht. Jetzt bin ich froh das der Quote-Benutzername funktioniert. Vielen Dank.