Doppelter Bezeichner Type/var geht

Für Fehler in Lazarus, um diese von anderen verifizieren zu lassen.
Antworten
Mathias
Beiträge: 7350
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Doppelter Bezeichner Type/var geht

Beitrag von Mathias »

Ich habe gerade dies vor meiner Nase und die proceduren werden anstandslos kompilert.
Darf dies so sein. oder ist das ein Bug ?
Ist es aber ausserhalb der procedure, dann motzt er wie erwartet.

Code: Alles auswählen

program Project1;

  procedure test1(pointer: pointer); // geht
  begin
    pointer := nil;
  end;

  procedure test2(integer: integer); // geht
  begin
    integer := 123;
  end;

var
  Pointer=Pointer; // da motz er

begin
  test1(nil);
  test2(1234);
end.         
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2912
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Doppelter Bezeichner Type/var geht

Beitrag von m.fuchs »

Das hat mit dem Scope zu tun.

Deklarierst du Pointer lokal, dann überschreibt er nicht die globale Typendefinition. Versuchst du es global zu deklarieren, dann gibt es den Pointer-Typ nicht mehr.

Wenn du . eine funktionsfähige - Deklaration vor deine Prozedur schiebst...

Code: Alles auswählen

var
  Pointer: String; // da motz er
Dann wirst du auch bei der lokalen Deklaration einen Fehler kassieren. Der Typ existiert dann nicht mehr.
0118999881999119725-3

Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

siro
Beiträge: 792
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Doppelter Bezeichner Type/var geht

Beitrag von siro »

Hat mich grade neugierig gemacht :wink:

Global und Lokal, beides funktioniert bei mir:

Code: Alles auswählen

var Pointer:String;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Pointer:='Hallo';
  Caption:=Pointer;
end;                   
und auch das geht:

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
var Pointer:String;
begin
  Pointer:='Hallo';
  Caption:=Pointer;
end;            
Lazarus 4.6 (rev lazarus_4_6) FPC 3.2.2 x86_64-win64-win32/win64
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

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

Re: Doppelter Bezeichner Type/var geht

Beitrag von Mathias »

siro hat geschrieben: Sa 5. Sep 2026, 16:33 Hat mich grade neugierig gemacht :wink:

Global und Lokal, beides funktioniert bei mir:

Code: Alles auswählen

var Pointer:String;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Pointer:='Hallo';
  Caption:=Pointer;
end;                   
und auch das geht:

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
var Pointer:String;
begin
  Pointer:='Hallo';
  Caption:=Pointer;
end;            
Lazarus 4.6 (rev lazarus_4_6) FPC 3.2.2 x86_64-win64-win32/win64
Dies hätte mich verwundert wen es nicht gehe würde, du kannst alles nehmen, solange das Wort nicht reserviert ist.

Aber sowas ist echt merkwürdig:

Code: Alles auswählen

procedure test1(pointer: pointer); // geht
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: Doppelter Bezeichner Type/var geht

Beitrag von fliegermichl »

Damit kann man aber einen in den Wahnsinn treiben.

Code: Alles auswählen

Program PtrTest;
var Pointer : string;

procedure ZeigePointer(Ptr : Pointer);
begin
 WriteLn(IntToHex(PtrInt(Ptr), SizeOf(Pointer)*2));
end;

begin
 Pointer := 'Hallo';
 ZeigePointer(@Pointer);
end.
Der Compiler meckert jetzt bei der Deklaration von ZeigePointer mit "Type identifier expected", weil es den Typ Pointer jetzt nicht mehr gibt.

Benutzeravatar
Zvoni
Beiträge: 732
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz/FPC fixes)
CPU-Target: 64Bit
Wohnort: BW

Re: Doppelter Bezeichner Type/var geht

Beitrag von Zvoni »

fliegermichl hat geschrieben: So 6. Sep 2026, 08:57 Damit kann man aber einen in den Wahnsinn treiben.

Code: Alles auswählen

Program PtrTest;
var Pointer : string;

procedure ZeigePointer(Ptr : Pointer);
begin
 WriteLn(IntToHex(PtrInt(Ptr), SizeOf(Pointer)*2));
end;

begin
 Pointer := 'Hallo';
 ZeigePointer(@Pointer);
end.
Der Compiler meckert jetzt bei der Deklaration von ZeigePointer mit "Type identifier expected", weil es den Typ Pointer jetzt nicht mehr gibt.
Das hier wiederum funktioniert:

Code: Alles auswählen

Program PtrTest;
Uses Sysutils;  //Braucht man für IntToHex
var Pointer : string;

procedure ZeigePointer(Ptr : System.Pointer);  //Voll qualifizierter Typ mit Unit-Namen, wo er definiert ist
begin
 WriteLn(IntToHex(PtrInt(Ptr), SizeOf(Pointer)*2));
end;

begin
 Pointer := 'Hallo';
 ZeigePointer(@Pointer);
 Readln;
end.
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2912
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Doppelter Bezeichner Type/var geht

Beitrag von m.fuchs »

Ja, wenn du es komplett qualifiziert angibst geht ja auch das Original:

Code: Alles auswählen

program Project1;

  procedure test1(pointer: pointer); // geht
  begin
    pointer := nil;
  end;

  procedure test2(integer: integer); // geht
  begin
    integer := 123;
  end;

var
  Pointer: System.Pointer; // geht auch

begin
  test1(nil);
  test2(1234);
end.
0118999881999119725-3

Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
Zvoni
Beiträge: 732
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz/FPC fixes)
CPU-Target: 64Bit
Wohnort: BW

Re: Doppelter Bezeichner Type/var geht

Beitrag von Zvoni »

Womit wir den Bumerang bekommen zu:
Benutze halt keine Keywords als Variablen-Namen *schulterzuck*

Glaube mich sogar daran zu erinnern, dass irgendwas deswegen sogar in der Doku steht.
Bin mir aber nicht sicher
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 7433
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Doppelter Bezeichner Type/var geht

Beitrag von af0815 »

Ein Typ ist kein Keywort.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
Zvoni
Beiträge: 732
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz/FPC fixes)
CPU-Target: 64Bit
Wohnort: BW

Re: Doppelter Bezeichner Type/var geht

Beitrag von Zvoni »

af0815 hat geschrieben: Mo 7. Sep 2026, 14:25 Ein Typ ist kein Keywort.
Argghh.....stimmt.....
Du weisst was ich meine :lol: :P
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Warf
Beiträge: 2325
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Doppelter Bezeichner Type/var geht

Beitrag von Warf »

Shadowing regeln in FPC sind etwas seltsam. Grundsätzlich ist es erst mal nur ein Fehler wenn es keine Mööglichkeit zur Auflösung gibt. Über den Qualifizierten Namen kann man über Units hinweg immer auflösen wie von Zvoni gezeigt mit System.Pointer. Das einzige was gar nicht erlaubt ist, ist wenn es keine Möglichkeit mehr zum Auflösen gibt (z.B. zwei globale Bezeichner in der gleichen Unit).

In manchen Situationen ist Shadowing darüber hinaus nicht erlaubt, z.B.:

Code: Alles auswählen

type TMyClass = class
public
  MyInt: Integer;
  procedure Foo(MyInt:Integer); // Error Duplicate Identifier in Mode ObjFPC
end;
Das gibt in Mode ObjFPC einen Fehler obwohl man über Self MyInteger immer auflösen kann. In Mode Delphi ist das aber erlaubt.

Benutzeravatar
Zvoni
Beiträge: 732
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz/FPC fixes)
CPU-Target: 64Bit
Wohnort: BW

Re: Doppelter Bezeichner Type/var geht

Beitrag von Zvoni »

Warf hat geschrieben: Mo 7. Sep 2026, 15:17 Shadowing regeln in FPC sind etwas seltsam. Grundsätzlich ist es erst mal nur ein Fehler wenn es keine Mööglichkeit zur Auflösung gibt. Über den Qualifizierten Namen kann man über Units hinweg immer auflösen wie von Zvoni gezeigt mit System.Pointer. Das einzige was gar nicht erlaubt ist, ist wenn es keine Möglichkeit mehr zum Auflösen gibt (z.B. zwei globale Bezeichner in der gleichen Unit).

In manchen Situationen ist Shadowing darüber hinaus nicht erlaubt, z.B.:

Code: Alles auswählen

type TMyClass = class
public
  MyInt: Integer;
  procedure Foo(MyInt:Integer); // Error Duplicate Identifier in Mode ObjFPC
end;
Das gibt in Mode ObjFPC einen Fehler obwohl man über Self MyInteger immer auflösen kann. In Mode Delphi ist das aber erlaubt.
Wobei ich aber dann sage: Wer Typen-Bezeichner als Variablen-Namen verwendet ("..... (pointer : pointer)" oder "Var pointer:String;") hat dann sowieso kein Mitleid von mir zu erwarten.

In einem Programmierer-Team wäre das mMn sogar ein Grund für eine Abmahnung :lol:
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Antworten