Autor Beitrag
LittleBen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 258
Erhaltene Danke: 4

Win 7, Mac OS
Delphi 7
BeitragVerfasst: So 29.12.13 18:56 
Hallo zusammen,
klar, const benutzt man, wenn der übergebene Wert nicht verändert werden darf, eben konstant bleiben soll. Jetzt habe ich mir gerade mal die ganzen Methoden in einem etwas größeren Projekt von mir angeschaut und festgestellt, dass man 90% aller Parameter konstant machen könnte.
Jetzt die Frage: Macht es wirkich Sinn, jeden Parameter, der nur gelesen wird, als const zu deklarieren?
Bin mal auf eure Antworten gespannt...

Viele Grüße
Benny
GuaAck
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 378
Erhaltene Danke: 32

Windows 8.1
Delphi 10.4 Comm. Edition
BeitragVerfasst: So 29.12.13 19:07 
Hallo,

bei Const wird der Wert auf den Stack geschoben, die aufgerufen Methode kann dann nur diese Kopie verändern, das Original bleibt erhalten.

Bei VAR wird nur die Adresse der Variablen (Pointer) auf den Stack geschoben, es kann also das Original verändert werden.

Fazit: Bei größeren Strukturen ist die Übergabe als VAR etwas schneller, allerdings würde ich diesen Vorteil nur bei großen Strukturen und häufigen Aufrufen dem Nachteil opfern, dass das Programm unübersichtlicher wird.

Sonderfälle kann es bei Strings und dynamischen Feldern geben, diese sind ja eigentlich nur Pointer, ich bin mir nicht sicher was da passiert.

Gruß
GuaAck
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: So 29.12.13 19:20 
Hallo,

Nur zur Klarstellung.
const sowie var vor einem Parameter, sorgen für die Übergabe eines Pointers auf die Daten.
Es gibt aber Parameter, die immer als Zeiger übergeben werden Opjekte, dynamische Array, ansi/unicodestring
Bei const meckert der Compiler aber bei Zuweisungen auf diesen Parameter.( rechts vom ":=" )
Es ist also sinnig, wenn man sicherer ( sicher ist man nicht immer ) vor nicht beabsichtigten Veränderungen sein will.

Gruß Horst
GuaAck
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 378
Erhaltene Danke: 32

Windows 8.1
Delphi 10.4 Comm. Edition
BeitragVerfasst: So 29.12.13 20:13 
Entschuldigung,
Horst_H hat natürlich Recht:

VAR und CONST übergeben die Adresse (Pointer), ohne eines von beiden wird der Wert übergeben, so dass eine Kopie angelegt wird, die man innerhalb der Methode verändern kann.

Aber ansonsten stimmt es: VAR nur da benutzen, wo das aufrufende Programm eine Veränderung erwartet oder erlaubt.

Gruß
GuaAck
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 29.12.13 20:29 
user profile iconHorst_H hat folgendes geschrieben Zum zitierten Posting springen:
const sowie var vor einem Parameter, sorgen für die Übergabe eines Pointers auf die Daten.
Nur bei komplexeren Datentypen. Ein Wert wie ein Integer, der in ein Register passt, wird bei const auch als solcher übergeben. Das lässt sich auch leicht zeigen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure Test1(const A: Integer); begin end;
procedure Test2(var A: Integer); begin end;
procedure Test3(A: Integer); begin end;
procedure Test;
var
  a: Integer;
begin
  a := 3;
  Test1(a);
  Test2(a);
  Test3(a);
end;
Daraus wird:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
Unit37.pas.32: a := 3;
005B469C C745FC03000000   mov [ebp-$04],$00000003
Unit37.pas.33: Test1(a);
005B46A3 8B45FC           mov eax,[ebp-$04]
005B46A6 E8C9FFFFFF       call Test1
Unit37.pas.34: Test2(a);
005B46AB 8D45FC           lea eax,[ebp-$04]
005B46AE E8CDFFFFFF       call Test2
Unit37.pas.35: Test3(a);
005B46B3 8B45FC           mov eax,[ebp-$04]
005B46B6 E8D1FFFFFF       call Test3
Unit37.pas.36end;
005B46BB 59               pop ecx


user profile iconHorst_H hat folgendes geschrieben Zum zitierten Posting springen:
Bei const meckert der Compiler aber bei Zuweisungen auf diesen Parameter.( rechts vom ":=" )
Es ist also sinnig, wenn man sicherer ( sicher ist man nicht immer ) vor nicht beabsichtigten Veränderungen sein will.
Wobei man dazu sagen sollte, dass diese Zuweisungen nur innerhalb der aufgerufenen Methode sichtbar sind. Sprich es wird nicht der ursprüngliche Wert verändert. Bei einem Pointer kann man aber natürlich auch die Werte dahinter verändern, aber dagegen hilft const auch nicht.

Heißt:
Bei einfachen Datentypen, auch bei Pointern, bringt const keinen echten Unterschied. Man verhindert damit aber, dass jemand versehentlich einen Parameter in der aufgerufenen Methode verändert und dadurch unsauberer Code entsteht. Deshalb macht es durchaus Sinn const generell zu verwenden.
Bei strukturierten Datentypen und z.B. Strings kommt wie schon erwähnt dazu, dass der Compiler den generierten Code optimieren kann, da er weiß, dass in der aufgerufenen Methode keine Änderungen stattfinden und daher keine Kopie benötigt wird.

Es gibt also keinen echten Nachteil, aber teils deutliche Vorteile.