![]() |
Warum kennt Delphi eigentlich keine Makros?
Warum kennt Delphi eigentlich immernoch keine Makros? :gruebel:
Vorallem beim Übersetzen von C-Headern wäre sowas einfach zu praktisch. So schwer sollte das doch nicht zu implementieren sein? Und es, bezüglich der Delphi-Language, kompatibel zu implementieren ist och nicht unmöglich.
Delphi-Quellcode:
Der Compiler braucht das doch nur beim Parsen im Code zu ersetzen und danach zu interpretieren.
{$DEFINEMACRO param '; xyz: Integer'}
{$DEFINEMACRO param_x ', xyz'} {$DEFINEMACRO say 'Beep; ShowMessage(''Hello %1'');' string} {$DEFINEMACRO msg '(''%3'' + Format('' %%s %%d'', [''%1'', %2]))' string integer string} procedure Test(abc: string {$MACRO param}); // procedure Test(abc: string ; xyz: Integer); begin {$IFMACRO param} ShowMessage(IntToStr(xyz)); {$ENDIF} OtherProc(abc {$MACRO param_x}); {$MACRO param 'World'} // Beep; ShowMessage('Hello World'); ShowMessage{$MACRO msg 'World' 123 'Hello'}; // ShowMessage('Hello' + Format(' %%s %%d', ['World', 123])); end; Natürlich sollte er alle Zeilenumbrüche in den Macros ignorieren (durch Leerzeichen zu ersetzen) ... dann dürfte auch der Debugger keine Probleme bekommen, da sich die Zeilenpositionen nicht verändern. Voll blöd, daß man immernoch nicht wieder selber einen Precompiler reinhängen kann, um das selbst zu implementieren. :cry: |
AW: Warum kennt Delphi eigentlich keine Makros?
Der Free Pascal Compiler kennt Makros in einfacher Form:
Delphi-Quellcode:
Bloss Parameter sind noch nicht unterstuetzt. Aber parametrisierte Makros sind doch quasi nichts gross anderes als Inline-Routinen.
{$macros on}
{$define blabla:=tudiesunddas(xyz);undnochwas();xyz:=123} ... blabla; // tudiesunddas(xyz);undnochwas();xyz:=123; |
AW: Warum kennt Delphi eigentlich keine Makros?
Indirekt kann man sowas wie unparametrisierte Makros schon verwenden.
Es ist nur etwas umständlich/häßlich/unübersichtlich/unpraktisch. Zitat:
Zitat:
Delphi-Quellcode:
Die selbe Technik, nur eben mit einer anderen Quelle und etwas mit Parameter aufgemotzt, wäre nötig.
{$DEFINE XYZ_PARAMS}
procedure Test(abc: string {$I paramdef}); begin OtherProc(abc {$I param}); Länger(abc {$INCLUDE param}); end; (statt von Datei, aus einer Liste, welche über die DEFINEMACRO-Dinger befüllt wird) |
AW: Warum kennt Delphi eigentlich keine Makros?
Also ich persönlich finde es schon in C++ schrecklich unübersichtlich. Ich hoffe, dass das niemals in Delphi kommt...
|
AW: Warum kennt Delphi eigentlich keine Makros?
Schließe mich jaenicke an und erhöhe um ein gepflegtes: "wozu soll das gut sein?"
Sherlock |
AW: Warum kennt Delphi eigentlich keine Makros?
Um Delphicode ähnlich unleserlich zu machen wie C++-Code. :stupid:
|
AW: Warum kennt Delphi eigentlich keine Makros?
Zitat:
Aber als "erkennbarer" Compiler-Befehl find ich es doch ganz OK. Zitat:
Ich find es leider nicht, aber ich hatte hier dieses/letzt Jahr doch mal einen Einzeiler gepostet, welcher ein "step" in die Forschleife baut. Schön mit Gernics und Anonymen verschnuddelt ... ihr kennt doch diese einzeiligen C-Codes, wo tausende Rechenoperationen "verschlüsselt" sind. Es geht mir halt um eine Headerübersetzung. Diese wird in Zukunft öfters mal angepaßt werden müssen und da fände ich es praktisch, daß es halbwegs wie im Original aussieht. Ich hab es jetzt erstmal mit den Include-Dateien gelöst, aber leider kann Delphi nachwievor nicht ordentlich damit arbeiten. Debuggen ist grausam und bei Fehlern muß man erstml umständlich suchen, weil bei einem Fehler in der IncludeDatei, bzw. wenn der Fehler eigentlich in der PAS beginnt, aber in der INC aufrtitt, dann zeigt der Debugger, aber vorallem der Compiler nicht an, aus welcher Datei der Aufruf (die Einbindung) kam. |
AW: Warum kennt Delphi eigentlich keine Makros?
Dein Beispiel mit den Macro-Schaltern finde ich auch eher verwirrend (aber auf sowas stehst Du ja immer :mrgreen:).
Deine Problemschilderung mit den Includes kann ich aber gut nachvollziehen und verzichte deswegen meist darauf. Alternativ zu Macros (wie ich das verstanden habe) würde ich mir andere Lösungen wünschen: Eine Überarbeitung des Quelltexteditors wäre in dem Zusammanhang nochmal überdenkenswert. Wir hatten das schon mal angesprochen in Bezug auf mehrere Editorfenster... Grundsätzlich wäre es nett, wenn eine Unit nicht generell stur komplett im Editor stehen würde, sondern die einzelnen Klassen, Funktionen und Methoden (auf Wunsch) in eigenen Editoren bearbeitet werden könnten. Wenn ich eine Funktion ausfülle, dann brauche ich ja nicht die gesamte Unit im Editor sehen, sondern lediglich die Bereiche, auf die ich von der aktuellen Stelle aus zugreifen kann. Also ich würde gern im Interface-Teil eine Funktion definieren und das Ausfüllen dann (z.B. nach Doppelklick) optional in einem eigenen Editor erledigen. Darüber hinaus könnte auch ein Include-Code real im Code eingebunden und dargestellt werden (vielleicht farbig hinterlegt) und Änderungen würden (automatisch im Hintergrund in die externe Datei gespeichert und) in allen anderen Units übernommen, wenn man zu einer solchen wechselt. Ich könnte mir da ein paar hilfreiche Dinge vorstellen. Ob Emba sich aber die Zeit für solchen Kleinkram nimmt... Das Beispiel ![]() |
AW: Warum kennt Delphi eigentlich keine Makros?
Zitat:
Das ist dann fast so schlimm wie bei Delphi 7 und früher... :shock: |
AW: Warum kennt Delphi eigentlich keine Makros?
Du könntest die Klassen auch in Regionen packen und dann nur die jeweils "richtige" eingeblendet lassen
|
AW: Warum kennt Delphi eigentlich keine Makros?
Zitat:
|
AW: Warum kennt Delphi eigentlich keine Makros?
Es gibt ja auch Lisp-Programmierer, die sind richtig hardcore drauf, denn Makros werden in Lisp selbst in der Programmiersprache Lisp programmiert.
Das wäre ungefähr so wie wenn der Sourcecode zuerst mit einem Pascal-Interpreter verarbeitet wird, bevor der Compiler ran darf. Hier mal als kleine verrückte Idee. Alles was zwischen #beginmacro und #endmacro liegt sind Anweisungen an den Pascal-Interpreter:
Delphi-Quellcode:
Aber man muss zugeben: Lisp ist irgendwie besser für Makros geeignet als Pascal/Delphi.
#beginmacro
function Forever():string; // neues Makro begin result := 'while(True) do'; end; function Sondersoftware(veriante:integer):string; begin case veriante of 1: result := 'x * x / 2.0'; 2: result := '(x * x / 2.0) + 0.0001'; else raise Exception.Create('ungültige veriante von #Sondersoftware()'); // erzeugt Compilerfehler end; end; function RepeatInline(const Befehl:string; Anzahl:Integer):string; begin result := ''; while (Anzahl > 0) do Result := Result + Befehl + ';'+#13#10; end; #endmacro // Beispiel RepeatInline('ShowMessage(''Hello World'')', 5); |
AW: Warum kennt Delphi eigentlich keine Makros?
Nja, aus der WinAPI kennt man auch makros, welche eigentlich mehr funktionen sind, außer daß sie quasi im Compiler ausgeführt aufgelöst werden.
Bei ErrorCodes oder z.B. bei dem Wert für IOCTL_IDE_PASS_THROUGH. In Delphi ist sowas einfach nicht möglich.
Code:
Als Funktion kann man es nicht für Konstanten verwenden:
#define CTL_CODE(DeviceType, Function, Method, Access) (
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) ) # define IOCTL_ATA_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x040B, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
Delphi-Quellcode:
Oder man macht es so, bzw. rechnet den Wert gleich aus.
function CTL_CODE(DeviceType, _Function, Method, Access: Cardinal): Cardinal;
begin Result := (DeviceType shl 16) or (Access Shl 14) or (_Function shl 2) or (Method); end; Flag:=CTL_CODE(IOCTL_SCSI_BASE, $040B , METHOD_BUFFERED, (FILE_READ_ACCESS or FILE_WRITE_ACCESS));
Delphi-Quellcode:
Nahezu alle Header lassen sich nach C und Co. übersetzen ... nur Andersrum geht es meistens nicht.
const
IOCTL_ATA_PASS_THROUGH= (IOCTL_SCSI_BASE shl 16) or ((FILE_READ_ACCESS or FILE_WRITE_ACCESS) shl 14) or ($040B shl 2) or (METHOD_BUFFERED); |
AW: Warum kennt Delphi eigentlich keine Makros?
Macros sind normalerweise der Tod von richtig gutem Tools support (á la Resharper oder IntelliJ).
Es macht IMO mehr Sinn pure & deterministische Funktionen einzuführen. Also Funktionen ohne Nebeneffekte, die bei gleichem Input den gleichen Output liefern. Dann kann der Compiler sowas für Release builds auflösen. Und nebenbei ist sowas sehr beruhigend wenn man sehr viel Threading nutzt. Macros sind IMO eine kurzsichtige, billige Lösung, die einem langfristig die Sprache versauen. |
AW: Warum kennt Delphi eigentlich keine Makros?
Delphi is ja angeblich eh schon tot ... da kommt's darauf nun och nimmer an. :roll:
|
AW: Warum kennt Delphi eigentlich keine Makros?
Zitat:
|
AW: Warum kennt Delphi eigentlich keine Makros?
Zitat:
|
AW: Warum kennt Delphi eigentlich keine Makros?
Jain.
Erstmal dreht dann der Debugger durch und dann würde man das Makro dann direkt im QuellCode ändern (nicht nur wirklich "temporär", im Hintergrund, beim Kompilieren) und wenn dabei was schief geht, dann steht der Quellcode danach schief. PS: Ich hab 'ne Option aktiv "Speichern beim Kompilieren", falls die IDE abkratzt, damit dann nicht eventuell was weg ist. Tja, dabei würden dann auch die ersetzten Makros gespeichert. Ach ja, im Post-Build müssten die ersetzten Makros wieder zurückgesetzt werden, nur gibt es da das Problem, daß das Post-Build z.B. bei einem Fehler (Compile-Error) nicht ausgeführt wird und dann die Markos ebenfalls noch ersetzt bleiben würden. Fazit: Egal wie man es dreht, irgendwo ist immer alles kaputt (dauerhaft oder gar nur halb Ersetzt). |
AW: Warum kennt Delphi eigentlich keine Makros?
Zitat:
Ich bin übrigens froh, dass FPC nur einfache Makros unterstützt. Was die Leute allein schon damit anstellen (abgesehen von den wenigen nützlichen Punkten). Gruß, Sven |
AW: Warum kennt Delphi eigentlich keine Makros?
Was war nochmal der Vorteil von Makros ggü (inline)Funktionen?
Und wo sind Makros sinnvoll, wenn man die Grundgesetze der OOP-Softwareentwicklung eingehalten hat? Früher hab ich mich auch oft gefragt, wieso das mit den Makros nicht geht. Aber in den letzten 10 Jahren eigentlich nicht mehr. Vermutlich liegt das daran, das ich eingerostete Gedanken habe und mich in ausgetrampelten Pfaden bewege. |
AW: Warum kennt Delphi eigentlich keine Makros?
Zitat:
ein Compile-Projekt mit aufnimmt, jede makroverseuchte Datei des ursprünglichen Projektes bekommt dort ihr Pendant mit gleichem Namen, aber Suffix, z.B. _C, und dann wird in diese _C's expandiert und dieses "expandierte Projekt" schlussendlich compiliert? (OK, ich gebs zu, man muss dann immer eine solche Prj-Gruppe bevorraten, aber das halt ich für machbar wenn man schwer mit Makros arbeiten muss) (wär doch ne schöne Aufgabe für nen GExperts-Button, der das dann alles automat. erledigt ;-) ) |
AW: Warum kennt Delphi eigentlich keine Makros?
Zitat:
|
AW: Warum kennt Delphi eigentlich keine Makros?
Einfache Markos würden mir ja auch reichen, wobei "einfach" bei mir eher nur als "einzeilig" definiert ist, wobei man notfalls auch mehrere Befehle in eine machen könnte und "mehrzeiliges" notfalls als Include-Datei implementiert,
womit der Compiler und vorallem der Debugger problemlos klar kommen sollte. Nja, ich bin aktuell dabei mich nochmal durch die OpenToolsAPI zu kämpfen. Mal sehn, ob dafür eventuell sich doch irgendwie ein unschöner Weg bietet. Aber zuletzt gab es im alten Compiler (bis Delphi 7) mal jemanden, welcher es dort schaffte sich halbwegs ordentlich in den Compile-Vorganz reinzuhacken. PS: Über Markos könnte man eventuell sogar bedingt sowas wie eine Mehrfachvererbung für Klassen realisieren, was man bisher aber auch schon über zwei Includedateien machen könnte. > gleiche Funktionen "nachträglich" in meherere Klassen integrieren, ähnlich den Class.Helpern, nur eben richtig rein, in jeweils eine Klassenableitung. |
AW: Warum kennt Delphi eigentlich keine Makros?
Zitat:
Ich meinte 'Vorteile'. Nicht 'Spielereien' ;-) PS: Mehrfachvererbung von Klassen ist out und gefährlich. |
AW: Warum kennt Delphi eigentlich keine Makros?
Also ich kann da auch beim besten Willen keinen Vorteil entdecken.
|
AW: Warum kennt Delphi eigentlich keine Makros?
Zitat:
|
AW: Warum kennt Delphi eigentlich keine Makros?
Wobei UNLESERLICH nicht für alles gilt.
Die __LINE__ und __FILE__-Makros vom PHP wären eigentlich ganz nett, vorallem für den Code der Fehlerbehandlung und das Logging. Und was das "Mehrfachvererben" ist vielleicht ein zu großes Wort für: Ich hab mehrere Klassen ala TEdit, TButton usw. und mächte denen allen ein zusätzliches "gleiches" Property/Funktion verpassen, wobei man das hier nunmal nicht in einen gemeinsamem Vorfahren reinmachen kann, sondern nur in einen jeweils "gleichartig" erweiterten Nachfahren. Hierbei ist das Makro dann ein an einer Stelle notierter Copy&Paste-Code, den man sonst überall reinkopieren würde. |
AW: Warum kennt Delphi eigentlich keine Makros?
Zitat:
Zitat:
Zitat:
Code:
machen lassen. Ich habe keine passende delphiversion um das auszuprobieren, aber im C# kann man das AFAIR machen.
TControlExtended<TEdit>
|
AW: Warum kennt Delphi eigentlich keine Makros?
Nein, denn in Generics gibt es Einwas, das man nicht generisch machen kann und das ist der Vorfahre, da die Generics ebenfalls immer nur eine Einfachvererbung können.
Das geht nicht und das wäre dafür dann nötig
Delphi-Quellcode:
Sowas geht zwar
type
TMyClass<TVorfahr> = class(TVorfahr) end;
Delphi-Quellcode:
Aber grade in der VCL ist das auch nicht so gut, außer du fängst an nochmal alles z.B. in unsichtbaren TPanels zu kapseln und findest dann alle Property versteckt als Unterproperty in dem Gekapselt, da die Generics Diese nicht alle nach oben durchreichen kann, weil sie ja überall unterschiedlich sind, oder du schreibst die Weiterleitungen wieder manuell überall rein.
type
TMyClass<TAndereClasse> = class private FGekapselt: TAndereClasse; published property Gekapselt: TAndereClasse read FGekapselt; end; |
AW: Warum kennt Delphi eigentlich keine Makros?
Zitat:
Übrigens kann man sich für's Loggen einen Präprozessor schreiben, der geschriebene Aufrufe
Delphi-Quellcode:
in Aufrufe
Log('blabla');
Delphi-Quellcode:
übersetzt bzw. die bereits vorhandenen weiteren Parameter aktualisiert.
Log('blabla', 'u_TestUnit', 234, 'TestFunction');
|
AW: Warum kennt Delphi eigentlich keine Makros?
Die zwei PHP Beispiele sind eher schlecht gewählt, für das Logging bringt das nämlich nicht so wahnsinnig viel. Wir haben das früher immer mitprotokolliert, aber inzwischen verzichten wir darauf. Der Mehrwert ging gegen null, da sich die Log-Meldungen ja sowieso unterscheiden. Und für das Logging im Fehlerfall ist es untauglich, da man dort ja eigentlich eher die Infos aus dem Stack-Trace braucht, also das von wo wurde aufgerufen, weniger das was (denn den Ort kennt man ja aus der Meldung).
Was die VCL angeht: Bei dem Fall wäre ich eher für Class Helper. die auf mehrere Klassen passen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:50 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