11

In Delphi is there a way to declare a procedure as an alias of another? Something like:

function AnAliasToUpperCase(const S: AnsiString): AnsiString = system.AnsiStrings.UpperCase;  

and later in the program calling AnAliasToUpperCase or UpperCase must be exactly the same.

Fabrizio
  • 7,603
  • 6
  • 44
  • 104
zeus
  • 12,173
  • 9
  • 63
  • 184
  • 7
    You would save and others a lot of trouble if you would finally learn how to ask proper questions. Stating what your real problem is, how you tried to solve it and what were the problems with your solutions. – Dalija Prasnikar Jan 22 '18 at 09:32

2 Answers2

32

Defining it e.g. like a constant declaration:

const
  AliasToUpperCase: function(const S: AnsiString): AnsiString = System.AnsiStrings.UpperCase;

might work for your needs.

Victoria
  • 7,822
  • 2
  • 21
  • 44
  • 4
    Neat. Could be used nicely for C header translations. Must consider that the next time. – Rudy Velthuis Jan 21 '18 at 23:56
  • @Rudy, I've used that for the same reason in favor of variable declarations a few times in implementation units. – Victoria Jan 22 '18 at 00:02
  • 1
    const could be good, but in background it's have implication because i think it's same as VAR AliasToUpperCase: function(const S: AnsiString): AnsiString, and i know that var have some performance penalty (maybe because of the try finally that the compiler must add on each call) – zeus Jan 22 '18 at 07:49
  • 1
    @loki you are right: It's simply a function pointer variable in disguise, so the same performance penalty applies. Still a neat idea Victoria. – dummzeuch Jan 22 '18 at 08:26
  • 1
    @loki There is no try finally being added. calling this AliasToUpperCase simply generates a `call dword ptr []`. – Stefan Glienke Jan 22 '18 at 08:32
  • @stefan : so i need to investigate because i notice the the call to a var procedure is little more slow that the call the the raw procedure. but maybe it's my timer that are wrong ... – zeus Jan 22 '18 at 08:38
  • @loki The difference is probably in the range of a nanosecond per call. – Stefan Glienke Jan 22 '18 at 08:48
  • @stefen: yes you are probably right ... i will try to see to be sure – zeus Jan 22 '18 at 09:21
6

The proper answer to the question "How to make an alias to a function/procedure" is "You can't".

But there are two workarounds to simulate this which both might introduce a bit of overhead - the first is the const as shown in the other answer.

Additionally to declaring it as const you can also declare it as new inline routine:

function AliasToUpperCase(const S: AnsiString): AnsiString; inline;
begin
  Result := System.AnsiStrings.UpperCase(S);
end;

But then you are depending on the compiler settings for inlining and need to also add the AnsiStrings unit to wherever you are calling AliasToUpperCase or you will get the H2443 Inline function has not been expanded because unit is not specified in USES list warning.

For this function signature it works but for other return types you might suffer from missing return value optimization and have extra value copies.

Stefan Glienke
  • 20,860
  • 2
  • 48
  • 102
  • The missing RVO optimization seems to be fixed in 10.2 Tokyo. At least for managed types. https://quality.embarcadero.com/browse/RSP-16361. Ok, now I see, they probably messed something up: https://stackoverflow.com/a/47532570/576719 – LU RD Jan 22 '18 at 08:58
  • No, its not. The title of that issue is wrong, method pointers are no managed types. Try for yourself before guessing. Make a record with a string field and return it from 2 nested function calls (similar to the `AliasToUpperCase` function and look at the double `CopyRecord` calls) – Stefan Glienke Jan 22 '18 at 09:06