Recent

Author Topic: Unexpected Incompatible Type Error  (Read 1907 times)

simsee

  • Full Member
  • ***
  • Posts: 183
Unexpected Incompatible Type Error
« on: September 26, 2021, 10:13:06 am »
Consider the following program:

Code: Pascal  [Select][+][-]
  1. program Project1;
  2. uses
  3.   Classes, DOM, XMLWrite;
  4. var
  5.   Doc: TXMLDocument;
  6.   RootNode, ParentNode : TDOMNode;
  7.   Lst : TStringList;
  8. begin
  9.   Lst:=TStringList.Create;
  10.   try
  11.     Lst.AddPair('att','xyz');
  12.       try
  13.         Doc:=TXMLDocument.Create;
  14.         RootNode:=Doc.CreateElement('root');
  15.         Doc.Appendchild(RootNode);
  16.         RootNode:= Doc.DocumentElement;
  17.         ParentNode := Doc.CreateElement('parent');
  18.         TDOMElement(ParentNode).SetAttribute(Lst.Names[0], Lst.Values[0]); // <-- error
  19.         //TDOMElement(ParentNode).SetAttribute('att','xyz');   //ok
  20.         RootNode.Appendchild(ParentNode);
  21.       finally
  22.         Doc.Free;
  23.       end;
  24.   finally
  25.     Lst.Free;
  26.   end;
  27. end.  

The compiler generates the following error message:

project1.lpr(18,72) Error: Incompatible type for arg no. 1: Got "ShortInt", expected "AnsiString"

This amazes me because Lst.Names[0] is a string (as shown by the Getter function associated with the property), not a shortint. I'm definitely missing something trivial, but I don't understand what. Can anyone give me an explanation? Thanks in advance.
« Last Edit: September 26, 2021, 10:28:26 am by simsee »

Thaddy

  • Hero Member
  • *****
  • Posts: 14159
  • Probably until I exterminate Putin.
Re: Unexpected Incompatible Type Error
« Reply #1 on: September 26, 2021, 01:14:14 pm »
It is probably not the names, but the values, I suspect the latter needs conversion to string.
Specialize a type, not a var.

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: Unexpected Incompatible Type Error
« Reply #2 on: September 26, 2021, 01:34:12 pm »
The problem can be simplified to this code:
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. uses Classes;
  4. var
  5.   L: TStringList;
  6.   sn, sv: String;
  7. begin
  8.   L := TStringList.Create;
  9.   try
  10.     L.AddPair('Name1', 'Value1');
  11.     sn := L.Names[0];
  12.     sv := L.Values[0];
  13.   finally
  14.     L.Free;
  15.   end;
  16. end.

Attempting to compile this results in the same error message: "Got shortint, expected AnsiString". But when you look carefully at the editor, you see that the cursor has been put after the 0 - this means that the problem is not in the result of L.Values[...], but in the index. Now look at the declaration of the Values property:
Code: Pascal  [Select][+][-]
  1.     property Values[const Name: string]: string read GetValue write SetValue;
And in fact, the argument must be a string, not an integer like in your code.

So, when I change the code to
Code: Pascal  [Select][+][-]
  1.    sv := L.Values[sn];
the compiler is happy.

If you want to use the index in the Values call, you should use the property ValueFromIndex[Index: Integer].

simsee

  • Full Member
  • ***
  • Posts: 183
Re: Unexpected Incompatible Type Error
« Reply #3 on: September 26, 2021, 01:55:09 pm »
Thaddy, WP, thanks for explanations.

However the compiler error message was misleading, because the mismatch type concerned the second parameter, not the first. Moreover, the problem is not the parameter as a whole, but its index.
« Last Edit: September 26, 2021, 02:10:10 pm by simsee »

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: Unexpected Incompatible Type Error
« Reply #4 on: September 26, 2021, 02:37:22 pm »
No, the message is correct. The second parameter of your SetAttributes is Lst.Names[0], and the cursor if at the "0" - this means that the error message refers to the "0". In this is where a string is expected, not an integer.

simsee

  • Full Member
  • ***
  • Posts: 183
Re: Unexpected Incompatible Type Error
« Reply #5 on: September 26, 2021, 03:26:50 pm »
I don't want to insist, I just want to understand.

Code: Pascal  [Select][+][-]
  1. TDOMElement(ParentNode).SetAttribute(Lst.Names[0], Lst.Values[0]);

...The second parameter of your SetAttributes is Lst.Names[0]...

Lst.Names[0] is the first parameter from left. Or are the parameters numbered from right to left?

Addendum: Is Values that needs a string index, not Names
« Last Edit: September 26, 2021, 03:38:27 pm by simsee »

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: Unexpected Incompatible Type Error
« Reply #6 on: September 26, 2021, 03:56:49 pm »
I don't want to insist, I just want to understand.

Code: Pascal  [Select][+][-]
  1. TDOMElement(ParentNode).SetAttribute(Lst.Names[0], Lst.Values[0]);

...The second parameter of your SetAttributes is Lst.Names[0]...

Lst.Names[0] is the first parameter from left. Or are the parameters numbered from right to left?

Addendum: Is Values that needs a string index, not Names
Sorry to confuse you - typo: I meant Lst.Values[0] instead of .Names[0]. And yes: Values[] needs a string index.

simsee

  • Full Member
  • ***
  • Posts: 183
Re: Unexpected Incompatible Type Error
« Reply #7 on: September 26, 2021, 07:06:34 pm »
No problem.  Thanks wp.  I understand my mistake, but the compiler gives a wrong message, as the type mismatch is about the second argument, not the first.

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: Unexpected Incompatible Type Error
« Reply #8 on: September 26, 2021, 07:45:43 pm »
the compiler gives a wrong message, as the type mismatch is about the second argument, not the first.

Again no - the message is absolutely correct. Maybe you should put the arguments of SetAttributes into separate variables to see what I mean:
Code: Pascal  [Select][+][-]
  1. var
  2.   sName, sValue: String;
  3. ...
  4.   sName := Lst.Names[0];
  5.   sValue := Lst.Values[0];   // <--- this is where the compiler will find an error: the argument is an integer not a string - exactly what the compiler says.
  6.   // This would be correct:
  7.   // sValue := Lst.Values[sName];
  8.   // or:
  9.   // sValue := Lst.ValueFromIndex[0];
  10.   TDOMElement(ParentNode).SetAttribute(sName, sValue);

 

TinyPortal © 2005-2018