parts - delphi technologies
¿Cómo resuelve Delphi las funciones sobrecargadas con parámetros integrales? (1)
Considere el siguiente programa:
program IntegerOverloads;
{$APPTYPE CONSOLE}
procedure WordOrCardinal(Value: Word); overload;
begin
Writeln(''Word'');
end;
procedure WordOrCardinal(Value: Cardinal); overload;
begin
Writeln(''Cardinal'');
end;
procedure SmallintOrInteger(Value: Smallint); overload;
begin
Writeln(''Smallint'');
end;
procedure SmallintOrInteger(Value: Integer); overload;
begin
Writeln(''Integer'');
end;
procedure ShortintOrSmallint(Value: Shortint); overload;
begin
Writeln(''Shortint'');
end;
procedure ShortintOrSmallint(Value: Smallint); overload;
begin
Writeln(''Smallint'');
end;
procedure Main;
var
_integer: Integer;
_cardinal: Cardinal;
_word: Word;
begin
WordOrCardinal(_Integer);
SmallintOrInteger(_cardinal);
ShortintOrSmallint(_word);
end;
begin
Main;
Readln;
end.
La salida cuando es compilada por XE2 es:
Cardinal
Integer
Smallint
La salida cuando es compilada por Delphi 6 es:
Word
Smallint
Shortint
Los estados de documentation (énfasis mío):
Puede pasar a una rutina sobrecargada los parámetros que no son idénticos en tipo a los de cualquiera de las declaraciones de la rutina, pero que son compatibles con la asignación de los parámetros en más de una declaración. Esto ocurre con mayor frecuencia cuando una rutina está sobrecargada con diferentes tipos de enteros o diferentes tipos reales, por ejemplo:
procedure Store(X: Longint); overload; procedure Store(X: Shortint); overload;
En estos casos, cuando es posible hacerlo sin ambigüedad, el compilador invoca la rutina cuyos parámetros son del tipo con el rango más pequeño que acomoda los parámetros reales en la llamada .
Pero eso parece aplicarse aquí. Ninguna de las llamadas de procedimiento en el código de ejemplo acepta un tipo que acomode los parámetros reales en la llamada.
No puedo encontrar ninguna documentación que describa qué regla sigue el compilador. ¿Alguien puede indicarme tal documentación?
Esta pregunta fue formulada por los siguientes artículos:
- ReverseBytes()
- El código ZeroConf / Bonjour que funciona en Delphi 7 no funciona en 2009
- ¿Qué hay en una palabra ...?
Actualizar
A raíz de los comentarios de Ken White, escribí otro programa para ilustrar algunas rarezas más:
program IntegerOverloadsPart2;
{$APPTYPE CONSOLE}
procedure Test(Value: Byte); overload;
begin
Writeln(''Byte'');
end;
procedure Test(Value: Word); overload;
begin
Writeln(''Word'');
end;
procedure Test(Value: Cardinal); overload;
begin
Writeln(''Cardinal'');
end;
procedure Test(Value: Uint64); overload;
begin
Writeln(''Uint64'');
end;
procedure Main;
var
_byte: Byte;
_shortint: Shortint;
_word: Word;
_smallint: Smallint;
_cardinal: Cardinal;
_integer: Integer;
_uint64: UInt64;
_int64: Int64;
begin
Writeln(''Unsigned variables passed as parameters:'');
Test(_byte);
Test(_word);
Test(_cardinal);
Test(_uint64);
Writeln;
Writeln(''Signed variables passed as parameters:'');
Test(_shortint);
Test(_smallint);
Test(_integer);
Test(_int64);
end;
begin
Main;
Readln;
end.
Cuando es compilado por XE2 la salida es:
Unsigned variables passed as parameters:
Byte
Word
Cardinal
Uint64
Signed variables passed as parameters:
Uint64
Uint64
Uint64
Uint64
En Delphi 6 tengo que eliminar la sobrecarga de UInt64
ya que ese tipo no existe en Delphi 6, la salida es:
Unsigned variables passed as parameters:
Byte
Word
Cardinal
Signed variables passed as parameters:
Byte
Byte
Byte
Nuevamente ninguno de los comportamientos parece coherente con la afirmación de que
En estos casos, cuando es posible hacerlo sin ambigüedad, el compilador invoca la rutina cuyos parámetros son del tipo con el rango más pequeño que acomoda los parámetros reales en la llamada .
Ninguno de los tipos sin signo puede acomodar un tipo firmado; La documentación citada es coherente con sus ejemplos, simplemente no dice nada sobre cómo los tratará el compilador. Por otro lado, un tipo firmado puede aceptar un tipo sin signo (SmallInt acomoda a Byte, LongInt acomoda a Word, Int64 acomoda a Cardinal):
program IntegerOverloadsPart3;
{$APPTYPE CONSOLE}
procedure Test(Value: ShortInt); overload;
begin
Writeln(''Short'');
end;
procedure Test(Value: SmallInt); overload;
begin
Writeln(''Small'');
end;
procedure Test(Value: LongInt); overload;
begin
Writeln(''Long'');
end;
procedure Test(Value: Int64); overload;
begin
Writeln(''64'');
end;
procedure Main;
var
_byte: Byte;
_word: Word;
_cardinal: Cardinal;
_uint64: UInt64;
begin
Writeln(''Unsigned variables passed as parameters:'');
Test(_byte);
Test(_word);
Test(_cardinal);
Test(_uint64);
Writeln;
end;
begin
Main;
Readln;
end.
Salida Delphi XE:
Small
Long
64
64