Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2014-03

open array and address of "@" / crash, why?

10 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Martin Frb

The below program compiles fine (and generates no warning (fpc 2.6.2 / win 32)

"c" is an open array. But there is no warning when assigning the [address of c] to a [pointer to dyn array].

Assuming that type safety checks are performed, I would expect a working pointer. But it does not. The pointer point directly to the 1st element of the array. So using it a pointer to a dyn-array, crashes.

So what should happen?
- Should this code work?
- Should this code give a compile error?
- ?

program project1;
type
   TA = array of integer;
   PA = ^TA;
var
   a : array of integer;
   a1: PA;
procedure Foo(var c: array of integer; var c1: PA);
begin
   c1:= @c;
   writeln(PInteger(c1)^);  // writes 100
   writeln(c1^[1]);   //crash
   readln;
end;
begin
   SetLength(a,5);
   a[0]:= 100;
   a[1]:= 101;
   ;
   foo(a,a1);
end.

Reply by email

Jonas Maebe
to Martin Frb
Martin Frb wrote
The below program compiles fine (and generates no warning (fpc 2.6.2 / win 32)

It only compiles fine with the (default) {$t-}. If you add {$t+}, it doesn't compile. Without typed pointers, the result of the @-operator is an untyped pointer, which by definition is assignment-compatible with all other pointer types.

Making {$t+} the default is hard because it could break existing, correct code (e.g., "" would result in a pointer 2 bytes after @wordvar instead of 1 with {$t+}).

Jonas

Reply by email

Martin Frb
to Jonas Maebe
Jonas Maebe wrote 12 lines
On 30/03/14 15:24, Martin Frb wrote: > The below program compiles fine (and generates no warning (fpc 2.6.2 / > win 32) It only compiles fine with the (default) {$t-}. If you add {$t+}, it doesn't compile. Without typed pointers, the result of the @-operator is an untyped pointer, which by definition is assignment-compatible with all other pointer types. Making {$t+} the default is hard because it could break existing, correct code (e.g., "" would result in a pointer 2 bytes after @wordvar instead of 1 with {$t+}).

Ah yes, so easy to forget... (Now I remember)

Slight change, and I get
Fatal: Compilation aborted

program project1;
{$t+}
type
   TA = array of integer;
   PA = ^TA;
var
   a : array of integer;
   a1: PA;
procedure Foo(var c: array of integer; var c1: PA);
begin
   //c1:= @c;
   writeln( (@c)^[1] );
   //writeln(PInteger(c1)^);
   //writeln(c1^[1]);
   readln;
end;
begin
   SetLength(a,5);
   a[0]:= 100;
   a[1]:= 101;
   ;
   foo(a,a1);
end.

Reply by email

Michael Van Canneyt
to Martin Frb
Martin Frb wrote 46 lines
On 30/03/2014 14:35, Jonas Maebe wrote: > On 30/03/14 15:24, Martin Frb wrote: >> The below program compiles fine (and generates no warning (fpc 2.6.2 / >> win 32) > > It only compiles fine with the (default) {$t-}. If you add {$t+}, it > doesn't compile. Without typed pointers, the result of the @-operator is an > untyped pointer, which by definition is assignment-compatible with all > other pointer types. > > Making {$t+} the default is hard because it could break existing, correct > code (e.g., "" would result in a pointer 2 bytes > after @wordvar instead of 1 with {$t+}). Ah yes, so easy to forget... (Now I remember) Slight change, and I get Fatal: Compilation aborted program project1; {$t+} type TA = array of integer; PA = ^TA; var a : array of integer; a1: PA; procedure Foo(var c: array of integer; var c1: PA); begin //c1:= @c; writeln( (@c)^[1] ); //writeln(PInteger(c1)^); //writeln(c1^[1]); readln; end; begin SetLength(a,5); a[0]:= 100; a[1]:= 101; ;
If you are counting on the implicit pointer=array as in C,
then this should probably be  or a1:=PA(a)

Michael.

Reply by email

Martin Frb
to Michael Van Canneyt
Michael Van Canneyt wrote 19 lines
On Sun, 30 Mar 2014, Martin Frb wrote: > > Slight change, and I get > Fatal: Compilation aborted > > > > procedure Foo(var c: array of integer; var c1: PA); > begin > > writeln( (@c)^[1] ); > > If you are counting on the implicit pointer=array as in C, then this should probably be or a1:=PA(a)

No I didn't.

c is an open array.
@c is a pointer to an open array (if something like that exists) (@c)^ is the open array again.
(@c)^[1] is an element in that array

But this is not about the question if this works. It would be fine if it gave a proper error. But an "Internal Error"? That seems to be a bug.

I will shorten the example, and report it.

Leaves the question, what should it do?
1) Error: cant take the address of an open array?
2) Address of an open array is address of first member, then "(@c)^" is an integer, and can not have an index: Error unexpected "["....
3) Work as described in the steps above?
4) ?

Reply by email

Jonas Maebe
to Martin Frb
Martin Frb wrote
But this is not about the question if this works. It would be fine if it gave a proper error. But an "Internal Error"? That seems to be a bug.

You said that you got "Fatal: Compilation aborted", not that you got an internal error. Internal errors are indeed always bugs.

Jonas

Reply by email

Martin Frb
to Jonas Maebe
Jonas Maebe wrote 9 lines
On 31 Mar 2014, at 14:53, Martin Frb wrote: > But this is not about the question if this works. It would be fine if > it gave a proper error. But an "Internal Error"? That seems to be a bug. You said that you got "Fatal: Compilation aborted", not that you got an internal error. Internal errors are indeed always bugs.

Sorry, now I was incorrect. It does not say "internal". What I meant to describe is, that it gives the "fatal error" without any extra error message, or without indication where or why the error happened. That is something, that up to now, I have only seen with internal errors.

So question is should there be some other error message?

Show quoted text 11 lines
Hint: Start of reading config file C:\FPC\rel_2_6_2\gw\bin\i386-win32\fpc.cfg Hint: End of reading config file C:\FPC\rel_2_6_2\gw\bin\i386-win32\fpc.cfg Free Pascal Compiler version 2.6.2 [2013/02/16] for i386 Copyright (c) 1993-2012 by Florian Klaempfl and others Target OS: Win32 for i386 Compiling project1.lpr Fatal: Compilation aborted

Shortened example:

program project1;
{$t+}
var
   a : array of integer;
procedure Foo(var c: array of integer);
begin
   writeln( (@c)^[1] );
   readln;
end;
begin
   SetLength(a,5);
   a[0]:= 100;
   a[1]:= 101;
   foo(a);
end.

Reply by email

Howard Page-Clark
to Martin Frb
Martin Frb wrote 19 lines
Shortened example: program project1; {$t+} var a : array of integer; procedure Foo(var c: array of integer); begin writeln( (@c)^[1] ); readln; end; begin SetLength(a,5); a[0]:= 100; a[1]:= 101; foo(a); end.

This compiles here (FPC 2.6.5, Win32), and produces the output "101" with no errors.

Howard

Reply by email

Martin Frb
to Howard Page-Clark
Howard Page-Clark wrote
This compiles here (FPC 2.6.5, Win32), and produces the output "101" with no errors.

You are right, I just run with the setting I have in my IDE, without further testing.

Just testing the compilation, not running the reslt for now:

This is good:
C:\FPC\rel_2_6_4\gw\bin\i386-win32\fpc.exe project1.lpr

-----------
C:\FPC\rel_2_6_4\gw\bin\i386-win32\fpc.exe -Criot project1.lpr or
C:\FPC\rel_2_6_4\gw\bin\i386-win32\fpc.exe -Cr project1.lpr

Compiling project1.lpr
Fatal: Compilation aborted
An unhandled exception occurred at $004B352B :
EAccessViolation : Access violation
$004B352B
$00440720
$004E9F72
$004EC4B8
$004EC4CC
$004EC4CC

It is the -Cr
For some reason, when compiling in Lazarus, I do not see the trace. Seems the IDE stops reading after Compilation aborted

BTW, trying to compile fpc trunk itself, with -Cr also does not work.

Reply by email