![]() |
Compiler ersetzt Variable durch Konstante - AV zur Laufzeit
Eine WinAPI-Methode erwartet einen PWideChar den sie eventuell auch verändern wird. Meine Methode hat dafür eine lokale Variable des Typs. Sieht so aus:
Delphi-Quellcode:
Die Zugriffsverletzung führe ich eindeutig auf einen Schreibversuch auf die Konstante zurück. Der Compiler sieht wohl "He, die Variable ist ja genau das gleiche wie die Konstante" und wird nicht die Variable
const
defaultStrValue: String = 'Das ist ein String'; var myString: String; myWideChar: PWideChar; begin myString := defaultStrValue; myWideChar := PWideChar(myString); WinApiAufruf(myWideChar); // AV end;
Delphi-Quellcode:
sondern die Konstante
myString
Delphi-Quellcode:
casten.
defaultStrValue
Jetzt das kuriose: Ändere ich die myWideChar-Zuweisung mit diesen drei Zeichen ab, läuft alles wunderbar:
Delphi-Quellcode:
Völlig klar: Das Anhängen eines leeren Strings erzeugt einen neuen String der dann nach PWideChar gecastet wird. Und diese Adresse ist schreibbar.
myWideChar := PWideChar(myString+'');
Meine Frage: Ist das hier ein Compilerfehler oder Übereifrige Optimierung? Oder hätte ich glasklar damit rechnen müssen? |
AW: Compiler ersetzt Variable durch Konstante - AV zur Laufzeit
Das ist as-designed. Es wird nur eine Referenz benutzt. Du kannst das aber so machen (ungetestet):
Delphi-Quellcode:
So musst du das auch bei CreateProcess machen, sonst knallt es bei Unicode, wenn du z.B. einen const Parameter an CreateProcess übergibst.
const
defaultStrValue: String = 'Das ist ein String'; var myString: String; myWideChar: PWideChar; begin myString := defaultStrValue; UniqueString(myString); myWideChar := PWideChar(myString); WinApiAufruf(myWideChar); // AV end; |
AW: Compiler ersetzt Variable durch Konstante - AV zur Laufzeit
Ganz genau der Fall (CreateProcess) war es auch ;-)
Ist mir bislang nie aufgefallen da ich die Variable, ausgehend von der Konstante, immer noch einmal verändert hatte. Fazit: Copy on Write für Delphi-Strings. Bei der Zuweisung
Delphi-Quellcode:
hat man natürlich auch erst einmal nur die Adresse der Konstante dort. Muss man aber auch erstmal drauf kommen :roteyes:
variablerString := konstanterString
|
AW: Compiler ersetzt Variable durch Konstante - AV zur Laufzeit
Genau dieser Fall ist aber doch
![]() Zitat:
|
AW: Compiler ersetzt Variable durch Konstante - AV zur Laufzeit
Ja, bei MSDN steht das natürlich auch. Das habe ich schon verstanden, ich hatte nur instinktiv damit gerechnet, dass spätestens beim Cast nach
Delphi-Quellcode:
eine neue Kopie vom String angelegt und diese gecastet würde.
PWideChar
|
AW: Compiler ersetzt Variable durch Konstante - AV zur Laufzeit
Naja,
Zitat:
|
AW: Compiler ersetzt Variable durch Konstante - AV zur Laufzeit
Zitat:
Folgendes Beispiel verdeutlicht das:
Delphi-Quellcode:
funktioniert.
myString := defaultStrValue;
myString[1] := 'W';
Delphi-Quellcode:
funktioniert nicht ohne das UniqueString.
myString := defaultStrValue;
//UniqueString(myString); PChar(myString)^ := 'W'; |
AW: Compiler ersetzt Variable durch Konstante - AV zur Laufzeit
Delphi-Quellcode:
! Großartig, das ist doch um einiges eleganter als einen leeren String irgendwo anzuhängen oder sich selber was zu basteln.
UniqueString
Danke dafür 8-) |
AW: Compiler ersetzt Variable durch Konstante - AV zur Laufzeit
Bei dynamischen Arrays gibt es garkein Copy on Write.
Dort wäre eine Art Äquivalent zum UniqueString das Copy.
Delphi-Quellcode:
var
A, B: array ob Integer; SetLength(A, 1); A[0] := 123; A := Copy(B); // A := B; B := A; B[0] := 456; ShowMessage(IntToStr(A[0]); // 123 und ohne Copy ist es auch 456 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:02 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz