Sign in Join

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

Mailing lists / fpc-pascal / 2017-10

Problem with array of const

5 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

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

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.

Reply by email

Vojtěch Čihák

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. 
______________________________________________________________

Show quoted text 5 lines
Od: Darius Blaszyk Komu: FPC-Pascal users discussions 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.

----------

Reply by email

Unknown author
to Vojtěch Čihák
Vojtěch Čihák wrote 52 lines
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 > Komu: FPC-Pascal users discussions > 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  -   http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - 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.

Reply by email

Unknown author
to Vojtěch Čihák: Looking to docs: https://www.freepascal.org/docs-html/ref/refsu69.html I tried…
Vojtěch Čihák wrote 43 lines
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 > Komu: FPC-Pascal users discussions > 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.

Reply by email

Tony Whyman
to Darius Blaszyk: Consider the application below. When I run it I do get the following output: name…

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.

Darius Blaszyk wrote 28 lines
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 - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email