array of const

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Mathias
Beiträge: 6146
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

array of const

Beitrag von Mathias »

In der Unit xlib habe ich folgendes gefunden:

Code: Alles auswählen

function XGetIMValues(para1:PXIM; dotdotdot:array of const):Pchar;cdecl;external libX11;
Da wird eine "array of const" verlangt.
Da wollte ich folgendes deklarieren;

Code: Alles auswählen

  var
    ac:array of const;
Da motzt der Colpiler "Illegal expression"

Das habe ich noch probier, bei

Code: Alles auswählen

XGetIMValues(im, xnq)
den Cursor auf "xng" setzen und [Ctrl+Shft+c] zu drücken.
Dann hüpft er aber in der "xlib" auf folgende Zeile:

Code: Alles auswählen

function XGetIMValues(para1:PXIM; dotdotdot:array of const):Pchar;cdecl;external libX11;
Mit dem Fehler: "xlib.pp(1759,54) Error: Bezeichner erwartet, statt dessen const gefunden"

Wie kann ich dieses Problem lösen ?


Nachtrag:

Code: Alles auswählen

  function test(ac:array of const):Pchar;
  begin
  end;
Aber sowas kompiliert er. :roll:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10461
Registriert: Mo 11. Sep 2006, 19:01

Re: array of const

Beitrag von theo »

Mathias hat geschrieben:
Mi 16. Nov 2022, 17:24
Da wird eine "array of const" verlangt.
Eine FPC Doku gibt es ja durchaus: :wink:
https://www.freepascal.org/docs-html/ref/refsu69.html

PascalDragon
Beiträge: 823
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: array of const

Beitrag von PascalDragon »

Mathias hat geschrieben:
Mi 16. Nov 2022, 17:24
In der Unit xlib habe ich folgendes gefunden:

Code: Alles auswählen

function XGetIMValues(para1:PXIM; dotdotdot:array of const):Pchar;cdecl;external libX11;
Da wird eine "array of const" verlangt.
Im Fall einer externen cdecl Funktion heißt das einfach, dass du beliebige Parameter mit Array-Klammern nutzen kannst:

Code: Alles auswählen

XGetIMValues(im, [a, b, 42, p])
Es gibt aber keinen Typ dafür.
FPC Compiler Entwickler

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1423
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: array of const

Beitrag von fliegermichl »

Das wird ja auch bei Format verwendet.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender : TObject)
begin
 Memo1.Lines.Add(Format('%s %d %.3f', ['Hallo', 14, 1.414]));
end;

Mathias
Beiträge: 6146
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: array of const

Beitrag von Mathias »

Die Funtion von "XGetIMValues" ist in der Xlib.h sowieso etwas merkwürdig.

Code: Alles auswählen

extern char *XGetIMValues(
    XIM /* im */, ...
) _X_SENTINEL(0);
Was bedeuten da die "..." ?
In Pascal ist sie so:

Code: Alles auswählen

function XGetIMValues(para1:PXIM; dotdotdot:array of const):Pchar;cdecl;external libX11;
Da sind 2 Parameter.

Und in einem funktionierendem C-Programm sind es 4 Parameter.

Code: Alles auswählen

#define XNQueryInputStyle "queryInputStyle"
...
   failed_arg = XGetIMValues(im, XNQueryInputStyle, &styles, NULL);


Die Sprache C zu verstehen, ist zwischendurch echt schwer. :roll:

Haben die "..." in C etwa die gleiche Bedeutung wie in Pascal "array of char" ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1423
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: array of const

Beitrag von fliegermichl »

Das ist in C wie die Deklaration array of const und bedeutet, daß hier noch mehr Parameter folgen können.
Deren Anzahl ist nicht begrenzt.

In Pascal ist das nur bei spziellen Prozeduren wie z.B. writeln möglich.

Mathias
Beiträge: 6146
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: array of const

Beitrag von Mathias »

So geht es in Pascal:

Code: Alles auswählen

XGetIMValues(im, [XNQueryInputStyle, @styles, nil]);
Und so in C:

Code: Alles auswählen

XGetIMValues(im, XNQueryInputStyle, &styles, NULL);
Anscheinend braucht C keine [] bei einer offenen Array.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 823
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: array of const

Beitrag von PascalDragon »

Mathias hat geschrieben:
Do 17. Nov 2022, 18:26

Code: Alles auswählen

XGetIMValues(im, XNQueryInputStyle, &styles, NULL);
Anscheinend braucht C keine [] bei einer offenen Array.
Das ist kein offenes Array , sondern eine „variable Argumentliste”. Konzeptionell sind das zwei verschiedene Konzepte: ein offenes Array ist ein einzelner Parameter, während bei einer variablen Argumentliste auch wirklich alles einzeln übergeben wird.

Deswegen habe ich beim array of const das cdecl im Zusammenhang mit external explizit erwähnt, da sich hier der Parameter nicht wie ein Array verhält, sondern eben wie eine variable Argumentliste, auch wenn es als Array deklariert wird. Eine Alternative ist der varargs Modifizierer:

Code: Alles auswählen

function XGetIMValues(para1:PXIM):Pchar;cdecl;varargs;external libX11;
In dem Fall kannst du XGetIMValues wie in C nutzen.
fliegermichl hat geschrieben:
Do 17. Nov 2022, 14:54
In Pascal ist das nur bei spziellen Prozeduren wie z.B. writeln möglich.
Writeln ist ein Intrinsic und keine Prozedur, deswegen folgt es auch nicht den üblichen Begrenzungen bei Prozeduren/Funktionen.
FPC Compiler Entwickler

Mathias
Beiträge: 6146
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: array of const

Beitrag von Mathias »

Eine Alternative ist der varargs Modifizierer:
Ich kann mit vorstellen, da die xlib Unit schon recht alt ist, das da FPC varargs gar noch nicht kannte.
Wäre dies ein Bug-Report wert ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 823
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: array of const

Beitrag von PascalDragon »

Mathias hat geschrieben:
Fr 18. Nov 2022, 08:31
Eine Alternative ist der varargs Modifizierer:
Ich kann mit vorstellen, da die xlib Unit schon recht alt ist, das da FPC varargs gar noch nicht kannte.
Wäre dies ein Bug-Report wert ?
Nein, weil das die Kompatibilität der Unit brechen wurde (Aufruf mit eckigen Klammern vs. ohne).
FPC Compiler Entwickler

Mathias
Beiträge: 6146
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: array of const

Beitrag von Mathias »

Bei folgender function musste ich zwingend eckige Klammer verwende:

Code: Alles auswählen

function XCreateIC(para1:PXIM; dotdotdot:array of const):PXIC;cdecl;external libX11;
Bei GTK2 bin ich auf folgende Funktion gestossen:

Code: Alles auswählen

procedure gtk_dialog_add_buttons(dialog:PGtkDialog; first_button_text:Pgchar; args:array of const); overload; cdecl; external gtklib;
procedure gtk_dialog_add_buttons(dialog:PGtkDialog; first_button_text:Pgchar); cdecl; overload; varargs; external gtklib;
Bei der GTK2 function werden keine eckigen Klammer verlangt.
Ich sehe das "varargs", aber nur in der "overload" function, welche keine "array of const" hat. Aber anscheinend verwendet es diese, obwohl dort nur ein PChar definiert ist.

Dies würde folgender Test beweisen, welcher anstandslos kompiliert wird:

Code: Alles auswählen

program project1;
const
  gtklib = 'libgtk-x11-2.0.so';
  //procedure gtk_dialog_add_buttons(dialog:Pointer; first_button_text:Pchar; args:array of const); overload; cdecl; external gtklib;
  procedure gtk_dialog_add_buttons(dialog: Pointer; first_button_text: PChar); cdecl; overload; varargs; external gtklib;
begin
  gtk_dialog_add_buttons(nil, 'Beenden', 100, 'Abbrechen', 101, 'Speichern', 102, nil);
end.
Anscheinend ist "varargs" eine recht magische Sache.
https://www.freepascal.org/docs-html/ref/refsu97.html
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 823
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: array of const

Beitrag von PascalDragon »

Mathias hat geschrieben:
Di 7. Feb 2023, 15:32
Bei der GTK2 function werden keine eckigen Klammer verlangt.
Ich sehe das "varargs", aber nur in der "overload" function, welche keine "array of const" hat. Aber anscheinend verwendet es diese, obwohl dort nur ein PChar definiert ist.
Bei einer Routine, welche einen array of const-Parameter hat, müssen die Werte mit Hilfe eines Array-Konstruktors übergeben werden, schließlich handelt es sich um einen offenen Array Parameter. Bei einer externen cdecl Routine werden diese Werte dann passend für eine variadische C Routine übergeben.
Bei einer Routine, welche mit varargs markiert ist, werden die Parameter wie in C Code direkt im Aufruf ohne einen offenen Array Konstruktor angegeben und die Parameter passend an die C Routine übergeben.

Hast du zwei überladene Routinen, von denen eine mit array of const und die andere mit varargs markiert ist, heißt das einfach nur, dass du wählen kannst, ob du die Parameter auf die eine oder die andere Weise übergeben möchtest.
Mathias hat geschrieben:
Di 7. Feb 2023, 15:32
Anscheinend ist "varargs" eine recht magische Sache.
https://www.freepascal.org/docs-html/ref/refsu97.html
Die array of const-Variante ist magischer als die varargs-Variante, schließlich ist letzteres das was quasi jeder C Compiler beherrscht, um Funktionen wie printf oder scanf umzusetzen.
FPC Compiler Entwickler

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1423
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: array of const

Beitrag von fliegermichl »

Wenn aber der FPC varargs beherrscht, weshalb stehen diese dem FPC Programmierer nicht zur Verfügung?
Also außer um externe C Routinen aufzurufen.

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: array of const

Beitrag von Socke »

fliegermichl hat geschrieben:
Mi 8. Feb 2023, 06:12
Wenn aber der FPC varargs beherrscht, weshalb stehen diese dem FPC Programmierer nicht zur Verfügung?
Also außer um externe C Routinen aufzurufen.
Ein Beispiel wie das in C genutzt wird findest du hier: https://www.tutorialspoint.com/cprogram ... uments.htm. Die Referenz gibt da ein paar gute Gründe, das Konstrukt nicht zu verwenden:
https://en.cppreference.com/w/c/variadic/va_arg hat geschrieben:If the type of the next argument in ap (after promotions) is not compatible with T, the behavior is undefined, unless:

one type is a signed integer type, the other type is the corresponding unsigned integer type, and the value is representable in both types; or
one type is pointer to void and the other is a pointer to a character type.
Damit hast du zwei Punkte, die ein Pascal Array of Const besser macht:
  • Die Länge des Arrays wird immer korrekt mitgegeben.
  • Es werden Typinformationen der Argumente übergeben.
Letzteres gilt natürlich nur innerhalb von Pascal. Wenn ein Array of Const an eine externe C-Funktion übergeben wird, fallen die Typinformationen natürlich weg (werden in C nicht unterstützt).
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

PascalDragon
Beiträge: 823
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: array of const

Beitrag von PascalDragon »

fliegermichl hat geschrieben:
Mi 8. Feb 2023, 06:12
Wenn aber der FPC varargs beherrscht, weshalb stehen diese dem FPC Programmierer nicht zur Verfügung?
Also außer um externe C Routinen aufzurufen.
Weil die Seite der Implementierung um einiges schwieriger umzusetzen ist. Man braucht zum Beispiel Mechanismen, um auf die Parameter zugreifen zu können (in C und C++ die va_arg und Freunde Funktionen/Makros) und das auch für jede Plattform. Die Möglichkeit solche Funktionen aufzurufen bekommt man im Gegensatz dazu quasi gratis, wenn man die ABI der Plattform implementiert.

Und wie Socke geschrieben hat: array of const ist da um einiges mächtiger und typsicherer. Wir brauchen da nicht noch einen weiteren Mechnismus, den die Leute dann missbrauchen und sich wundern warum was nicht funktioniert.
FPC Compiler Entwickler

Antworten