Also ich verwende ausschließlich Beispiel 1, also sowohl den Pointer im Prozedurargument als auch das @ bei der übergabe.
Dein zweites Beispiel hat eine Zuweisung mehr (*blahblah.Whatever = blahblah).
Außerdem fehlt hier ein Protected for "*blahblah.Whatever", um eine Kollision mit einer globalen Variable zu verhinden.
Bei der Übergabe das @ wegzulassen geht, aber verringert die Lesbarkeit des Codes.
Bei MyProcedure2(MyVar2) sieht man nicht sofort, dass MyVar2 als Referenz übergeben wird und sich daher auch ändern könnte.
Die erste Variante ist die effizientere. Man kann von außen auch sehen, welcher Struktur Typ benötigt wird.
Die zweite Variante hat auch die Eigenschaft, daß Du mehr Variablen benötigst und zusätzliche Wert-Zuweisungen durchführst. Dies sind nur 3-4 Operationen mehr per Funktionsaufruf, aber wenn sowas häufig passiert kann sich das sammeln und bei zeitkritischen oder intensiven Rechnungen ist das vielleicht nicht wünschenswert.
Dennoch benutze ich gelegentlich aber selten Variante 2 (oder sowas Ähnliches) wenn die Struktur ebenso ein Interface ist, also ein selbstgebautes "Objekt"; siehe unten im Beispiel bei der foo() Methode Zeile 22. Manchmal geht es auch nur mit Variante 2, wenn gerade verschiedene Strukturen und Datentypen übergeben werden können z.B. bei Konvertierungen wie bei PeekS() etc.
Finde beide Varianten blöd. Bei Variante 1 würde ich erwarten, das mir der Compiler bzw. der Debugger in den Schoß speit, wenn ich ihm eine beliebige Adresse bzw. irgendein Pointer geben würde. Macht er dummerweise aber nicht, da er aus der Adresse nicht direkt ableiten kann, das es sich eben um keinen Pointer einer Struktur handelt. Ein Pointer passt in einen Int. Somit ist es völlig Egal, ob man *blahblah.Whatever oder nur *blahblah nutzt. Der Fehler wird erst in der ersten Zeile der Prozedur geschmissen. Er erkennt erst dann, das die Prozedur eine Struktur sein sollte, aber keine übergeben wurde. Noch bescheidener ist es, wenn man ihm den Pointer irgendeines numerischen Datentyps übergibt. Da schmeißt er keinen Fehler, obwohl er keinen Pointer einer Struktur bekommen hat. Am Ende ist ein Pointer immer ein "Int", weil eine Adresse nun einmal ein ganzzahliger Typ ist und da sehe ich leider einiges an Fehlerpotenzial. Da hilft meiner Meinung nach Variante 1 auch nicht. Das kann zwar wenigstens etwas helfen, wenn der Code schon geschrieben wurde. Hilft aber kaum, wenn man ihn noch schreiben muss. Eine aussagekräftige Fehlermeldung alá "Du Vogel gibst mir die Adresse eines Floats. Brauch aber Pointer des Typs -Whatever-" hingegen schon.
Wenn dieses Verhalten etwas strikter wäre und Strukturen als Übergabeparameter sowie auch als Rückgabe nativ unterstützt werden würden, dann würde sich denke ich mal die Frage garnicht stellen. Dann geht Variante 2 ohne Zeile 1 der Prozedur deutlich geschmeidiger von der Hand und wenn man es dann mit dem Parameter vergeigt, springt einem der Debugger ins Gesicht.
PC: Ryzen 9 3950X | 96 GB RAM | RX6800XT | 2,5 TB NVMe | Linux Mint Notebook: 16" 3:2 | Ryzen 7 5800H | 16 GB RAM | Radeon Vega | 1TB NVMe | Linux Mint NAS: Fritz.Box 5690 Pro (Nur für Keepass-DB) Coding: Purebasic, Spiderbasic, GDevelop, Javascript/Node
Ich bin für Variante 1 mit Angabe der Structure. Aber ohne Prüfung von den Debugger wie von TroaX angedeutet.
Sonst funktioniert Überlagerung von Strukturen nicht mehr wie ich bei Vererbung von Strukturen und Interfaces verwende.