Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Char and Chr in Delphi

Tags:

char

delphi

The difference between Chr and Char when used in converting types is that one is a function and the other is cast

So: Char(66) = Chr(66)

I don't think there is any performance difference (at least I've never noticed any, one probably calls the other).... I'm fairly sure someone will correct me on this!

EDIT Thanks to Ulrich for the test proving they are in fact identical.
EDIT 2 Can anyone think of a case where they might not be identical, e.g. you are pushed towards using one over the other due to the context?

Which do you use in your code and why?

like image 295
James Barrass Avatar asked Dec 29 '22 22:12

James Barrass


2 Answers

I did a small test in D2007:

program CharChr;

{$APPTYPE CONSOLE}

uses
  Windows;

function GetSomeByte: Byte;
begin
  Result := Random(26) + 65;
end;

procedure DoTests;
var
  b: Byte;
  c: Char;
begin
  b := GetSomeByte;
  IsCharAlpha(Chr(b));
  b := GetSomeByte;
  IsCharAlpha(Char(b));

  b := GetSomeByte;
  c := Chr(b);
  b := GetSomeByte;
  c := Char(b);
end;

begin
  Randomize;
  DoTests;
end.

Both calls produce the same assembly code:

CharChr.dpr.19: IsCharAlpha(Chr(b));
00403AE0 8A45FF           mov al,[ebp-$01]
00403AE3 50               push eax
00403AE4 E86FFFFFFF       call IsCharAlpha
CharChr.dpr.21: IsCharAlpha(Char(b));
00403AF1 8A45FF           mov al,[ebp-$01]
00403AF4 50               push eax
00403AF5 E85EFFFFFF       call IsCharAlpha

CharChr.dpr.24: c := Chr(b);
00403B02 8A45FF           mov al,[ebp-$01]
00403B05 8845FE           mov [ebp-$02],al
CharChr.dpr.26: c := Char(b);
00403B10 8A45FF           mov al,[ebp-$01]
00403B13 8845FE           mov [ebp-$02],al

Edit: Modified sample to mitigate Nick's concerns.

Edit 2: Nick's wish is my command. ;-)

like image 51
Uli Gerhardt Avatar answered Dec 31 '22 11:12

Uli Gerhardt


The help says: Chr returns the character with the ordinal value (ASCII value) of the byte-type expression, X. *

So, how is a character represented in a computer's memory? Guess what, as a byte*. Actually the Chr and Ord functions are only there for Pascal being a strictly typed language prohibiting the use of bytes* where characters are requested. For the computer the resulting char is still represented as byte* - to what shall it convert then? Actually there is no code emitted for this function call, just as there is no code omitted for a type cast. Ergo: no difference.

You may prefer chr just to avoid a type cast.

Note: type casts shall not be confused with explicit type conversions! In Delphi 2010 writing something like Char(a) while a is an AnsiChar, will actually do something.

**For Unicode please replace byte with integer*

Edit:

Just an example to make it clear (assuming non-Unicode):

var
  a: Byte;
  c: char;
  b: Byte;
begin
  a := 60;
  c := Chr(60);
  c := Chr(a);
  b := a;
end;

produces similar code

ftest.pas.46: a := 60;
0045836D C645FB3C         mov byte ptr [ebp-$05],$3c
ftest.pas.47: c := Chr(60);
00458371 C645FA3C         mov byte ptr [ebp-$06],$3c
ftest.pas.48: c := Chr(a);
00458375 8A45FB           mov al,[ebp-$05]
00458378 8845FA           mov [ebp-$06],al
ftest.pas.49: b := a;
0045837B 8A45FB           mov al,[ebp-$05]
0045837E 8845F9           mov [ebp-$07],al

Assigning byte to byte is actually the same as assigning byte to char via CHR().

like image 34
Uwe Raabe Avatar answered Dec 31 '22 12:12

Uwe Raabe