Problem with array of const

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Problem with array of const

Darius Blaszyk
Consider the application below. When I run it I do get the following output:

name
rg��������name�F&{00000000-0000-0000-C000-000000000046}

In other words I lose the first character (a) from the arguments supplied and the string returns with a lot of garbage. What am I doing wrong here?

Rgds, Darius

program test_args;

procedure test(name: string; args: array of const);
begin
  writeln(name);
  writeln(args[0].VString^);
end;

begin
  test('name', ['arg']);
end.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Problem with array of const

vojtech.cihak

Looking to docs: https://www.freepascal.org/docs-html/ref/refsu69.html

I tried writeln(AnsiString(args[0].VAnsiString));

or just writeln(String(args[0].VAnsiString));

which works.

 

V. 

______________________________________________________________
> Od: Darius Blaszyk <[hidden email]>
> Komu: FPC-Pascal users discussions <[hidden email]>
> Datum: 29.10.2017 00:59
> Předmět: [fpc-pascal] Problem with array of const
>

Consider the application below. When I run it I do get the following output:

name
rg��������name�F&{00000000-0000-0000-C000-000000000046}

In other words I lose the first character (a) from the arguments supplied and the string returns with a lot of garbage. What am I doing wrong here?

Rgds, Darius

program test_args;

procedure test(name: string; args: array of const);
begin
  writeln(name);
  writeln(args[0].VString^);
end;

begin
  test('name', ['arg']);
end.


----------

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Problem with array of const

pascalX
On 29/10/17 00:31, Vojtěch Čihák wrote:

> Looking to docs: https://www.freepascal.org/docs-html/ref/refsu69.html
>
> I tried writeln(AnsiString(args[0].VAnsiString));
>
> or just writeln(String(args[0].VAnsiString));
>
> which works.
>
> V.
>
> ______________________________________________________________
>  > Od: Darius Blaszyk <[hidden email]>
>  > Komu: FPC-Pascal users discussions <[hidden email]>
>  > Datum: 29.10.2017 00:59
>  > Předmět: [fpc-pascal] Problem with array of const
>  >
>
> Consider the application below. When I run it I do get the following output:
>
> name
> rg��������name�F&{00000000-0000-0000-C000-000000000046}
>
> In other words I lose the first character (a) from the arguments
> supplied and the string returns with a lot of garbage. What am I doing
> wrong here?
>
> Rgds, Darius
>
> program test_args;
>
> procedure test(name: string; args: array of const);
> begin
>    writeln(name);
>    writeln(args[0].VString^);
> end;
>
> begin
>    test('name', ['arg']);
> end.
>
>
> ----------
>
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>
>
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>


       vtString     : (VString: PShortString);


in short the compiler is  sending  AnsiString and you are then telling
it to interpret this as a traditional pascal string of length 97.  The
Tvarrec  in the Array of const effectively removes the usual strong type
checking you get with Pascal.

string literals now get compiled as AnsiString unless you explicitly
assign them to a typed constant:


program test_args;
{$mode objfpc}

procedure test(name: string; args: array of const);
begin
   writeln(name);
   writeln(args[0].VString^);
end;

const  sh:shortstring='sconst';
var s:shortstring='arg';

begin
   test('name', [s]);
   test('name', [sh]);
end.


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Problem with array of const

pascalX
In reply to this post by vojtech.cihak
On 29/10/17 00:31, Vojtěch Čihák wrote:

> Looking to docs: https://www.freepascal.org/docs-html/ref/refsu69.html
>
> I tried writeln(AnsiString(args[0].VAnsiString));
>
> or just writeln(String(args[0].VAnsiString));
>
> which works.
>
> V.
>
> ______________________________________________________________
>  > Od: Darius Blaszyk <[hidden email]>
>  > Komu: FPC-Pascal users discussions <[hidden email]>
>  > Datum: 29.10.2017 00:59
>  > Předmět: [fpc-pascal] Problem with array of const
>  >
>
> Consider the application below. When I run it I do get the following output:
>
> name
> rg��������name�F&{00000000-0000-0000-C000-000000000046}
>
> In other words I lose the first character (a) from the arguments
> supplied and the string returns with a lot of garbage. What am I doing
> wrong here?
>
> Rgds, Darius
>
> program test_args;
>
> procedure test(name: string; args: array of const);
> begin
>    writeln(name);
>    writeln(args[0].VString^);
> end;
>
> begin
>    test('name', ['arg']);
> end.
>
>
> ----------
>

PS

In fact this page of doc linked by Vojtěch may need reviewing:

docs-html:


"Remark that this is not true for Delphi, so code relying on this
feature will not be portable."

What is not "true"?  It is unclear exactly what "this" refers to. Should
this be stating that cdecl modifier is not supported in Delphi?



"Remark: Note that there is no support for QWord arguments in array of
const. This is for Delphi compatibility, "

Huh?

        vtWideString : (VWideString: Pointer);
        vtInt64      : (VInt64: PInt64);
        vtQWord      : (VQWord: PQWord);
    end;


Also all the code examples are displayed using the wrong quote character
and copying the code results in tons of syntax errors.  If this was done
to make mark-up easier it should at least be noted in the About this
Guide, Notations section.  Preferably the code should paste and work.


the testit example requires a mode but this is not included as is
promised in  About this Guide.
{$mode objfpc}


Further typos suggest is was never tested:

         Writeln (’AnsiString, value :’,AnsiString(Args[I].VAnsiString);

missing parenthesis at end of line.

        Writeln (’No aguments’);

aguments ??

       Therefor, inside the procedure body,

Should be "Therefore". Therefor is a different word.





_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Problem with array of const

Tony Whyman
In reply to this post by Darius Blaszyk

I've fallen into various traps with array of const before. I would always recommend that:

1. Test the vType before accessing the argument value and raise an exception if it is not what is expected. You are dealing with a free union and the compiler may not always do what you expect it to.

2. Values such as VAnsiString are best dealt with as PChars as otherwise you can quickly get into problems with reference counts.

For example:

program test_args;

procedure test(name: string; args: array of const);
begin
  writeln(name);

  case args[0].vType of

  vtAnsiString:
    writeln(strpas(PAnsiChar(args[0].VAnsiString)));
  else
    raise Exception.Create('Unexpected vtype');
  end;

end;

begin
  test('name', ['arg']);
end.

Use of "strpas" is probably unnecessary in the above, but it does illustrate the point.


On 28/10/17 23:59, Darius Blaszyk wrote:
Consider the application below. When I run it I do get the following output:

name
rg��������name�F&{00000000-0000-0000-C000-000000000046}

In other words I lose the first character (a) from the arguments supplied and the string returns with a lot of garbage. What am I doing wrong here?

Rgds, Darius

program test_args;

procedure test(name: string; args: array of const);
begin
  writeln(name);
  writeln(args[0].VString^);
end;

begin
  test('name', ['arg']);
end.


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal