 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Albrecht Fritzsche Guest
|
Posted: Wed Apr 14, 2004 6:18 am Post subject: Verschieben von Objects und PODs |
|
|
Ok, ich hab' mir nun "Verschiebe"funktionen der Art (die _move()
Varianten sind sozusagen private, ein Implementierungsdetail)
template <typename T>
void _move(T* src, T* dest, int n, FalseType) {
// explizites Kopieren aller Objekte
}
template <typename T>
void _move(T* src, T* dest, int n, TrueType) {
// using memmove
}
// public interface
template <typename T>
void move(T* src, T* dest, int n) {
_move(src, dest, n, SomeTraits<T>::IsPOD());
}
Aber nun faellt mir gar nicht mehr ein, warum man denn nicht Objekte via
memmove verschieben kann. Kann jmd dies an einem kleinen Bsp erklaeren?
RAII (Resource Allocation Is Initialization) kann's ja nicht sein, da
die Destruktoren auf jeden Fall aufgerufen werden...
Ali
PS Die Probleme beim Kopieren sind mir bekannt, ebenso Probleme bei
Objekten, die Pointer auf eigene Datenmember halten (wo ich aber auch
noch nie ein ueberzeugendes Bsp gesehen habe).
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Ludwig Pumberger Guest
|
Posted: Wed Apr 14, 2004 8:13 am Post subject: Re: Verschieben von Objects und PODs |
|
|
Albrecht Fritzsche schrieb:
| Quote: | Aber nun faellt mir gar nicht mehr ein, warum man denn nicht Objekte via
memmove verschieben kann. Kann jmd dies an einem kleinen Bsp erklaeren?
|
Bei nicht-PODs darf der Compiler Dinge anlegen von denen du nichts weisst
und die bei memmove Probleme machen _können_. Es wird in der Praxis häufig
so sein dass es keine Probleme gibt, aber bereits bei der nächsten
Compilerversion, oder auch nur beim nächsten Vollmond kann das anders sein.
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Stefan Reuther Guest
|
Posted: Wed Apr 14, 2004 9:42 am Post subject: Re: Verschieben von Objects und PODs |
|
|
Albrecht Fritzsche wrote:
| Quote: | Ok, ich hab' mir nun "Verschiebe"funktionen der Art (die _move()
Varianten sind sozusagen private, ein Implementierungsdetail)
[...]
Aber nun faellt mir gar nicht mehr ein, warum man denn nicht Objekte via
memmove verschieben kann.
|
Damit könnte ein Objekt mittendrin seine Adresse ändern, ohne davon was
mitzubekommen. Das darf nicht sein.
| Quote: | Kann jmd dies an einem kleinen Bsp erklaeren?
RAII (Resource Allocation Is Initialization) kann's ja nicht sein, da
die Destruktoren auf jeden Fall aufgerufen werden...
|
Was ist mit Zeigern von außen auf das Objekt? In einem Windows-Programm
könnte man z.B. sowas finden:
class Window {
// Diese Funktion wird als Window-Callback beim OS
// angemeldet
static BOOL CALLBACK dialogProc(HWND hwnd, UINT umsg,
WPARAM wparam, LPARAM lparam)
{
Window* w = (Window*) GetWindowLong(hwnd, GWL_USERDATA);
if (umsg == WM_COMMAND)
return w->handleCommand(LOWORD(wparam),
HIWORD(wparam));
else if (umsg == WM_SIZE)
...
else
return false;
}
HWND hwnd;
public:
virtual bool handleCommand(int command, int notify)
{ return false; }
Window(int res_id)
{
hwnd = CreateWindow(...);
SetWindowLong(hwnd, GWL_USERDATA, (LONG) this);
}
virtual ~Window()
{ DestroyWindow(hwnd); }
};
(in leicht abgewandelter Form hab ich das in meinem letzten größeren
Windows-Programm).
Der this-Zeiger eines Objektes wird also beim Betriebs^WWindowing-
System abgelegt, damit Callbacks dem korrekten Objekt zugeordnet werden
können. Wenn nun jemand ein Objekt verschiebt, kann diese Anmeldung
nicht geändert werden.
Stefan
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Markus Breuer Guest
|
Posted: Wed Apr 14, 2004 10:07 am Post subject: Re: Verschieben von Objects und PODs |
|
|
| Quote: | Aber nun faellt mir gar nicht mehr ein, warum man denn nicht Objekte via
memmove verschieben kann. Kann jmd dies an einem kleinen Bsp erklaeren?
RAII (Resource Allocation Is Initialization) kann's ja nicht sein, da
die Destruktoren auf jeden Fall aufgerufen werden...
Ali
PS Die Probleme beim Kopieren sind mir bekannt, ebenso Probleme bei
Objekten, die Pointer auf eigene Datenmember halten (wo ich aber auch
noch nie ein ueberzeugendes Bsp gesehen habe).
|
Compiler-spezifisch kann die Implementierung von virtuellen Methoden
sein, stell dir hier einmal absolute Pointer vor. Indem du das Objekt
verschiebst, passt du den Pointer nicht entsprechend an. Dann denke mal
an Optimierungen, der Compiler hat sich den Pointer gemerkt, du
verschiebst das Objekt aber heimlich.
Für deinen Zweck solltest du placment new/delete verwenden. Wenn etwas
reorganisiert werden muss, dann erledigt der Compiler das an dieser
Stelle. Andernfalls bleibt es nur im Code ein Methoden-Aufruf, zur
Laufzeit passiert nichts.
Gruß Markus
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Heinz Saathoff Guest
|
Posted: Wed Apr 14, 2004 4:15 pm Post subject: Re: Verschieben von Objects und PODs |
|
|
Moin,
Stefan Reuther schrieb...
| Quote: | Albrecht Fritzsche wrote:
Aber nun faellt mir gar nicht mehr ein, warum man denn nicht Objekte via
memmove verschieben kann.
Damit könnte ein Objekt mittendrin seine Adresse ändern, ohne davon was
mitzubekommen. Das darf nicht sein.
|
Das ist dann aber eine Einschränkung für Memberfunktionen des
verschobenen Objektes. Wenn das Verschieben 'von außen' durchgeführt
wird, ist's doch so wie bei PODs.
| Quote: | Was ist mit Zeigern von außen auf das Objekt? In einem Windows-Programm
könnte man z.B. sowas finden:
[snip]
|
Das gilt aber genauso für PODs. Sobald eine Adresse irgendwo registriert
wird, muß sie gültig sein, bis sie deregistriert wird.
- Heinz
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Heinz Saathoff Guest
|
Posted: Wed Apr 14, 2004 4:15 pm Post subject: Re: Verschieben von Objects und PODs |
|
|
Markus Breuer schrieb...
| Quote: | Compiler-spezifisch kann die Implementierung von virtuellen Methoden
sein, stell dir hier einmal absolute Pointer vor. Indem du das Objekt
verschiebst, passt du den Pointer nicht entsprechend an.
|
Wüsste zwar nicht, wo man dort absolute Pointer innerhalb des
Datenspeichers des Objektes braucht, aber warum nicht?
| Quote: | Dann denke mal
an Optimierungen, der Compiler hat sich den Pointer gemerkt, du
verschiebst das Objekt aber heimlich.
|
ich bin mir jetzt nicht sicher, ob der Standard da was über die in C
übliche Aliasproblematik aussagt. In C ist es ja so, daß im Beispiel
XYZ *var;
void Func(XYZ *a);
int main() {
/*var initialisieren*/
Func(var); /*1*/
Func(var); /*2*/
return 0;
}
der Compiler bei 2 nicht davon ausgehen kann, daß var den selben Wert
wie bei 1 hat. Er muß also zwischendurch var neu laden.
Soweit ich weiß, gilt dies bei C++ auch. Damit sind einige
Optimierungsmöglichkeiten mit Adresse merken schon nicht möglich.
Aber auch, wenn mir kein Beispiel einfällt, wo sich non-PODs anders
verhalten, muß das nicht heißen, daß es nicht doch eins gibt.
- Heinz
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Karl Heinz Buchegger Guest
|
Posted: Wed Apr 14, 2004 4:21 pm Post subject: Re: Verschieben von Objects und PODs |
|
|
Albrecht Fritzsche wrote:
| Quote: |
Aber nun faellt mir gar nicht mehr ein, warum man denn nicht Objekte via
memmove verschieben kann.
|
Weil Du nicht weist wieviele Bytes Du denn im Speicher bewegen musst.
sizeof liefert Dir naemlich nicht unbedingt alles was ein Objekt
im Speicher ausmacht. zB.: Meist speichert sich der Compiler den
VTable Pointer (so er einen benutzt) vor dem eigentlichen Objekt ab.
--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Rolf Magnus Guest
|
Posted: Wed Apr 14, 2004 5:34 pm Post subject: Re: Verschieben von Objects und PODs |
|
|
Karl Heinz Buchegger wrote:
| Quote: | Albrecht Fritzsche wrote:
Aber nun faellt mir gar nicht mehr ein, warum man denn nicht Objekte
via memmove verschieben kann.
Weil Du nicht weist wieviele Bytes Du denn im Speicher bewegen musst.
sizeof liefert Dir naemlich nicht unbedingt alles was ein Objekt
im Speicher ausmacht. zB.: Meist speichert sich der Compiler den
VTable Pointer (so er einen benutzt) vor dem eigentlichen Objekt ab.
|
Der wird doch im Objekt gespeichtert und nicht davor, und wird bei
sizeof auch berücksichtig. Sonst könnte man aus solchen Objekten keine
Arrays erzeugen.
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Stefan Reuther Guest
|
Posted: Wed Apr 14, 2004 9:19 pm Post subject: Re: Verschieben von Objects und PODs |
|
|
Heinz Saathoff wrote:
| Quote: | Stefan Reuther schrieb...
Albrecht Fritzsche wrote:
Aber nun faellt mir gar nicht mehr ein, warum man denn nicht Objekte via
memmove verschieben kann.
Damit könnte ein Objekt mittendrin seine Adresse ändern, ohne davon was
mitzubekommen. Das darf nicht sein.
Das ist dann aber eine Einschränkung für Memberfunktionen des
verschobenen Objektes. Wenn das Verschieben 'von außen' durchgeführt
wird, ist's doch so wie bei PODs.
|
Okay, ich hab nicht zuende geschrieben. Ich bin davon ausgegangen, dass
wir ein fertiges non-POD irgendwoher bekommen und uns nun wundern 'warum
darf ich das Ding nicht memmoven?'.
Wenn ich ein non-POD habe, hat das Konstruktoren, und der Compiler
garantiert mir als Implementierer, dass ich so ein Ding nicht erzeuge,
ohne einen Konstruktor durchlaufen zu haben. Wenn ich als Benutzer es
mit memmove verschiebe, verletze ich diese Garantie.
Freilich, in der Praxis dürfte kaum ein Compiler bei einer
selbstgeschriebenen Klasse wie dieser
struct foo {
int i;
foo(int i) : i(i) { }
};
mit memmove Mucken machen. Er darf aber, theoretisch, die Annahme 'jedes
Objekt wird durch einen Konstruktor erzeugt' ausnutzen. Ich wüsste
allerdings nichts praktisches, wo es das was bringt (RTTI:
'typeid(x).num_active_instances()'?)
Stefan
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Uwe Schnitker Guest
|
Posted: Thu Apr 15, 2004 6:17 am Post subject: Re: Verschieben von Objects und PODs |
|
|
Heinz Saathoff <hsaat (AT) despammed (DOT) com> wrote
| Quote: | Moin,
Stefan Reuther schrieb...
Albrecht Fritzsche wrote:
Aber nun faellt mir gar nicht mehr ein, warum man denn nicht Objekte via
memmove verschieben kann.
Damit könnte ein Objekt mittendrin seine Adresse ändern, ohne davon was
mitzubekommen. Das darf nicht sein.
Das ist dann aber eine Einschränkung für Memberfunktionen des
verschobenen Objektes. Wenn das Verschieben 'von außen' durchgeführt
wird, ist's doch so wie bei PODs.
Was ist mit Zeigern von außen auf das Objekt? In einem Windows-Programm
könnte man z.B. sowas finden:
[snip]
Das gilt aber genauso für PODs. Sobald eine Adresse irgendwo registriert
wird, muß sie gültig sein, bis sie deregistriert wird.
|
Wenn diese Registrierung vom User vorgenommen wird, besteht wohl kein
Unterschied zwischen POD und nicht-POD.
Andererseits könnte bei nicht-PODs das System eine unsichtbare Registrierung
vornehmen. Theoretisch denkbar wäre z.B. eine Implementierung des Stack
Unwindings bei Exceptions mittels eines Pointer-Stacks auf gegebenenfalls
zu zerstörende Objekte.
Uwe
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Uwe Schnitker Guest
|
Posted: Thu Apr 15, 2004 6:29 am Post subject: Re: Verschieben von Objects und PODs |
|
|
Stefan Reuther <stefan.news (AT) arcor (DOT) de> wrote
| Quote: | Heinz Saathoff wrote:
Stefan Reuther schrieb...
Albrecht Fritzsche wrote:
Aber nun faellt mir gar nicht mehr ein, warum man denn nicht Objekte via
memmove verschieben kann.
Damit könnte ein Objekt mittendrin seine Adresse ändern, ohne davon was
mitzubekommen. Das darf nicht sein.
Das ist dann aber eine Einschränkung für Memberfunktionen des
verschobenen Objektes. Wenn das Verschieben 'von außen' durchgeführt
wird, ist's doch so wie bei PODs.
Okay, ich hab nicht zuende geschrieben. Ich bin davon ausgegangen, dass
wir ein fertiges non-POD irgendwoher bekommen und uns nun wundern 'warum
darf ich das Ding nicht memmoven?'.
Wenn ich ein non-POD habe, hat das Konstruktoren, und der Compiler
garantiert mir als Implementierer, dass ich so ein Ding nicht erzeuge,
ohne einen Konstruktor durchlaufen zu haben. Wenn ich als Benutzer es
mit memmove verschiebe, verletze ich diese Garantie.
Freilich, in der Praxis dürfte kaum ein Compiler bei einer
selbstgeschriebenen Klasse wie dieser
struct foo {
int i;
foo(int i) : i(i) { }
};
mit memmove Mucken machen. Er darf aber, theoretisch, die Annahme 'jedes
Objekt wird durch einen Konstruktor erzeugt' ausnutzen. Ich wüsste
allerdings nichts praktisches, wo es das was bringt (RTTI:
'typeid(x).num_active_instances()'?)
|
Der Compiler darf auch zusätzliche Informationen in den Objekten speichern
und etwa bei der Destruktion verwenden. Z.B. könnte der Compiler bei mit
new erzeugten Objekten eine Id des verwendeten Memory Managers einfügen
und diese beim delete dann auswerten. So hätte z.B. Microsoft im Prinzip
die Probleme bei der Verwendung von dlls mit nichtkonsistent gewählten
Runtime-Libraries vernmeiden können, allerding nur für nicht-PODs, was
natürlich eine sehr fragile Lösung gewesen wäre.
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Heinz Saathoff Guest
|
Posted: Thu Apr 15, 2004 7:00 am Post subject: Re: Verschieben von Objects und PODs |
|
|
Albrecht Fritzsche schrieb...
| Quote: | Aber nun faellt mir gar nicht mehr ein, warum man denn nicht Objekte via
memmove verschieben kann. Kann jmd dies an einem kleinen Bsp erklaeren?
RAII (Resource Allocation Is Initialization) kann's ja nicht sein, da
die Destruktoren auf jeden Fall aufgerufen werden...
|
Ich hab jetzt doch noch einige Probleme gefunden. Was ist z.B. mit
folgendem Code:
XYZ *p = new XYZ;
XYZ *moved = reinterpret_cast<XYZ*>( new char[sizeof XYZ] );
_move(p, moved, 1);
// wie kann jetzt der Speicher von p wieder freigegeben werden
// darf ich einfach
delete reinterpret_cast<char *>(p);
// schreiben?
Auch hier gibt's Probleme:
void Foo() {
XYZ p;
XYZ *moved = reinterpret_cast<XYZ*>( new char[sizeof XYZ] );
_move(&p, moved, 1);
// hier dard dann kein
delete moved;
//stehen, da sonst 2 Destruktoren ausgeführt werden. Also
delete reinterpret_cast<char *>(moved);
// schreiben?
}
Und dies geht dann überhaupt nicht:
void Foo() {
XYZ p;
XYZ moved;
_move(&p, &moved, 1);
// 2 Destruktoren automatisch ausgeführt
}
All diese Probleme hat man mit PODs nicht, weil hier keine automatischen
Konstruktoren/Destruktoren aufgerufen werden.
- Heinz
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Albrecht Fritzsche Guest
|
Posted: Thu Apr 15, 2004 7:15 am Post subject: Re: Verschieben von Objects und PODs |
|
|
Stefan Reuther wrote:
| Quote: | Damit könnte ein Objekt mittendrin seine Adresse ändern, ohne davon was
mitzubekommen. Das darf nicht sein.
|
Aber warum nicht?
| Quote: | Kann jmd dies an einem kleinen Bsp erklaeren?
RAII (Resource Allocation Is Initialization) kann's ja nicht sein, da
die Destruktoren auf jeden Fall aufgerufen werden...
Was ist mit Zeigern von außen auf das Objekt?
|
Dies ist kein Argument fuer mich, ein std::vector gibt Dir auch nicht
diese Garantie.
Ali
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Heinz Saathoff Guest
|
Posted: Thu Apr 15, 2004 7:17 am Post subject: Re: Verschieben von Objects und PODs |
|
|
Stefan Reuther schrieb...
| Quote: | Wenn ich ein non-POD habe, hat das Konstruktoren, und der Compiler
garantiert mir als Implementierer, dass ich so ein Ding nicht erzeuge,
ohne einen Konstruktor durchlaufen zu haben. Wenn ich als Benutzer es
mit memmove verschiebe, verletze ich diese Garantie.
|
Sowas in der Art habe ich mir nach einigem Nachdenken auch überlegt. Man
macht etwas 'am Compiler vorbei', was dann schiefgehen kann, wenn man
nicht aufpaßt. PODs sind halt nur 'reiner Speicher', den C++ genauso wie
C behandelt.
- Heinz
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
Albrecht Fritzsche Guest
|
Posted: Thu Apr 15, 2004 7:25 am Post subject: Re: Verschieben von Objects und PODs |
|
|
Markus Breuer wrote:
| Quote: | Compiler-spezifisch kann die Implementierung von virtuellen Methoden
sein, stell dir hier einmal absolute Pointer vor. Indem du das Objekt
verschiebst, passt du den Pointer nicht entsprechend an. Dann denke mal
an Optimierungen, der Compiler hat sich den Pointer gemerkt, du
verschiebst das Objekt aber heimlich.
|
Hm ja - das wuerde sicherlich zu Problemen fuehren. Ich kann aber kaum
glauben, dass ein Optimizer so etwas versucht, zu machen. Aber egal, ich
verstehe nun, wo ueberall Probleme auftauchen koennen.
| Quote: |
Für deinen Zweck solltest du placment new/delete verwenden.
|
Daher habe ich ja die Traits - fuer PODs wird memmove, fuer die Objekte
Kopieren (bzw Initialisieren/Zerstoeren) verwendet.
Ali
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|