{"id":1041,"date":"2025-05-27T11:43:23","date_gmt":"2025-05-27T10:43:23","guid":{"rendered":"https:\/\/jorgeturiel.es\/?page_id=1041"},"modified":"2025-05-27T11:43:23","modified_gmt":"2025-05-27T10:43:23","slug":"algunas-diferencias-entre-el-modo-fpc-objfpc-y-modo-delphi-y-fpc-en-modo-delphi","status":"publish","type":"page","link":"https:\/\/jorgeturiel.es\/?page_id=1041","title":{"rendered":"Algunas diferencias entre el modo FPC ObjFpc  y modo Delphi (y FPC en modo Delphi)"},"content":{"rendered":"\n<p>Nota: Este art\u00edculo es una traducci\u00f3n de <a href=\"https:\/\/github.com\/modern-pascal\/modern-pascal-introduction\/wiki\/Some-differences-betwen-FPC-ObjFpc-mode-and-Delphi-(and-FPC-Delphi-mode)\">https:\/\/github.com\/modern-pascal\/modern-pascal-introduction\/wiki\/Some-differences-betwen-FPC-ObjFpc-mode-and-Delphi-(and-FPC-Delphi-mode)<\/a> escrito por Michalis Kamburelis<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Introducci\u00f3n<\/h2>\n\n\n\n<p>El compilador FPC ofrece algunos \u00abmodos de sintaxis\u00bb. Se pueden elegir mediante:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Directivas en el c\u00f3digo de Pascal (como por ejemplo: <code><em>{$mode objfpc}<\/em><\/code>, <code><em>{$mode delphi}<\/em><\/code>).<\/li>\n\n\n\n<li>O por la l\u00ednea de comandos en el compilador FPC (<code>-<em>Mobjfpc<\/em><\/code>, <code>-<em>Mdelphi<\/em><\/code>).<\/li>\n\n\n\n<li>O en los ajustes del proyecto en Lazarus (en el archivo .lpi; aplicavable si compilas desde el IDE Lazarus).<\/li>\n\n\n\n<li>O usando la opci\u00f3n <code><em>-Mxxx<\/em><\/code> en  <code><em>&lt;compiler_options><\/em><\/code> dentro de  <code><em>CastleEngineManifest.xml<\/em><\/code>,si compilas usando el editor CGE o la herramienta  CGE build (ver <a href=\"https:\/\/castle-engine.io\/project_manifest#_compiler_options_and_paths\">https:\/\/castle-engine.io\/project_manifest#_compiler_options_and_paths<\/a> ).<\/li>\n<\/ul>\n\n\n\n<p>Existen algunos modos de sintaxis en FPC, pero en esta p\u00e1gina nos centraremos en dos que son los m\u00e1s populares: la sintaxis ObjFpc y la sintaxis Delphi. Ofrecen 100% las mismas capacidades y son muy compatibles\u2026 pero no absolutamente compatibles, existen peque\u00f1as diferencias que describimos a continuaci\u00f3n.<\/p>\n\n\n\n<p>Delphi no tiene este concepto (aunque tambi\u00e9n tiene algunas opciones que afectan a la sintaxis, mencionamos algunas de ellas m\u00e1s abajo).<\/p>\n\n\n\n<p>Como sus nombres sugieren, el \u00abmodo Delphi\u00bb de FPC es muy compatible con el Delphi real.<\/p>\n\n\n\n<p>El \u00abmodo ObjFpc\u00bb de FPC es un poco m\u00e1s recomendado por los desarrolladores de FPC (aunque esto puede depender de a qui\u00e9n le preguntes \ud83d\ude42 ). De forma m\u00e1s pr\u00e1ctica, las nuevas unidades creadas por Lazarus tienen {$mode objfpc}{$H+} y los nuevos proyectos de Lazarus comienzan con la configuraci\u00f3n \u00abmodo ObjFpc\u00bb. Por lo tanto, los desarrolladores de Lazarus recomiendan y usan por defecto el modo ObjFpc.<\/p>\n\n\n\n<p>En Castle Game Engine, seguimos a Lazarus, por lo que usamos el modo ObjFpc por defecto para tus proyectos CGE, si se compilan con FPC. Aunque puedes cambiarlo para tus proyectos: simplemente a\u00f1ade -Mdelphi en las opciones del compilador en CastleEngineManifest.xml. Mostramos este ejemplo en <a href=\"https:\/\/castle-engine.io\/project_manifest#_compiler_options_and_paths\">https:\/\/castle-engine.io\/project_manifest#_compiler_options_and_paths<\/a> .<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00bfCu\u00e1les son las diferencias? Acompa\u00f1ado de algunas reflexiones personales (de Michalis), a veces con un sesgo, sobre &#8216;qu\u00e9 es mejor&#8217;.<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Variables a procedimientos<\/h3>\n\n\n\n<p>Las variables a procedimientos (punteros a procedimientos) tienen un sintaxis un poco diferentes.<\/p>\n\n\n\n<p>Por ejemplo, puedes escribir:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >procedure TMyView.ButtonClick(Sender: TObject);\nbegin\nend;\n\nprocedure TMyView.Start;\nbegin\n  inherited;\n  OnClick := @ButtonClick; \/\/ this is only OK in FPC ObjFpc\nend;<\/pre><\/div>\n\n\n\n<p>Por otro lado, Delphi, decidi\u00f3 que <em>ButtonClick<\/em>, sin @, es un direcci\u00f3n v\u00e1lida. En efecto, esta l\u00ednea fallar\u00e1 al compilar:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >OnClick := @ButtonClick; \/\/ this is only OK in FPC ObjFpc<\/pre><\/div>\n\n\n\n<p>(ya que en Delphi significa que intentas tomar una direcci\u00f3n de la direcci\u00f3n de <code><em>ButtonClick<\/em><\/code>, por lo que ser\u00eda la direcci\u00f3n de una variable temporal, lo cual no tiene sentido)<\/p>\n\n\n\n<p>Solamente compila as\u00ed:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >OnClick := ButtonClick; \/\/ this is only OK in Delphi or FPC Delphi mode<\/pre><\/div>\n\n\n\n<p>\u00bfCu\u00e1l es la diferencia?<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>El enfoque ObjFpc de FPC (Free Pascal Compiler) es \u00fatil para hacer que algunas expresiones sean menos ambiguas. Por ejemplo, \u00bfqu\u00e9 significa si <code>OnMyEvent = MyFunction<\/code> entonces&#8230;?, cuando los eventos se definen como <code>function: <\/code><em><code>Integer<\/code> <\/em>(una funci\u00f3n que devuelve un entero): \u00bfEsto compara los eventos asignados, o los llama? Se complica a\u00fan m\u00e1s cuando la funci\u00f3n devuelve la direcci\u00f3n de otra funci\u00f3n (como <code>function: TNotifyEvent<\/code>). En el modo ObjFpc de FPC, estas expresiones son f\u00e1ciles de entender porque \u00absin el s\u00edmbolo @, no puedes tomar la direcci\u00f3n de un procedimiento, as\u00ed que la expresi\u00f3n anterior llama a <code>MyFunction<\/code>\u00ab.<\/li>\n\n\n\n<li>Por lo que s\u00e9, la ventaja de la \u00absintaxis de Delphi\u00bb es simplemente la brevedad. Puedes olvidarte del s\u00edmbolo <strong>@<\/strong>, y la mayor\u00eda de las expresiones son obvias para el compilador, es decir, puede distinguir cu\u00e1ndo quieres llamar a una funci\u00f3n y cu\u00e1ndo quieres tomar la direcci\u00f3n de una funci\u00f3n.<\/li>\n<\/ul>\n\n\n\n<p>Mira nuestra prueba en <a href=\"https:\/\/github.com\/michaliskambi\/modern-pascal-introduction\/blob\/master\/code-samples\/delphi_and_fpc_differences\/compare_function_pointers.dpr\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/michaliskambi\/modern-pascal-introduction\/blob\/master\/code-samples\/delphi_and_fpc_differences\/compare_function_pointers.dpr<\/a> para ver algunas construcciones que, en mi humilde opini\u00f3n, resultan realmente extra\u00f1as en Delphi\/FPC en modo Delphi, debido a la decisi\u00f3n de Delphi de omitir el <code>@<\/code>. Pero tambi\u00e9n es cierto que en el \u00abc\u00f3digo real y pr\u00e1ctico\u00bb no te encuentras con estos casos tan a menudo<\/p>\n\n\n\n<p>\u00bfQu\u00e9 hacer en tu c\u00f3digo?<\/p>\n\n\n\n<p>En el c\u00f3digo y los ejemplos de CGE, decidimos simplemente \u00abvivir con ello\u00bb y escribir <code>{$ifdef FPC}@{$endif}<\/code> donde fuera necesario. Nos gusta la <strong>claridad adicional<\/strong> que aporta el modo ObjFpc de FPC al requerir <code>@<\/code>. Adem\u00e1s, muchos usuarios de FPC\/Lazarus est\u00e1n m\u00e1s acostumbrados al modo ObjFpc, ya que es el modo predeterminado configurado en los nuevos proyectos de Lazarus, as\u00ed que nos adherimos a \u00e9l. As\u00ed que escribimos&#8230;<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >OnClick := {$ifdef FPC}@{$endif} ButtonClick;<\/pre><\/div>\n\n\n\n<p>Para ser perfectamente v\u00e1lidos, en realidad deber\u00edamos escribir\u2026<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >OnClick := {$ifdef FPC_OBJFPC}@{$endif} ButtonClick;.<\/pre><\/div>\n\n\n\n<ol class=\"wp-block-list\"><\/ol>\n\n\n\n<p>Pero para simplificar, decidimos asumir que \u00abcuando CGE se compila con FPC, sabemos que se compila en modo FPC ObjFpc, ya que lo configuramos nosotros mismos tanto en la l\u00ednea de comandos como en <code><em>castleconf.inc<\/em><\/code>.<\/p>\n\n\n\n<p>Tambi\u00e9n puedes optar por un enfoque diferente: usar el \u00abmodo Delphi\u00bb con FPC. Para ello, a\u00f1ade <code>-Mdelphi<\/code> en las opciones del compilador en <em>CastleEngineManifest.xml<\/em> (la configuraci\u00f3n del proyecto de Lazarus tambi\u00e9n tiene una opci\u00f3n para cambiar el modo). Consulta la secci\u00f3n \u00ab6.11. Opciones y rutas del compilador\u00bb en <a href=\"https:\/\/castle-engine.io\/project_manifest#_compiler_options_and_paths\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/castle-engine.io\/project_manifest#_compiler_options_and_paths<\/a> , donde mostramos y discutimos expl\u00edcitamente el uso de <code>-Mdelphi<\/code>.<\/p>\n\n\n\n<p>Entonces tendr\u00e1s un c\u00f3digo m\u00e1s consistente entre FPC y Delphi.<\/p>\n\n\n\n<p>A continuaci\u00f3n, se presentan m\u00e1s argumentos y discusiones sobre por qu\u00e9 el modo FPC ObjFpc es una buena idea:<\/p>\n\n\n\n<p>Considera escribir esto, en Delphi o en modo FPC Delphi:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >if X = Y then ...<\/pre><\/div>\n\n\n\n<p>\u00bfQu\u00e9 hace esto si <strong>X<\/strong> e <strong>Y<\/strong> son variables de tipo procedural? En modo Delphi (ya sea con <code>{$mode delphi}<\/code> en FPC o en el propio Delphi), esta es una pregunta dif\u00edcil. Surge del hecho de que en Pascal, llamas a una funci\u00f3n sin par\u00e1metros sin usar par\u00e9ntesis, es decir, sin el <code>()<\/code>. Si <strong>X<\/strong> e <strong>Y<\/strong> apuntan a funciones sin par\u00e1metros que devuelven, por ejemplo, enteros, entonces <code>if X = Y then<\/code> en realidad <strong>las llamar\u00e1 y comparar\u00e1 sus resultados<\/strong>. Solo en otros casos se comparar\u00e1n realmente los punteros a las funciones.<\/p>\n\n\n\n<p>Prueba<strong>:<\/strong> <code><a href=\"https:\/\/github.com\/modern-pascal\/modern-pascal-introduction\/blob\/master\/code-samples\/delphi_and_fpc_differences\/compare_function_pointers.dpr\">compare_function_pointers.dpr<\/a><\/code>. Es un programa Pascal v\u00e1lido, tanto para FPC como para Delphi. Sin embargo, el <code>if X = Y then<\/code> hace algo diferente.<br>Para asegurarte de que comparas punteros a funciones en Delphi, puedes a\u00f1adir el operador de direcci\u00f3n, como:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >if @X = @Y then ...<\/pre><\/div>\n\n\n\n<p>Lo cual es feo, porque en este caso el <code>@<\/code> no obtiene la direcci\u00f3n de <code>X<\/code> (aunque \u00ab<code>@X<\/code>\u00bb se define exactamente como \u00abobtener la direcci\u00f3n de la variable <code>X<\/code>\u00bb en el caso de otros tipos en Pascal). Simplemente indica que realmente queremos el puntero a la funci\u00f3n.<\/p>\n\n\n\n<p>Es a\u00fan m\u00e1s divertido si realmente quieres obtener \u00abuna direcci\u00f3n del puntero a la funci\u00f3n\u00bb, ya que entonces tienes que escribir:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >@@X<\/pre><\/div>\n\n\n\n<p>Lo cual tambi\u00e9n carece de sentido en circunstancias normales. <code>@X<\/code> suele ser un resultado temporal, no un \u00abl-value\u00bb (un valor al que se le puede asignar algo), \u00bfc\u00f3mo se le puede asignar algo?<\/p>\n\n\n\n<p>En modo ObjFpc, todo es m\u00e1s <strong>consistente<\/strong>. <strong>X<\/strong> y <strong>@<\/strong> se comportan igual que para otros tipos. La \u00fanica regla nueva es: \u00abcuando llamas a una variable procedural que contiene una funci\u00f3n sin par\u00e1metros, lo haces como en C: le a\u00f1ades <code>()<\/code>\u00ab. Esto significa que llamar a <strong>X<\/strong> no parece tan \u00abPascal\u00bb, ya que tienes que a\u00f1adir par\u00e9ntesis:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >X()<\/pre><\/div>\n\n\n\n<p>&#8230; Pero todo es m\u00e1s natural. En el modo FPC ObjFpc esto: <\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >if X = Y then<\/pre><\/div>\n\n\n\n<p>Compara punteros a funciones, cuando <strong>X<\/strong> e <strong>Y<\/strong> son, por ejemplo, del tipo <code>function: Pointer<\/code>. Compara intuitivamente el contenido de <strong>X<\/strong> e <strong>Y<\/strong>, sin importar si <strong>X<\/strong>, <strong>Y<\/strong> son enteros, punteros a funciones o punteros a funciones sin par\u00e1metros. Adem\u00e1s:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >@X<\/pre><\/div>\n\n\n\n<p>Ahora es siempre la <strong>direcci\u00f3n de X<\/strong> (sin importar si X es de tipo <code>Integer<\/code> o un puntero a funci\u00f3n). La asignaci\u00f3n de una variable de funci\u00f3n a otra es normal:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >X := Y<\/pre><\/div>\n\n\n\n<p>Y la asignaci\u00f3n de una funci\u00f3n real a X utiliza expl\u00edcitamente el operador <code>@<\/code> en el lado derecho, lo que significa que tomamos la direcci\u00f3n de la funci\u00f3n:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >X := @MyFunction;<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">En el modo ObjFpc, no est\u00e1 permitido tener nombres de campos\/variables\/par\u00e1metros que entren en conflicto, incluso entre descendientes y ancestros.<\/h2>\n\n\n\n<p>Esta regla rompe las reglas de alcance habituales de Pascal (\u00abse permiten conflictos cuando est\u00e1n en diferentes espacios de nombres, y el espacio de nombres m\u00e1s local es el que prevalece\u00bb), pero lo hace con un buen prop\u00f3sito: <strong>protegerte de ciertos errores<\/strong>. Imagina este c\u00f3digo:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >TMyClass = class\n  X: Integer;\n  procedure Foo(X: Integer);\nend;<\/pre><\/div>\n\n\n\n<p>Esto est\u00e1 permitido en modo Delphi. Dentro de la implementaci\u00f3n de <code>Foo<\/code>, la resoluci\u00f3n sigue las reglas normales de Pascal: el mismo nombre, <code>X<\/code>, est\u00e1 permitido si est\u00e1 en \u00e1mbitos diferentes, y el \u00e1mbito m\u00e1s local tiene prioridad.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >procedure TMyClass.Foo(X: Integer);\nbegin\n  X := 123; \/\/ changes the X parameter value, X field is untouched\nend;<\/pre><\/div>\n\n\n\n<p>Esto es peligroso: si cambias la declaraci\u00f3n de <code>Foo<\/code> a <code>Foo(Y: Integer)<\/code>, la implementaci\u00f3n seguir\u00e1 compilando&#8230; pero har\u00e1 algo totalmente diferente, probablemente err\u00f3neo, ya que ahora est\u00e1s cambiando el campo del objeto. Para evitar esto, ObjFpc lo proh\u00edbe: los nombres de los par\u00e1metros deben ser diferentes a los nombres de los campos\/m\u00e9todos\/propiedades de la clase. La clase <code>TMyClass<\/code> anterior simplemente no compilar\u00e1 en modo ObjFpc; tendr\u00e1s que cambiar el nombre del par\u00e1metro a algo como <code>AX<\/code>, y probablemente recordar\u00e1s usar <code>AX<\/code> dentro de la implementaci\u00f3n de <code>Foo<\/code>. Si alguna vez cambias la declaraci\u00f3n de <code>Foo<\/code>, lo m\u00e1s probable es que obtengas un error de compilaci\u00f3n hasta que corrijas todas las ocurrencias de <code>AX<\/code>.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >procedure TMyClass.Foo;\nvar\n  X: Integer\nbegin\n...\nend;<\/pre><\/div>\n\n\n\n<p>No est\u00e1 permitido.<\/p>\n\n\n\n<p>Tambi\u00e9n se aplica a los descendientes de <code>TMyClass<\/code>; en <code>TMyClassDescendant<\/code> tampoco puedes declarar <code>X<\/code> (campos, variables locales, etc.).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Tratando a los punteros como arrays, sin usar <code>^<\/code> (desreferenciaci\u00f3n)<\/strong><\/h2>\n\n\n\n<p>En el modo FPC ObjFpc si tu tienes:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >X: ^Integer;<\/pre><\/div>\n\n\n\n<p>Y usas:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >X[2]<\/pre><\/div>\n\n\n\n<p>Entonces ObjFPC lo trata de forma similar a C: es como si <strong>X<\/strong> fuera un puntero a un <em>array<\/em> de <code>Integer<\/code>, y quieres el segundo elemento. As\u00ed que:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >Y: array [0..999] of Integer;\nX: ^Integer;\n\n...\nX := @(Y[10]);\nAssert(X^ = Y[10]);\nAssert(X[0] = Y[10]);\nAssert(X[2] = Y[12]);<\/pre><\/div>\n\n\n\n<p>TODO<strong>:<\/strong> restaurar mi demo: <code>array_ptrs.lpr<\/code><\/p>\n\n\n\n<p>En Delphi, esto no est\u00e1 permitido; no puedes tratar un puntero a <code>TTT<\/code> como un array de <code>TTT<\/code>.<\/p>\n\n\n\n<p>Por otro lado, en Delphi hay un atajo diferente. Es decir, puedes <strong>simplemente omitir el <code>^<\/code> si el tipo <\/strong><strong>TODO:<\/strong> restaurar mi demo: <code>array_ptrs.lpr<\/code><\/p>\n\n\n\n<p>En Delphi, esto no est\u00e1 permitido; no puedes tratar un puntero a <code>TTT<\/code> como un array de <code>TTT<\/code>.<\/p>\n\n\n\n<p>Por otro lado, en Delphi hay un atajo diferente. Es decir, puedes<strong> simplemente omitir el <code>^<\/code> si el tipo <\/strong>desreferenciado ya es un array. Es decir, si <strong>X<\/strong> es un puntero y escribes:. Es decir, si <strong>X<\/strong> es un puntero y escribes:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >X[2]<\/pre><\/div>\n\n\n\n<p>Entonces Delphi trata esto como:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >X^[2]<\/pre><\/div>\n\n\n\n<p>Obviamente esto tiene sentido solamente si <em>X<\/em> es un puntero a una array como este:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >type\n  TIntegers = array [0..999] of Integer;\nvar\n  X: ^TIntegers;<\/pre><\/div>\n\n\n\n<p>Un truco muy utilizado en Delphi es declarar un <em>array<\/em> \u00abinfinito\u00bb (de hecho, tan largo como sea posible compilar, de ah\u00ed el truco de <code>MaxInt<\/code>), y usarlo como un tipo de puntero c\u00f3modo:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >type\n  TMyRecord = record A, B, C: Integer; ... whatever else ... end;\n  TMyRecords = array [0..MaxInt div SizeOf(TMyRecord) - 1] of TMyRecord;\n  PMyRecords = ^TMyRecords;\nvar\n  MyRecords: PMyRecords;\n\n  ... \/\/ and for example you can do:\n  MyRecords := GetMem(SizeOf(TMyRecord) * 10);\n  \/\/ in Delphi (real Delphi or delphi mode in FPC) you can do:\n  MyRecords[1].A := 123;\n  \/\/ in both Delphi mode and objfpc mode you can also do it without omitting ^:\n  MyRecords^[1].A := 123;<\/pre><\/div>\n\n\n\n<p>En el modo FPC ObjFpc, lo har\u00edas m\u00e1s bien as\u00ed:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >type\n  TMyRecord = record A, B, C: Integer; ... whatever else ... end;\n  PMyRecord = ^TMyRecord;\nvar\n  MyRecord: PMyRecord;\n\n  ... \/\/ and for example you can do:\n  MyRecord := GetMem(SizeOf(TMyRecord) * 10);\n  \/\/ not writing ^ means that MyRecord is automatically treated as a pointer\n  \/\/ to an array of whatever it was declared.\n  MyRecord[1].A := 123;<\/pre><\/div>\n\n\n\n<p>Hay un peque\u00f1o \u00abtruco\u00bb en todo esto, un lugar donde tanto Delphi (el Delphi real o <code>{$mode delphi}<\/code> en FPC) como el modo ObjFPC compilan, pero interpretan de forma diferente. Recuerda el ejemplo anterior del <em>array<\/em> infinito:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >type\n  TMyRecord = record A, B, C: Integer; ... whatever else ... end;\n  TMyRecords = array [0..MaxInt div SizeOf(TMyRecord) - 1] of TMyRecord;\n  PMyRecords = ^TMyRecords;\nvar\n  MyRecords: PMyRecords;\n\n  ... \/\/ and for example you can do:\n  MyRecords := GetMem(SizeOf(TMyRecord) * 10);\n  \/\/ in Delphi (real Delphi or {$mode delphi} in FPC) you can do:\n  MyRecords[1].A := 123;<\/pre><\/div>\n\n\n\n<p>El truco es que, de hecho, puedes usar <code>MyRecords[1].A<\/code> tambi\u00e9n en modo ObjFPC. Compilar\u00e1, pero significar\u00e1 algo que probablemente no quieres. <code>MyRecords<\/code> es entonces tratado como un <em>array<\/em> de lo que sea que apunte&#8230; \u00a1as\u00ed que <code>MyRecords<\/code> es un puntero a un <em>array<\/em> de <em>arrays<\/em> <code>TMyRecords<\/code>! <code>MyRecords[1]<\/code> se refiere al segundo <em>array<\/em>. Definitivamente no es lo que quer\u00edas, y est\u00e1 fuera de la memoria asignada.<\/p>\n\n\n\n<p><strong>Moraleja:<\/strong> no omitas el operador <code>^<\/code>. O presta atenci\u00f3n a tu modo: tanto ObjFPC como Delphi tienen una idea diferente de cu\u00e1ndo puedes omitirlo y c\u00f3mo se interpreta.<\/p>\n\n\n\n<p><strong>Nota:<\/strong> Versiones posteriores de Delphi introducen algo muy similar a FPC, <code>{$pointermath on}<\/code>. Esto hace que Delphi se comporte bastante parecido a lo que hace FPC en este aspecto y, en mi humilde opini\u00f3n, es una buena idea. Nuestro <code>castleconf.inc<\/code> (usado en todas las unidades CGE) lo define ahora, te recomiendo que tambi\u00e9n lo uses en tus aplicaciones donde tenga sentido. Consulta<a href=\"https:\/\/docwihttps:\/\/docwiki.embarcadero.com\/RADStudio\/Sydney\/en\/Pointer_Math_(Delphi\"> https:\/\/docwiki.embarcadero.com\/RADStudio\/Sydney\/en\/Pointer_Math_(Delphi)<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>El String por defecto es <code>ShortString<\/code> en modo ObjFpc, probablemente querr\u00e1s cambiarlo a <code>AnsiString<\/code>.<\/strong><\/h2>\n\n\n\n<p>Finalmente, una peque\u00f1a diferencia que en realidad es una ligera molestia del modo ObjFPC. En ObjFPC, por defecto, <strong><em><code>s<\/code><\/em><\/strong><em><code>tring<\/code> = <code>ShortString<\/code><\/em>. Es por eso que casi siempre deber\u00edas hacer:<\/p>\n\n\n\n<p>Al principio de tus fuentes, para usar la cadena moderna de Object Pascal.<\/p>\n\n\n\n<p>No hagas esto, ya que casi nunca querr\u00e1s lidiar con <em><code>ShortString<\/code> <\/em>y sus limitaciones en c\u00f3digo moderno:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >{$mode objfpc} \/\/ problamente no quieras hacer esto. Quiz\u00e1s quieras a\u00f1adir {$H+} como est\u00e1 encima<\/pre><\/div>\n\n\n\n<p><br>En contraste, <code><em>{$mode delphi}<\/em><\/code><strong> <\/strong>cambia autom\u00e1ticamente <code>string<\/code> para que sea un alias de la moderna <em><code>AnsiString<\/code> <\/em>por defecto. As\u00ed que, simplemente usando:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >{$mode delphi}<\/pre><\/div>\n\n\n\n<p>Es suficiente. Por supuesto, tambi\u00e9n puedes usar <code><em>{$mode delphi}{$H+}<\/em><\/code>, pero entonces el <code><em>{$H+}<\/em><\/code> es simplemente superfluo.<\/p>\n\n\n\n<p><em>ObjFPC <\/em>se comporta as\u00ed (no implica que <code>string<\/code> sea <code><em>AnsiString<\/em><\/code>) por <strong>compatibilidad con versiones anteriores<\/strong>. Ha habido discusiones sobre cambiar este comportamiento por defecto (y cambiar el modo por defecto de <em>FPC<\/em>), pero (hasta ahora) el argumento de la compatibilidad con versiones anteriores prevalece.<\/p>\n\n\n\n<p>Ten en cuenta que el Delphi real, en sus versiones recientes, hace algo incluso diferente hoy en d\u00eda: el <code>String<\/code> por defecto es <code><em>UnicodeString<\/em><\/code>, no <em><code>ShortString<\/code> <\/em>ni <code><em>AnsiString<\/em><\/code>. En CGE, lo manejamos ajust\u00e1ndonos a los valores por defecto de ambos compiladores: la mayor parte del c\u00f3digo deber\u00eda usar simplemente <code>String<\/code>, y estar preparado para que sea de 8 bits en FPC y de 16 bits en Delphi.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Gen\u00e9ricos<\/h2>\n\n\n\n<p>En FPC ObjFpc, debes usar las palabras clave <em><code>generic<\/code> <\/em>y <code><em>specialization<\/em><\/code>, las cuales puedes omitir en Delphi (o en el modo FPC Delphi).<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:default decode:true \" >type\n  generic TMyCalculator&lt;T&gt; = class\n    Value: T;\n    procedure Add(const A: T);\n  end;\n\n  TMyFloatCalculator = specialize TMyCalculator&lt;Single&gt;;<\/pre><\/div>\n\n\n\n<p>(fuente: <a href=\"https:\/\/github.com\/michaliskambi\/modern-pascal-introduction\/blob\/master\/code-samples\/generics.lpr\">https:\/\/github.com\/michaliskambi\/modern-pascal-introduction\/blob\/master\/code-samples\/generics.lpr<\/a> )<\/p>\n\n\n\n<p>En FPC ObjFpc, debes usar las palabras clave <strong><code>generic<\/code><\/strong> y <strong><code>specialization<\/code><\/strong>, las cuales puedes omitir en Delphi (o en el modo FPC Delphi).<\/p>\n\n\n\n<p>Esto es: <\/p>\n\n\n\n<p>En Delphi, o en modo FPC Delphi, simplemente eliminas estas palabras clave. O las rodeas con <code>{$ifdef FPC_OBJFPC}\u2026\u200b{$endif}<\/code>. En Castle Game Engine, las rodeamos con <code>{$ifdef FPC}\u2026\u200b{$endif}<\/code> para simplificar y confiar en la suposici\u00f3n de que \u00abcuando el <em>engine<\/em> es compilado por FPC, siempre est\u00e1 en modo ObjFpc\u00bb.<\/p>\n\n\n\n<p>Adem\u00e1s, la implementaci\u00f3n de FPC (tanto en modo ObjFpc como Delphi) es, en este momento, un poco <strong>menos estricta<\/strong> que la implementaci\u00f3n de Delphi en lo que respecta a la comprobaci\u00f3n de la correcci\u00f3n de tipos de los gen\u00e9ricos. Es decir:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>FPC<\/strong> verificar\u00e1 el 100% de la correcci\u00f3n en la especializaci\u00f3n y permitir\u00e1 definir algunos gen\u00e9ricos que pueden, o no, ser correctos.<\/li>\n\n\n\n<li><strong>Delphi<\/strong> es m\u00e1s estricto en este sentido; se realizan m\u00e1s comprobaciones ya en la definici\u00f3n del gen\u00e9rico. El uso de <strong>restricciones gen\u00e9ricas<\/strong> es m\u00e1s a menudo necesario en Delphi.<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nota: Este art\u00edculo es una traducci\u00f3n de https:\/\/github.com\/modern-pascal\/modern-pascal-introduction\/wiki\/Some-differences-betwen-FPC-ObjFpc-mode-and-Delphi-(and-FPC-Delphi-mode) escrito por Michalis Kamburelis Introducci\u00f3n El compilador FPC ofrece algunos \u00abmodos de sintaxis\u00bb. Se pueden elegir mediante: Existen algunos modos de sintaxis en FPC, pero en esta p\u00e1gina nos centraremos en dos que son los m\u00e1s populares: la sintaxis ObjFpc y la sintaxis Delphi. Ofrecen 100% las [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1041","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/pages\/1041","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1041"}],"version-history":[{"count":9,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/pages\/1041\/revisions"}],"predecessor-version":[{"id":1050,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/pages\/1041\/revisions\/1050"}],"wp:attachment":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1041"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}