|
|
Copyright (C) 2001-2005 Free Software Foundation. Inc
Se concede permiso para copiar, distribuir y/o modificar este documento bajo los t�rminos de la Licencia de Documentaci�n Libre GNU, Versi�n 1.1 o cualquier otra versi�n posterior publicada por la Free Software Foundation; sin ninguna Secci�n Invariante, sin Texto de Cubierta Frontal, sin Texto de Cubierta Trasera.
Se incluye una copia de esta licencia en la secci�n titulada “Copia de la Documentaci�n” en el Manual de GNU Pascal.
�ltima actualizaci�n 2005-01-01.
Los Est�ndares de Codificaci�n de GNU Pascal fueron dise�ados por un grupo de voluntarios del proyecto GNU Pascal. El objetivo de este documento es extender los Estandares de Codificaci�n GNU con informaci�n espec�fica relativa a la programaci�n en Pascal. De hecho, la informaci�n contenida en el Est�ndar de Codificaci�n de GNU en su mayor parte pertenece a programas escritos en lenguaje C. Por otra parte, tambi�n explican muchas de las reglas y principios que son �tiles para escribir programas portables, confiables y robustos. La mayor�a de esos temas generales podr�an compartirse con este documento con s�lo unas notas espec�ficas, as� que se dan referencias cruzadas las cu�les le dirigir�n a informaci�n m�s extensa contenida en el Est�ndar de Codificaci�n GNU.
Esta liberaci�n de los Est�ndares de Codificaci�n de GNU Pascal se actualiz� por �ltima vez el 2005-01-01.
Los Est�ndares de Codificaci�n de GNU Pascal est�n disponibles como parte de las distribuci�n de GPC – en las distribuciones binarias como ficheros info, en las distribuciones fuente tambi�n como ficheros Texinfo desde los que se pueden generar m�s formatos como HTML, PostScript y PDF. Una versi�n HTML est� disponible tambi�n en la p�gina inicial de GPC, http://www.gnu-pascal.de.
Correcciones o sugerencias para este documento deber�an enviarse a la lista de correo de Documentaci�n de Compilador de Pascal de GNU, gpc-doc@gnu.de. Si hace una sugerencia, por favor, incluya la palabra sugerida para ella; nuestro tiempo es limitado. Un diff contextual al fichero Texinfo “fuente” Texinfo se agradecer� mucho, si es posible. Si no puede proporcionar un diff contextual, por favor si�ntase libre para enviar por correo su sugerencia igualmente.
Esa gente son los tiranos que est�n imponiendo si estilo de codificaci�n a la comunidad: Peter Gerwinski peter(at)gerwinski.de, Frank Heckenbach frank(at)pascal.gnu.de, Markus Gerwinski markus(at)gerwinski.de, Dominik Freche dominik.freche(at)gmx.net, Nicola Girardi nicola(at)g-n-u.de.
Este cap�tulo de los Est�ndares de Codificaci�n GNU discuten c�mo puede asegurarse de que el software GNU evita dificultades legales, y otras cuestiones relacionadas. See Propiedad Intelectual (est�ndares).
Este cap�tulo trata sobre las cuestiones que deber�a tener en cuenta cuando dise�e su programa.
Apoyamos la idea de que una variedad de lengajes de programaci�n es una cosa buena y que lenguajes diferentes son apropiados para diferentes clases de tareas. Al contrario que los Est�ndares de Codificaci�n GNU (see Lenguaje del Fuente (est�ndares)), no le intentamos persuadir para que utilice C, Pascal o cualquier otro lenguaje para todo.
Si est� leyendo esto, ya ha decidido probablemente usar Pascal para alg�n proyecto o est� considerando usarlo. Esta documentaci�n le sugerir� c�mo dar formato a su c�digo pascal cuando lo haga.
Puede enlazar una biblioteca C o un c�digo objeto C a su programa Pascal o unidad. Por favor vea la descripci�n en el manual de GPC sobre c�mo hacer esto (see Otros Lenguajes (gpc)).
En particular, para acceder a bibliotecas C, recomendamos encarecidamente usar encapsulados C. Esto es una custi�n de portabilidad. Quiz� haya cambios en versiones diferentes de la biblioteca que puedan afectar directamente a declaraciones external en el c�digo Pascal. Deber�a actualizar la encapsulaci�n para que los programas Pascal o unidades funcionen con cualquier versi�n de la biblioteca que tenga.
Hay veces cuando se tratan paquetes grandes que no se puede mantener la compatibilidad f�cilmente entre versiones diferentes de los mismos paquetes. En este caso, puede enlazar directamente a la biblioteca con la que va trabajar, y enlazar un fichero C suplementario que no contine nada excepto una verificaci�n de la versi�n. Este es un ejemplo:
#include <foo.h>
#if FOO_MAJOR != 1 || FOO_MINOR != 2
#error The GPC interface for libfoo was only written for libfoo-1.2.
#error Please get libfoo-1.2 or check for a version of the GPC interface
#error matching your version of libfoo.
#endif
N�tese el uso de != en vez de < o >, para efectuar una verificaci�n de versi�n muy estricta. Por favor tenga en mente que esto es correcto si hay s�lo una implementaci�n de una biblioteca, p.e., puede hacer esto con GTK, pero no puede hacer esto con libc, libm, curses etc.
Est� planeado un traductor autom�tico de cabeceras que har� el encapsulamiento en C superfluo. Este es un trabajo no trivial y no se est� seguro de cu�ndo ser� esto posible, as� que tomar� al menos algo de tiempo el que est� disponible.
Puede asumir que el Compilador de C de GNU se usa para compilar los encapsulados y, en general, cualquier c�digo C que enlace a su c�digo Pascal. La raz�n para esta suposici�n es que s�lo el Compilador C de GNU est� garantizado que tenga todas las convenciones compatibles con el Compilador Pascal GNU en cada plataforma en la que funciona, coo comparten ambos el mismo backend. Tambi�n, el Compilador Pascal de GNU se contruye siempre junto con el Compilador C de GNU, as� que gcc puede asumirse que est� disponible donde lo est� gpc.
Se proporcionan multitud de facilidades en GNU Pascal que extienden el lenguage Pascal est�ndar. El decidir si usar estas extensiones al implementar su programa es una discusi�n tediosa.
Por un lado, el uso de estas extensiones puede hacer un programa m�s limpio. Por el otro lado, la gente no ser� capaz de construir el programa a no ser que tenga disponible el Compilador de Pascal de GNU. Esto quiz� haga que el programa no compile al usar otros compiladores.
En general, es mejor mantener compatibilidad con otros compiladores o a los est�ndares del lenguaje, si esta compatibilidad es f�cil de lograr. En general, tristemente, para lograr compatibilidad se tienen considerables desventajas. For ejemplo, quiz� tenga que a�adir cantidad de {$ifdef}s para tener compatibilidad con algunos compiladores no est�ndar, los cuales hacen el c�digo m�s dif�cil de leer, escribir, verificar y mantener. Adem�s los{$ifdef}s en s� mismos son estensiones no est�ndar, as� que no se gana mucho de esta manera.
Al final, sugerimis no tomarse excesivas molestias en la compatibilidadd. Todos los interfaces del Compilador de Pascal de GNU (compilador y Run Time System) son abiertos. Esto significa que pueden ser implementados para otros compiladores cuando se necesiten o incluso los mismos fuentes pueden ser usados gracias a que la licencia los preserva (lea m�s acerca de la Licencia P�blica General GNU en http://www.gnu.org/copyleft/gpl.html), en vez de enrrarecer el c�digo no usando las caracter�sticas extendidas. Un elemplo (limitado) de esta estrategia est� en la unidad gpc-bp para Borland Pascal, distribu�da con el Compilador Pascal de GNU. Quiz� quiera echarle un vistazo a su interfaz para ver exactamente qu� contiene, Es f�cil extenderlo para m�s caracter�sticas de compatibilidad cuando se necesiten, aunque hay caracter�sticas que no pueden ser f�cilmente emuladas (en particular aquellas que tienen una sintaxis especial).
Por favor, no use las siguientes caracter�sticas, especialmente aquellas que fuerom implementadas tan s�lo para compatibilidad hacia atr�s.
Str (Foo, s);
s := 'Hola ' + s;
FillChar (s, SizeOf (s), 0);
para borrar una cadena, es incorrecto en GNU Pascal e ineficiente incluso en Borland Pascal, debido a que lo siguiente podr�a ser usado:
s := '';
Esto tan s�lo borrar�a el campo de longitud de la cadena s.
Los Est�ndares de Codificaci�n GNU tienen buenas sentencias en este tema. See Uo de Extensiones (est�ndares).
Este cap�tulo de los Est�ndares de Codificaci�n GNU describen convenciones para escribir software robusto. Tambi�n describe est�ndares generales para mensajes de error, el interfaz de l�nea de �rdenesm y c�mo deber�an comportarse las bibliotecas. Le animamos a leer esa parte de los Est�ndares de Codificacion GNU. See Comportamiento del Programa (est�ndares).
Aqu� est�n las notas especiales para la programaci�n en Pascal, en cualquier caso.
La elecci�n entre funciones de se�ales, discutidad en los Est�ndares de Codificaci�n GNU, se hacen en el Run Time System as� que no tiene que preocuparse por ellas.
Otra discrepancia con los Est�ndares de Codificaci�n GNU es el comportamiento predeterminado para verificaci�n de errores que detecten condiciones “imposibles”. No sugerimos tan s�lo abortar. Esto implica que cada usuario puede ser un programador, pero no creemos que esto sea realista. Nuestra opci�n es imprimir un mensaje de error razonable para que los usuarios puedan informar del descripciones del fallo a los programadores que no se dieron cuenta del fallo por s� mismos o que no podr�an reproducirlo.
Adem�s, los Est�ndares de Codificaci�n de GNU sugieren verificar cada llamada de systema para un error devuelto. Eso se aplica a C. En Pascal, la verificaci�n de error a menudo es autom�tica, as� que no necesita preocuparse de verificar errores. Muchas rutinas de E/S no devuelven un valor (por ejemplo, Reset), pero aquellas que lo devuelben deber�an normalmente ser verificadas.
Desde luego, puede desactivar la verificaci�n autom�tica de errores y buscarlos usted mismo. De hecho, algunos errores quiz� causen que el programa se aborte sin un mensaje de error. En su lugar, especialmente en unidades o m�dulos, quiz� quiera informar de errores y darle al usuario una oportunidad de interenir y corregir las cosas. Para hacer esto, debe usar la directiva del compilador {$I-} , y verificar el valor de IOResult (see IOResult (gpc)) o las variables de error globales como InOutRes (see InOutRes (gpc)). Note que las rutinas de E/S retornan inmediatamente si InOutRes est� puesto, as� que no es necesario verificarlas despu�s de cada operaci�n, as� que lo siguiente es posible:
{$local I-}
Rewrite (f, 'bla');
WriteLn (f, 'foo');
WriteLn (f, 'bar');
WriteLn (f, 'baz');
Close (f);
{$endlocal}
if InOutRes <> 0 then
begin
WriteLn (StdErr, GetIOErrorMessage);
...
end;
Sin embargo en su c�digo quiz� quiera tambi�n verificar Rewrite y otras llamadas de apertura, las cu�les son las que tienden a fallar, y evitar� m�s llamadas innecesarias.
Hay un conjunto de rutinas en la unidad GPC para nombrar ficheros temporales, ficheros de configuraci�n y muchos otro material relacionado con nombres de fichero. Las ventajas de usar �stos son que funcionan para distintas clases de sistemas (por ejemplo Unix y DOS), y que los problemas futuros pueden ser corregidos en un s�lo lugar en el Run Time System en vez de en varios programas o unidades diferentes.
En tanto en cuanto a las bibliotecas se refiere, sugerimos que no ponga cada rutina en un fichero separado. Afortunadamente alg�n d�a el Compilador Pascal de GNU har� esto autom�ticamente a nivel del enlazador. En este momento, creemos que lo conveniente para el programador es mucho m�s importante que el tama�o del binario. Tambi�n recomendamos no usar un frefijo en el nombre, debido a que los conflictos con los nombres pueden resueltos por identificadores cualificados (UnitName.RoutineName). Hasta entonces, por favor utilice arreglos temporales cuando surjan conflictos.
Este cap�tulo proporciona consejos acerca de c�mo usar mejor el lenguaje Pascal cuando escriba software. Por supuesto, las reglas se aplican al c�digo publicado �nicamente – si usted por ejemplo quiere comentar cosas fuera con comentarios al estilo antiguo como (* este *), deber�a hacerlo temporalmente y quitarlos antes de distribuir su c�digo. Sin embargo, si nunca sabe cuando se va a publicar el c�digo, es buena idea ce�irse a las reglas desde el principio.
Los nombres de los ficheros de c�digo Pascal deber�an tener el sufijo .pas. El nombre del fichero sin el sufijo deber�a usualmente corresponderse con el nombre del programa/unidad/m�dulo, todo en min�sculas. Deber�a haber �nicamente un s�lo programa/unidad/m�dulo en un fichero.
El c�digo debe compilarse con el flag -Wall, con y sin el flag -O3 sin advertencias. (See Directivas del Compilador, para saber c�mo deshabilitar intencinalmente ciertas advertencias si es realmente necesario.)
No utilice la variable autom�tica Result en las funciones. Si quiere una, decl�rela:
function Foo (...) = Bar: Integer;
Utilice la declaraci�n con =, no sin �l, a no ser que quiera ser estrictamente compatible con PXSC.
Si una funci�n devuelve un Boolean para indicar �xito, True deber�a significar �xito y False fracaso, a diferencia de algunas rutinas de C donde 0 significa �xito.
Evite goto y sentencias similares, como Exit, Return, Break, Continue. Evite goto a cualquier precio (excepto posiblemente un goto no local para retornar desde funciones profundamente anidadas, recursivas en caso de error). Evite los otros si es posible con un esfuerzo razonable. Si ello requiere una variable Boolean adicional, esto cuenta como una excusa para usar estas sentencias si realmente quiere. N�tese que a menudo, el c�digo se hace significativamente m�s simple no usando Break etc. y usando en su lugar una condici�n de bucle mejor o una clase de bucle diferente.
Nunca modifique los contadores de un bucle for, o conf�e en su valor despu�s del bucle. (Bien, esto no es meramente un estilo de codificaci�n, es la deficnici�n de Pascal. Hacer estas cosas producir�n resultados indefinidos.)
Nunca conf�e en comportamientos no definidos. Por ejemplo, que las variables globales aparenten estar inicializadas a 0 al comienzo de un programa, o quiz�s que algunas veces la memoria reservada nueva aparente estar inicializada, o que los contadores de bucle for aparenten tener cierto valor despu�s del bucle – nada de esto est� garantizado, y puede cambiar con cada compilador, plataforma o versi�n. Indefinido significa indefinido, de hecho estas cosas quiz� parezcan funcionar en todos los sistemas que ha verificado y con otros 42 compiladores signifique exactamente nada.
En comparaci�n, ponga la expresi�n “m�s variables” en el lado izquierdo:
for i := 1 to 10 do
if a[i] = Foo then
for j := 1 to 10 do
if b[j] = a[i] then ...
Considerando la segunda l�nea del ejemplo de arriba, la expresi�n a la
izquierda (a[i]) var�a en cada vuelta, pero el lado derecho
(Foo) no. (En este caso asumimos que Foo es una constante
o una funci�n que no depende de i u alg�n otro dato global.
De otra forma quiz� tendr�a m�s sentido poner Foo a la izquierda,
y quiz� usar un comentario extra para hacer notar esto.)
la �ltima l�nea del ejemplo de arriba quiz� parezca extra�a, porque
b[j] y a[i] quiz� parezcan como si tuviesen el mismo
nivel de “variablidad”. Pero de hecho, j var�a m�s a menudo que
i, ya que cada vez que i cambia, j ha cambiado
ya 10 veces.
Evite la duplicaci�n de c�digo. Es sencilo copiar el c�digo, pero convierte el mantenimiento en una pesadilla al tener que cambiar varios lugares similares. Use rutinas o subrutinas, unidades o m�dulos, lo que sea. Planifique cada parte del c�digo para que pueda ser extendido. No ponga demasiados trucos en lugares que ser�n probablemente modificados m�s tarde.
No rodee sentencias simples con begin y end, a no ser que tenga que evitar el problema del else colgante o que la �nica l�nea forme el cuerpo de una rutina completa. Vea los ejemplos siguientes:
if foo then
begin
if bar then
baz
end { Avoid the dangling else problem. }
else
qux { Single line statement. }
No escriba inicializadores de unidad vac�os. Esto es lo que no se debe hacer:
...
procedure Foo;
begin
...
end;
begin
end.
En su lugar, simplemente:
...
procedure Foo;
begin
...
end;
end.
No escriba declaraciones que no se usen, excepto en los interfaces que est�n destinados a ser usados por el importador.
Recuerde que los Booleanos son Booleanos. Por favor use if Foo then en lugar de if Foo = True then, y if not Foo then en vez de if Foo = False then. Adem�s, emplee until False en lugar de until 1 = 0 – esto parece m�s inteligente. Otra situaci�n com�n es Foo := Expression en vez de if Expression then Foo := True else Foo := False.
Evite duplicar identificadores globales, por ejemplo no sobrecargue un identificador integrado, aunque el Compilador de GNU Pascal permite esto, y no utilice el mismo identificador global en varias unidades o m�dulos. (Esta caracter�stica es presente en el Compilador Pascal de GNU llam�ndose “identificadores cualificados” pero todav�a no la use.)
Desalentamos el uso de variables globales para prop�sitos no globales
(e.g., el uso de una variable Contador usada como un contador en
varias rutinas locales). Declare una variable contador para cada rutina
que lo necesite, es su lugar. En general, esto tambi�n permite una mejor
optimizaci�n del c�digo generado.
Cuando necesite un bucle infinito (que pueda ser abandonado con
Break), le sugerimos que utilice un repeat mejor que un bucle
while porque desplaza el c�digo menos a la derecha (al menos si hay
m�s de una sentencia dentro del bucle). Esto es:
repeat
...
until False
En vez de:
while True do
begin
...
end
Al igual que se establece en la documentaci�n de la biblioteca de C (see Verificaci�n de Consistencia (libc)), cuando se escribe un programa, a menudo es una buena idea poner verificaciones para las violaciones de asunciones b�sicas. Considere el siguiente c�digo en Pascal:
procedure HacerAlgoEnAPString (StrPtr:PString);
Puede asumir impl�citamente que el procedimiento anterior nunca ser�
llamado con nil como argumento, pero es m�s seguro verificar
la “condici�n imposible”, por ejemplo, verificando que
StrPtr es distinto de nil, de este modo:
procedure HacerAlgoEnAPString(StrPtr:PString);
begin
Assert (Str<>nil);
...
end;
Cuando esta verificaci�n falla, el programa produce un error en tiempo de ejecuci�n. Entonces puede deducir que el c�digo que llama a este procedimiento es defectuoso (o que necesita extender esta rutina en particular), as� que esto puede ser muy �til para localizar el problema. En otras palabras, verificar asunciones b�sicas al principio del cuerpo de una rutina u otro lugar estrat�gico es la manera correcta de asegurarse de que una funci�n no ser� usada de fora equivocada.
La biblioteca de C de GNU proporciona la macro assert para
esta clase de verificaciones. GNU Pascal proporciona su contraparte
Pascal que se llama Assert, la cu�l se comporta de manera un
poco diferente. Assert no abortar� su programa, sino que
causar� un error en tiempo de ejecuci�n (see Assert (gpc)) el
cu�l, podr� por ejemplo, atraparlo usando la unidad Trap
(see Trap (gpc)).
Una vez que piense que su programa est� depurado, puede desactivar
las verificaciones de errores efectuadas por la rutina Assert
mediante la recompilaci�n con el indicador --no-assertions.
No se necesita ning�n cambio en el c�digopara desactivar estas
verificaciones. Los efectos laterales en el argumento a
Assert todav�a son evaluados (a diferencia de C), as� que es
correcto escribir:
Assert (MiFuncion (Foo,Bar) > 0)
Esto siempre llamar� a MiFuncion, pero s�lo se asegurar� que
el resultado es positivo cuando no se de --no-assertions.
Sin embargo, se recomienda que no desactive la verificaci�n de consistencia a no ser que no pueda consentir que el programa se ejecute un poco m�s lentamente.
Lo primero de todo, evite espacios innecesarios al final de las l�neas. Tambi�n recuerde no salvar el fichero con caracteres TAB, debido a que diferentes editores o diferentes configuraciones los interpretar�n con una cantidad diferente de espacios, rompiendo entonces la indentaci�n. (Si usa GNU Emacs, la funci�n untabify es �til; si usa VIM, la opci�n expandtab (:set et); en PENG, puede usar la opci�n Expand tabs.)
Por favor evite el uso de cualquier car�cter de control, excepto el de l�na nueva, por supuesto. Esto significa nada de caracteres de alimentaci�nd e formularios (#12), o caracteres de p�gina nueva. Estos se recomiendan en los Est�ndares de Codificaci�n de GNU para separar las partes l�gicas de un fichero,pero no los use al menos en c�digo Pascal. No use el car�cter SUB ni el (#26), utilizado incorrectamente en DOS como indicador de finde fichero. Los editores antiguos de DOS pon�an este car�cter al final de cada fichero sin ninguna buena raz�n, aunque el sistema de ficheros FAT sabe acerca del fin de un fichero por s� mismo.
Recomendamos una longitud de l�nea m�xima de 68 caracteres, de esta manera puede ser impreso en TeX con el tipo predeterminado en A4, o 78 caracteres, para las pantallas de 80 columnas de ancho. Esta no es una regla fija porque las l�neas rotas a menudo decrementan la legibilidad del c�digo fuente.
Utilice l�neas vac�as entre bloques. Los bloques sin comentarios largos, secciones type, const, var, label, cuerpos de rutinas, inicializadores/finalizadores de unidades/m�dulos, l�neas program, unit, interface, implementation, module, export, uses, import, directivas globales del compilaci�n. Junto a los comentarios largos que se refieran a la siguiete declaraci�n, ponga s�lo una l�nea vac�a antes del comentario, no entre el comentario y la declaraci�n misma. Una excepci�n especial es entre bloques dentro de la misma rutina – no use l�neas vac�as all�. Por ejemplo:
procedure Short;
var
Foo: Integer;
Bar: Char;
begin
...
end;
Pero recuerde usar l�neas vac�as para separar subrutinas, como lo siguiente:
procedure Long;
const
...
var
variables usadas por Sub ...
procedure Sub;
var
...
begin
...
end;
var
variables no usadas por Sub ...
begin
...
end;
N�tese que no deber�a ponerse una l�nea vac�a despu�s de la declaraci�n de la rutina principal, a no ser que le siga inmediatamente una declaraci�n de subrutina. Si se hiciera al contrario, la declaraci�n de la rutina principal podr�a semejarse a una declaraci�n “forward”.
D�se cuenta que en el fragmento de c�digo de arriba separamos las variables locales (o constantes) antes y despu�s de la subrutina – esto no es obligatorio.
Desde luego, lo que dijimos para las subrutinas es v�lido tambi�n para sub-subrutinas de cualquier profundidad.
Deber�a ponerse una l�nea vac�a entre declaraciones del mismo tipo, donde sea apropiado, para separarlas l�gicamente. En caso de que haya un comentario antes de la declaraci�n, la l�nea vac�a debe estar antes del comentario. En caso contrario, la l�nea vac�a va antes de la declaraci�n.
Las l�neas vac�as pueden ser usadas en comentarios largos para separar par�grafos.
No se ponen l�neas vac�as al principio o al final de un fichero, s�lo una l�nea nueva al final. No m�ltiples l�neas nuevas.
los comentarios deber�an ser colocados entre llaves como esto:
{ Este es un comentario bonito. }
No utilice los comentarios del estilo antiguo entre par�ntesis y asteriscos, como esto:
(* Este es un comentario feo. Uno de los que no debe escribir. *)
Tambi�n, no use comentarios introducidos por una barra oblicua doble:
// Otra clase de comentario que no debe escribir.
Aunque Pascal ISO expl�citamente permite comentarios mezclados, el Compilador de Pascal de GNU no los acepta a no ser que active la opci�n con la directiva de compilador apropiada {$mixed-comments} – pero debe quere hacerlo. Aqu� se muestran un par de ejemplos de comentarios mezclados que no deber�a seguir:
(* Este ... }
{ ... y ese. *)
Tambi�n, intente evitar comentarios anidados como { { Este otro } }. Estos son correctos si quiere poner alg�n TeX en un comentario o algo m�s ex�tico. Si por cualquier raz�n tuviera que usar comentarios anidados, necesitar� activar la opci�n con el interruptor del compilador apropiado, que es {$nested-comments}. No utilice la opcion de l�nea de �rdenes --nested-comments. Ponga esta clase de opciones en el fuente para que cualquiera intentando compilarlo no tenga que adivinar qu� opciones de l�nea de �rdenes se necesitan, y porque las opciones de l�nea de �rdenes afectar�an a todos los ficheros fuente, por ejem. cuando compile un proyecto con varios m�dulos/unidades.
Por favor, escriba los comentarios en sus programas en ingl�s, porque el ingl�s es el �nico idioma que casi todos los programadores en todos los pa�ses pueden leer. Si no escribe bien en ingl�s, por favor escriba los comentarios tan bien como pueda y entonces pida a otras personas que le ayuden a reescribirlos. Si no puede escribir comentarios en ingl�s, por favor, encuentre a alguien que trabaje con usted y le traduzca los comentarios al ingl�s.
Deber�a adoptar “Espaciado franc�s”, por ejem. s�lo un espacio al final de la frase. De esta manera, no puede usar el M-a de GNU Emacs y la combinaci�n de teclas M-e para moverse a trav�s de la frase. Esperamos que pueda vivir sin ello. Adem�s, por favor ponga �nicamente un espacio despu�s de la llave de apertura del comentario y antes de la llave de cierre.
Si un comentario se refiere �nicamente a una l�nea de c�digo, posiblemente escr�balo despu�s de la l�nea de c�digo, en la misma l�nea, separado del c�digo por dos espacios. Esto est� tambi�n permitido para la secci�n de interfaz de una unidad y para las variables globales. M�s a menudo querr� escribir esta clase de comentarios detr�s de los campos de registro/objeto. En otros casos, los comentarios van en una o m�s l�neas propias, como esto:
{ foo bar baz }
O:
{ foo bar
baz }
O Con par�grafos:
{ foo bar
baz
qux }
Los comentarios necesitan ser colocados antes del c�digo que describenm y necesitan tener el mismo nivel de indentaci�n. Este ejemplo deber�a hacer esto claro:
{ Mis tipos. }
type
...
type
{ Mis primeros tipos. }
...
begin
{ Mi primera sentencia. }
Bla;
{ Inicio del bucle. }
repeat
{ Cuerpo del bucle. }
...
{ Finaliza cuando Algo ocurre. }
until Algo
end;
N�tese la posici�n para el comentario until.
Los comentarios describiendo una declaraci�n global deber�an estar en una o m�s l�neas propias, inmediantamente antes de la declaraci�n. Por ejemplo:
{ Esto es Foo. Hace esto y lo otro. }
procedure Foo;
No escriba comentarios “triviales” como los que se listan en los ejemplos anteriores. Deber�a evitar los comentarios escribiendo c�digo claro. Linus Torvalds apunta esto remarcadamente en el Estilo de Codificaci�n del N�cleo:
Los comentarios son buenos, pero tambi�n est� el peligro de la sobrecomentaci�n. Nunca intente explicar c�mo funciona el c�digo en un comentario: es mucho mejor escribir c�digo en que el funcionamiento sea obvio, y es un desperdicio de tiempo explicar c�digo malamente escrito. Gereralmente, se quiere que los comentarios digan qu� hace el c�digo no c�mo.
(Note que nosotros nos desviamos un poquito del estilo de codificaci�n de Linus.)
El c�digo “peculiar”, “Tricky” es equivalente a ser comentado. Definimos como “peculiar” el c�digo que hace cosas que no som obvias, bas�ndose en asunciones no obvias, tiene implicaciones no obvias, hay algo que notar cuando se cambie, no es lo que parace a primera vista, tiene un efecto lateral, o requiere que otra parte del c�digo fuente sea cambiada simult�neamente con �l. El codigo peculiar deber�a seer usado muy de vez en cuando.
En el caso de que el comentario se refiera a algun otro lugar en el c�digo, sea en el mismo fichero o en uno diferente, por favor refi�rase a �l no por el n�mero de l�nea (esto cambiar� muy a menudo) sino por el nombre de la rutina o el contexto. Adem�s, piense si es �til poner un comentario en el otro lugar refiri�ndose a �ste. (No siempre, pero a veces esto nos ha sido �til).
Para comentar partes del c�digo que no deban compilarse, necesita rodearlas con {$if False} ... {$endif} en vez de usar un comentario.
Para separar partes l�gicas dentro de m�dulos grandes o unidades, puede usar un comentario especial – sugerimos un patr�n fijo que sea f�cilmente encontrable:
{@secci�n Nombre de la secci�n}
{@subsecci�n Nombre dela subsecci�n}
N�tese que ning�n espacio sigue a la llave de apertura o precede a la llave de cierre en este caso.
Un m�dulo o unidad o biblioteca deber�a tener un comentario para cada una de las declaraciones del interfaz, de manera que la parte del interfaz del fichero fuente sea una fuente de documentaci�n confiable. Esto es opcional para cualesquiera declaraciones introducidas �nicamente en la secci�n de implementaci�n o en programas. Por supuesto, varias declaraciones relacionadas (ej: grupos de constantes) pueden compartir un comentario.
Una utilidad llamada pas2texi ser� escrita para construir ficheros Texinfo desde los comentarios Pascal. Esto permitir� ciertas clases de marcado dentro de los comentarios. Ser�n escritos en la documentaci�n de pas2texi y/o en versiones futuras de este documento.
Puede usar comentarios “fixme”, (“arr�glame”) para apuntar cosas que deben ser arragladas en el c�digo, o en una biblioteca (o m�dulo, o unidad, o compilador usado) que afecte directamente al c�digo, requiriendo un arreglo. Estos comentarios son frefijados por al menos dos @ – a�ada tantos @ como la urgencia de la publicaci�n se incremente.
Estos comentarios pueden contener m�s o menos detalles oscuros acerca del problema, especialmente si la ra�z del problema est� por cualquier parte. Por ejemplo, el comentario { @@fjf226 } declara el siguiente c�digo como un arreglo para un problema del Compilador de Pascal de GNU que es demostrado por el programa de prueba del Compilador de Pascal de GNU fjf226.pas. (Es un fichero que puede encontrar en el paquete de fuentes del Compilador de Pascal de GNU.)
Los comentario “Fixme”no deber�an mezclarse con comentarios ordinarios. Si necesita ambas clases, a�selos separadamente, incluso si directamente despu�s de cada uno. Pueden usarse en cualquier lugar, incluso dentro de sentencias, debido a que tienen naturaleza temporal. M�s a menudom suelen caer en el cuerpo, a no ser que inluencien a interfaces. En particular los interfaces deber�an cambiar debido a un comentario @@ inmediatamente antes de su comentario de descripci�n.
Por favor, comience cada fichero con un comentario conteniendo, en este orden:
En general, deber�a seguir este orden para los bloques de declaraciones:
Puede desviarse de este orden cuando sea necesario o haga el c�digo m�s legible. Esto es un ejemplo donde el orden no puede ser respetado:
type
TSomething = record
This, That: Integer
end;
const
SomeConst = SizeOf (TSomething);
Las reglas de arriba se aplican a los bloques de declaraci�n dentro de rutinas tambi�n.
Cuando hay varias partes, m�s o menos independientes, especialmente en una unidad grande o un m�dulo, puede aplicar este orden dentro de cada parte. No ponga, por ejemplo, constantes de todas las partes juntas. Debe mantener el c�digo legible.
Las variables que son usadas solamente en el programa principal deben ser declaradas globalmente en Pascal. sin embargo, GNU Pascal ofrece unaextensi�n para declarar variables en lugares arbitrarios del c�digo (see var (gpc)). En este caso, en contraste con la regla general anterior, a menudo es mejor poner su declaraci�n justo antes del begin del programa principal, despue todas las rutinas, etc., especialmente cuando hay m�s que unas pocas variables y el tama�o del fichero fuente no es peque�o. As�, el bloque de declaraci�n de variables es m�s f�cil de ver y cambiar para el programador cuando edita el programa principal, y puede asegurarse de que las rutinas no lo usan accidentalmente.
Cuando declara un tipo junto con su tipo de puntero, declare el puntero primero. Es m�s f�cil de reconocer, especialmente si el tipo es un registro largo o un objeto. adem�s, hace posible el uso de estructuras recursivas /por ejemplo, usando punteros a un tipo dentro de su tipo). Deber�a anteponer un T al nombre del tipo y una P al tipo de puntero asociado. Vea el ejemplo:
type
PMyInt = ^TMyInt;
TMyInt = Integer;
PStrList = ^TStrList;
TStrList = record
Next: PStrList;
s: TString
end;
N�tese que el campo Next se especifica primero. Sugerimos siempre ponerlo como el primer campo en tipos recursivos, as� permite algunas rutinas gen�ricas de listas y quiz� sea un poco m�s eficiente recorrer por ejemplo, sin offsets.
Sugerimos poner todos los tipos punteros dentro de cada declaraci�n type en primer lugar, aunque no consideramos esto imperativo. Este es un ejemplo:
type
{ Pointer types }
PFoo = ^TFoo;
PBar = ^TBar;
PBaz = ^TBaz;
{ Some custom integer types }
TFoo = Integer (16);
TBar = Cardinal (16);
TBaz = Cardinal (32);
Dentro de tipos objeto puede haber tres areas de declaraci�n. Hay tres palabras reservadas para introducir estas �reas: public, protected, private. Dentro de En el interior de cada una de estas �reas se sigue este orden:
En la parte de implementaci�n del objeto, ponga los cuerpos de rutina en el mismo orden en que aparecen en la declaraci�n del interfaz. Esto tambi�n se aplica a unidades y m�dulos, en los cu�les la implementaci�n deber�a reflejar las declaraciones del interfaz.
No use el ; de cola al final de un bloque, por ejem. antes de end, until, etc. excepto en case – la �ltima rama antes de la rama else (o la �ltima rama si no hay rama else) deber�a tener un ;, para evitar problemas como:
case ...
Foo:
if Bar then { later inserted }
begin
...
end { si no hay punto y coma aqu� ... }
else { ... esto ser� confundido como el else del then }
...
(Lo mismo si el if estaba aqu� para antes y la rama else del case se inserta despu�s.)
En un oibjeto, puede parecer extra�o omitir el ; despu�s del �ltimo elemento que es a menudo un m�todo. Sin embargo lo permitimos, y por consistencia, tambi�n en los registros.
Las palabras reservadas deber�an estar todas en min�scula, incluyendo directivas, por ejem. palabras que est�n reservadas s�lo en algunos contextos, como protected. Si usa directivas como identificadores (lo que es como causerte un dolor) fuera de sus contextos, escr�balas como identificadores.
Como excepci�n especial, puede usar File empezando por may�scula cuando sea usado como un tipo propio, por ejem, como en file of Char. Lo mismo no puede decirse para procedure como un tipo (estilo Borland Pascal) debido a que File puede ser un tipo propio, mientras que procedure es un tipo constructor, por ejemplo:
procedure Foo (var a: File); { Esto Funciona. }
procedure Foo (var a: procedure); { Esto no. }
La siguiente cuesti�n es la escritura de identificadores. No hay diferencia entre los identificadores integrados y los definidos por el usuario. S�lo la primera letra deber�a ser may�scula, o, si hay palabras concatenadas o acr�nimos , la primera letra de cada palabra deber�a ponerse en may�sculas – no emplee guiones bajos. Los acronimos que se han convertido en parte del lenguaje natural pueden escribirse de la misma forma. Por ejemplo, Dos o DOS; pero siempre GPC, not Gpc. Here are some examples of identifiers: Copy, Reset, SubStr, BlockRead, IOResult, WriteLn, Sqr, SqRt, EOF, EOLn.
Estas reglas se aplican a los identificadores de constantes tambi�n, como las macros de C
Tambi�n d�se cuenta que los identificadores muy peque�os pueden escribirse en min�sculas, como i o s1 o xx. Dichos identificadores cortos deber�an ser usados s�lo localmente. Pueden ser usados para par�metros de rutinas globales, porque el �mbito de dichos par�metros es local tambi�n, y sus nombres de hecho no importan para nada a quien los llame. El uso de estos identificadores en un contexto global deber�a ser evitado, especialmente en unidades o m�dulos o bibliotecas (porque el autor no sabe en qu� contextos ser�n usadas).
Por favor, sea consistente en el uso de las may�culas. Sabe que Pascal no se quejar� si cambia la capitalizaci�n de un identificador a trav�s del c�digo, pero por favor, c��ase a la misma capitalizaci�n.
Para los identificadores de los valores de los tipos enumerados y para bloques de constantes, por ejemplo, lugares donde se introducen muchos identificadores, puede ser �til usar un prefijo de dos letras min�sculas y _, en contraste con las reglas anteriores:
type
TFooBar = (fb_Foo, fb_Bar, fb_Baz, fb_Qux);
{ My Foos }
const
mf_Foo = 1;
mf_Bar = 3;
mf_Baz = 42;
En c�digo orientado a objetos (especialmente en constructores), a menudo existe la necesidad de tener un par�metro correspondiente a un campo de un objeto (ej. para pasar un valor con el cual inicializar el campo). Como ambos no pueden llamarse de la misma manera, el campo deber�a tener el nombre “natural” debido a que es normalmente empleado en m�s rutinas, y el nombre del par�metro deber�a ser “cambiado”. FIXME: Todav�a no hemos encontrado una regla realmente satisfactoria para este cambio (algunos usan a como un prefijo), y si usted tiene alguna idea, d�jenos conocerla.
En tanto a lo que concierne a las macros, recomendamos encarecidamente que no las use. Por favor, no use macros en sus programas. Intente evitar el uso de macros en sus programas, porque son el mal. Creemos que no debe usar macros en su c�digo. Dicho esto, si todav�a osa a usar una macro, escr�bala en may�sculas completamente y separe las palabras con guiones bajos (_). Debido a que las macros no siguen las reglas de visibilidad de Pascal, tiene sentido escribirlas de forma diferente. Esto se aplica a los condicionales tambi�n.
Gereralmente sugerimos que use tan pocas directivas del compilador como sea razonablemente posible, porque hacen el c�digo m�s dif�cil de entender (ej. cuando verifica efectos laterales) y de modificar (ej. cuando se mueven partes del c�digo dentro o fuera del �mbito de las directivas del compilador). Las directivas deber�an ser invocadas como en el siguiente ejemplo:
{$su_directiva_de_compilacion}
Definitivamente no de esta manera (see Comentarios):
(*$no-use-asi-una-directiva-de-compilacion*)
Adem�s, definitivamente no de esta manera que es dependiente de los saltos de l�nea, en Pascal normalmente es:
#su-directiva-de-compilacion
Lo mismo sirve para definiciones de macros:
{$define ...}
Esto ahorra la barra invertida antes de los saltos de l�nea, en contraste con #define. Pero no va a usar macros, �verdad? (see May�sculas)
Es lo que concierne al espaciado no escriba un espacio antes del cierre de llave, as� como no ponga uno despu�s de la llave de apertura. Si concatena varias directivas juntas, no ponga un espacio entre cada una de ellas, una sola coma es suficiente.
No introduzca comentarios dentro de las directivas. Escr�balos separados, como esto:
{$X+} { Necesitamos sintaxis extendida. }
Borland Pascal permite mezclar comentarios con directivas, pero realmente es un mal uso.
Formas cortas para llamar directivas est�n bien, pero las formas largas son por lo menos tan buenas como las otras, as� que siga su preferida. Las formas cortas deben ser escritas en may�sculas mientras que las formas cortas lo son en min�sculas (excepto para argumentos sensibles a la capitalizaci�n como mensajes y nombres de fichero – por supuesto, los nombres de fichero deben tratarse siempre como dependientes de la capitalizaci�n, incluso en DOS, para preservar la portabilidad del c�digo).
Puede combinar varias directivas, adem�s mezclar las cortas con las largas, en una sola llamada, por ejemplo como las siguientes:
{$gnu-pascal,I-,X+}
Cualquier unidad o module deber�a tener {$gnu-pascal,I-} o {$gnu-pascal,I+} cerca del principio (tras el comentario de la cabecera con la desripci�n y licencia). {$gnu-pascal} permite que la unidad sea compilada sin opciones de dialecto incluso si el programa principal est� compilado con alguno. {$I-} o {$I+} indica al usuario (incluso aunque uno de ellos est� predeterminado) si la unidad maneja/devuelve errores de esntrada/salida o permite que �stos causen errores en tiempo de ejecuci�n. La forma es preferible para la mayor�a de las unidades (rutinas que devuelven errores de entrada/salida deber�an declararse como iocritical cuando esto sea soportado). Para programas, este item es opcional.
{$W-} (sin advertencias) debe usarse localmente y debe tener un comentario “fixme” (see Comentarios) porque ello indica un problema con el c�digo o el compilador. Si est� disponible, use directivas para desactivar ciertas advertencias acerca de problemas del compilador. Por ejemplo, {$W no-object-directives} o {$W no-field-name-problem}. Estas directivas particulares pueden usarse globalmente.
Por favor, no deshabilite las advertencias cuando sea tan vago de no escribir c�digo que no produzca advertencias.
Cualquier flag del compilador que no se haya puesto globalmente (por ejemplo con {$gnu-pascal}, vea arriba) seber�a ponerse como {$local ...}. En otras palabras, no de esta manera:
{$I-} Reset (f); {$I+}
Pero s� de esta otra:
{$local I-} Reset (f); {$endlocal}
La forma esa equivocada si {$I-} ya fue puesto. Incluso si un programador pudirera darse cuanta y tener en cuenta de cual es la configuraci global, esto quiz� camiar� alguna vez, o parte del c�digo puede ser copiado o movido. La �ltima forma es m�s segura en estos casos.
Para hacerlo incluso m�s claro, de las dos �ltimas reglas que sigen:
{$local W-} Foo; {$endlocal} { @ GPC produces a superfluous warning }
Otra vez, intente evitar directivas locales. {$I-} se necesita algunas veces. {$X+} puede usarse si realmente, realmente es necesario (tan localmente como sea posible): evite aritm�tica de punteros.
No use {$X+} para ignorar resultados de funciones, no use {$ignore-function-results}, en cualquier caso. Es muy f�cil ignorar un resultado que no deber�a ignorar. Algunas veces, especialmente cuando enlaza a una biblioteca externa de C, quiz� tenga que tratar con funciones que tienen un resultado superfluo, que probablemente no quiera verificar. Puede declarar dichas funciones con el atributo especial ignorable, cuando est� disponible, as� que sus resultados son silenciosamente ignorados. Por el momento, use una variable desechable.
Tambi�n use variables desechables si no quiere ignorar el resultado de una llamada particular a una funci�n cuyo resultado en general deber�a no ser ignorado. En esos caso sverifique cuidadosamente que el resultado puede ser en efecto ignorado de forma segura. Si por ejemplo, un resultado no esperado podr�a indicar una situaci�n “imposible”, es normalmente mejor verificar el resultado e imprimir una advertencia a abortar en el caso inesperado, al menos si DEBUG est� definido (see Directivas del Compilador).
Las directivas del enlazador, ej. {$L} para bibliotecas y c�digo fuente C (u otro lenguaje) deber�an ser puestas cerca del principio en programas y cerca de la l�nea implementation en unidades o m�dulos. Varias bibliotecas, ficheros fuente C en una directiva son posibles cuando pertenecen a un mismo conjunto l�gico (por ejemplo, una biblioteca y sus wrapers de C), pero no para cosas distintas. Esta directiva no deber�a mezclarse con otras directivas (que incluso no funcionar�an si L viene primero – la otra manera quiz� funcione, pero no deber�a usarse). La declaraci�n externa de la biblioteca o rutina C deber�a seguir inmediatamente la directiva (excepto en una unidad o m�dulo para aquellos que van en el interfaz). El uso de {$L} en programas no es una buena idea a menudo, hacer una unidad es a menudo mejor por abstracci�n y reutilizaci�n.
La compilaci�n condicional quiz� sea �til algunas veces, pero deber�a usar tan pocos {$ifdef}s como sea posible, debido a que disminuyen la legibilidad. Cuando se usan condicionales para diferencias entre sistemas, verifique caracter�sticas (por ejemplo, __BYTES_LITTLE_ENDIAN__) o grupos de sistemas (por ejemplo, OS_DOS) en vez de sistemas individuales, para incluir mejor a los sistemas que no conoce o que no existan ahora.
Si es posible (esto quiz� no est� disponible), utilice las constantes predefinidas (por ejemplo, BytesBigEndian, OSDosFlag) en lugar de definiciones – para el c�digo en que sea posible (la rama “siempre falsa” ser� optimizada, pero todav�a tendr� su sintaxis verificada como beneficio aunque no use el preprocesador); para declaraciones de tipos no es usualmente posible y se tienen que usar definiciones. Un buen ejemplo es la declaraci�n de TWindowXY en la unidad CRT. Vea:
TWindowXY = packed record
{$ifdef __BYTES_BIG_ENDIAN__}
Fill: Integer (BitSizeOf (Word) - 16);
Y, X: Word (8)
{$else}
X, Y: Word (8);
Fill: Integer (BitSizeOf (Word) - 16)
{$endif}
end;
El flag DEBUG seber�a ser usado para (y s�lo para) ayudar en el debugueo, ej. c�digo que no cambia la funcionalidad real. Los programas deben compilar con y sin poner DEBUG. Lo �ltimo puede ejecutarse m�s lentamente y puede producir mensajes adicionales �tiles de una forma determinada, ej. claramente marcados como mensajes de debugueo, por ejemplo prefijados con DEBUG: , y pueden abortar la ejecuci�n cuando detectan condiciones err�neas o dudosas.
Los condicionales pueden ser usados para hacer versiones diferentes de alg�n c�digo, por ejemplo, usando n�meros GMP si una condici�n se satisface y usando enteros normales o reales en otro caso (GMP es una biblioteca para trabajar con n�meros muy grandes). En este caso, el nombre y significado de todas esas definiciones usadas en un fichero deben ser explicados en un comentario cerca de la parte superior. (Para eemplos, vea __BP_TYPE_SIZES__, __BP_RANDOM__ y __BP_PARAMSTR_0__ en la unidad System.) El c�digo debe compilar con cualquier combinaci�n de ese conjunto de condicionales, lo cual significa que debe comprobar exponencialente muchos casos – aqu� est� una buena raz�n para mantener su n�mero tan peque�o como sea posible.
Otro uso similar de los condicionales es para seleccionar entre diferentes implementaciones No deber�a adoptar esta estrategia �nicamente si todas las implementaciones est�n realmente soportadas o planeadas para ser soportadas. De otra forma, ser�a mejor mover las implementaciones antiguas a su “museo” y mantener el c�digo limpio. Las notas acerca de la compilaci�n de c�digo de la regla anterior se aplica aqu� tambi�n.
Cuando necesite tratar con condicionales complicados, utilice sintaxis Pascal, i.e. formatee los condicionales de acuerdocon las reglas para c�digo Pascal, en vez de sintaxis C. Este es un ejemplo tonto:
{$if defined (Foo) or False}
En su lugar, este es un ejemplo que no debe seguir:
{$if defined (Foo) || 0}
O incluso peor:
#if defined (Foo) || 0
Un condicional especial puede usarse para comentar c�digo temporalmente. Aqu� est� la sintaxis apropiada:
{$if False} ... {$endif}
Una sentencia condicional est�ndar deber�a usarse en programas o unidades o m�dulos que distribuya para asegurarse que la versi�n apropiada del Compilador Pascal GNU se usa. Puede segui esta plantilla:
{$if __GPC_RELEASE__ < 20020510}
{$error This unit requires GPC release 20020510 or newer.}
{$endif}
En general, no deber�an usarse espacios m�ltiples excepto para el sangrado y como se indica abajo
Un solo espacio va antes y despues de operadores, y := y .. as� como : en Write, WriteLn y WriteStr; destu�s de la coma y otros :. Este ejemplo deber�a dejarlo claro:
var
Foo: Integer;
...
begin
Foo := 42;
WriteLn (Foo + 3 : 5, ' bar')
end;
Ning�n espacio deber�a ir antes del - unario. De hecho, estas son las formas correctas: x - 1, -x, -1.
un espacio debe ir antes del par�ntesis de apertura (() y despu�s del par�ntesis de cierre ()), excepto que sea adjacente a m�s par�ntesis, corchetes, ^, ;, ,. En otras palabras, un espacio va entre identificadores o palabras reservadas y el par�ntesis de apertura ((). (Todos los otros espacios en este ejempo son implicados ya por la regla previa.) Vea:
Foo (Bar^(Baz[Qux * (i + 2)]), Fred (i) + 3);
Para indexar arrays no use un espacio antes del corchete de apertura, ej: Foo [42] en vez de Foo[42]. Sin embargo, inserte un espacio antes del corchete de apertura en las declaraciones de arrays, como:
Foo: array [1 .. 42] of Integer;
Un espacio va antes del corchete de apertura de un constructor de conjuntos en algunas situaciones – esos corchetes deber�an tratarse como par�ntesis, a diferencia de los corchetes usados en la indexaci�n de un array. Por ejemplo:
x := [0, 2 .. n];
Pero:
Foo ([1, 2, 3]);
Sin espacios para . and ^:
Rec.List^.Next^.Field := Foo
Como ya apuntamos, un �nico espacio va despu�s del brazo de apertura y antes del brazo de cierre en los comentarios, pero no en las directivas del compilador. Adem�s, y ya dijimos esto en alg�n otro lugar del manual, dos espacios van antes de los comentarios despu�s de una l�nea de c�digo. Por ejemplo:
Inc (x); { Incrementa x. }
Opcionalmente use espacios adicionales para “tabular” c�digo. En nuestra opini�n, esto incrementa la legibilidad un mont�n, porque el ojo humano y el cerebro est�n entrenados para reconocer estas estructuras, y similaridades y diferencias entre las l�neas pueden ser vistas m�s f�cilmente, y cuando cambia el c�digo, es m�s f�cil encontrar lugares relacionados. una aplicaci�n de este principio puede verse en las declaraciones “interface” (no tan aplicables cuando est�n separadas por comentarios, pero, por ejemplo, cuando se se describen por un comentario compartido sobre todas ellas):
function Pos (const SubString, s: String): Integer;
function LastPos (const SubString, s: String): Integer;
function PosCase (const SubString, s: String): Integer;
function LastPosCase (const SubString, s: String): Integer;
function CharPos (const Chars: CharSet; const s: String): Integer;
function LastCharPos (const Chars: CharSet; const s: String): Integer;
function PosFrom (const SubString, s: String; From: Integer): Integer;
function LastPosTill (const SubString, s: String; Till: Integer): Integer;
function PosFromCase (const SubString, s: String; From: Integer): Integer;
function LastPosTillCase (const SubString, s: String; Till: Integer): Integer;
Tambi�n posible:
procedure Foo;
function Bar ...;
procedure Baz;
Y desde luego:
const
FooBar = 1;
Baz = 2;
Quux = 3;
La misma estrategia “tabular” usada en los interfaces y declaraciones const puede usarse con los inicializadores:
const
Foo: TBarArray =
(('Foo' , 3),
('Bar baz', 42),
('' , -1));
Y en sentencias case:
case ReadKeyWord of
kbLeft : if s[n] > l then Dec (s[n]) else s[n] := m[n];
kbRight : if s[n] < m[n] then Inc (s[n]) else s[n] := l;
kbUp : if n > 1 then Dec (n) else n := 5;
kbDown : if n < 5 then Inc (n) else n := 1;
kbHome : s[n] := l;
kbEnd : s[n] := m[n];
kbPgUp,
kbCtrlPgUp: n := 1;
kbPgDn,
kbCtrlPgDn: n := 5;
kbCR : Done := True;
end
Y opcionalmente en otro c�digo:
WriteCharAt (1, 1, 1, Frame[1], TextAttr);
WriteCharAt (2, 1, w - 2, Frame[2], TextAttr);
WriteCharAt (w, 1, 1, Frame[3], TextAttr);
Una ruptura de l�nea es opcional despu�s de declaraciones locales const, type, var si contienen �nicamente una sola declaraci�n (pero es posible tener m�ltiples identificadores en una �nica l�nea).
procedure Baz;
var Foo, Bar: Integer;
begin
...
end;
Desde luego, esto tambi�n se acepta:
procedure Baz;
var
Foo, Bar: Integer;
begin
...
end;
Pero no siga este ejemplo:
procedure Baz;
var Foo, Bar: Integer;
Qux: Real;
begin
...
end;
Si tiene muchas declaraciones puede romper las l�neas de varias maneras. Lo siguiete es la forma preferida para declaraciones var:
var
Foo, Bar, Baz, Qux, Quux, Corge, Grault, Garply, Waldo, Fred,
Plugh, Xyzzy, Thud: Integer;
o:
var
Foo, Bar, Baz, Qux, Quux, Corge, Grault, Garply, Waldo: Integer;
Fred, Plugh, Xyzzy, Thud: Integer;
Esta �ltima, sin embargo, es ma apropiada para campos de registros (record) y para la parte p�blica de objetos (object), especialmente si hay un comentario para cada uno de ellos:
var
Foo,
Bar,
Baz,
Qux: Integer;
No hay ruptura de l�nea despu�s de declaraciones var dentro de bloques de sentencias, porque permiten s�lo una declaraci�n, y hacer una ruptura de l�nea podr�a pareces como si se permitiera m�s de una.
Foo := Bar;
var Baz: array [1 .. Foo] of Integer;
Como esto es una extensi�n de GNU Pascal, use estas declaraciones muy de vez en cuando, pero ejemplo para variables cuyo tama�o depende de valores computados dentro de la rutina, o para variables dentro de los inicializadores o finalizadores del m�dulo o unidad para evitar variables globales, aunque quiz� piense usar una subrutina.
No inserte una ruptura de l�nea despu�s de label. Esto es como se deben declarar etiquetas:
label Foo, Bar, Baz;
y como complemento, aqu� est� como no hacerlo:
label
Foo,
Bar,
Baz;
Algunas declaraciones en distintan l�neas incluso no funcionan:
label
Foo;
Bar;
Baz;
Aqu� est� un ejemplo de c�mo usar rupturas de l�nea dentro de una sentencia case.
case
foo:
begin
...
end;
bar,
baz .. qux:
...
else
...
end;
O (“tabular”):
case
foo: begin
...
end;
bar,
baz .. qux: ...
else ...
end;
Las sentencias largas o declaraciones deber�an ser rotas en cualquier caso antes de operadores o despu�s de ellos (donde lo que se entiende por siempre es al menos una subrutina) o despu�s de una coma, con sangrado suficiente para hacer el significado claro:
if (x = y)
and (foo
or (bar
and (baz or qux))
or fred) then
or:
if (x = y) and
(foo or
(bar and
(baz or qux)) or
fred) then
Aqu� est� como usar rupturas de l�nea dentro de sentencias. Otro uso para ello es d�nde deber�a usar una sentencia case si fuera posible, pero no es posible (por ejempo los typos no son ordinales, o los valores a ser comparados no son constantes, o la comparaci�n implica a una funci�n (StrEqualCase, o hay condiciones adicionales).
if ... then
a
else if ... then
b
else
c
Si a y no a son casos principales, y b y c son sub casos de no a, utilice lo siguiente (la distinci�n quiz� ser cuasti�n de gustos a veces):
if ... then
a
else
if ... then
b
else
c
El ejemplo siguiente (biologicamente muy incompleto) contiene una mezcla de ambas formas que consideramos razonable:
if Habitat = 'Water' then
{ Animals living in water }
WriteLn ('Is it a fish?')
else if Habitat = 'Air' then
{ Animals living in air }
WriteLn ('Is it a bird?')
else
{ Animals living on land }
if Legs = 8 then
WriteLn ('Is it a spider?')
else
WriteLn ('Is it a gnu?')
Los casos principales son determinados por el habitat, y el n�mero de patas determina algunos sub-casos.
Para bucles de control hay un breve resumen de posibilidades aqu�:
for ... do
...
while ... do
...
repeat
...
until ...
Si hay s�o una sentencia despu�s de la cl�usula if, o en un for o bucle while, o entre repeat y until, y si esa orden es suficientemente corta, puede poner la sntencia en una l�nea sola, coo esto:
if ... then ...
for ... do ...
while ... do ...
repeat ... until ...
Aqu� est� c�mo comportarse cuando begin yd end est�n implicados.
if ... then
begin
...
end
for ... do
begin
...
end
while ... do
begin
...
end
El sangrado es de 2 caracteres de ancho, para cada begin, then, else, case, do (for, while, with, to begin, to end), repeat, record, object, type, const, var, label.
Los cuerpos y variables locales etc. de rutinas globalesno deben ser sangrados, de la misma forma que las variables globales etc. Cada subrutina (cabecera y cuerpo) y sus declaraciones, al contrario, deben ser sangradas.
program Prog;
var
GlobalVar: Integer;
procedure GlobalProc;
var LocalVar: Integer;
procedure LocalProc;
var LocalLocalVar: Integer;
begin
WriteLn ('This is a local procedure.')
end;
begin
WriteLn ('This is a global procedure.')
end;
begin
WriteLn ('This is the main program.')
end.
Los registros variantes deber�an ser sangrados como los siguientes:
type
Foo = record
NonVariant: Foo;
case Discriminant: Bar of
Val1: (Variant1: Baz;
Variant2: Qux);
Val2: (Variant3: Fred)
end;
var
Foo: record
[ as above ]
end = [ initializer ]
Sangrados m�s grandes, ej. m�s de 2 caracteres de ancho, pueden usarse para romper sentencias o declaraciones o para obtener c�digo “tabulado”.
Los condicionales ({$ifdef}) deber�an estar al mismo nivel de sangrado que el c�digo al que afectan:
begin
{$ifdef DEBUG}
WriteLn ('Debugging version');
{$endif}
...
end;
Los condicionales cortos que afectan s�lo a una expresi�n pueden escribirse dentro de una sola l�nea:
Foo := {$ifdef DEBUG} 'debug' {$else} 'release' {$endif};
Si son usados intencionalmente en una forma contraria a las reglas sint�cticas usuales, p�ngalos donde parezcan quedar mejo y escriba un comentario:
begin
{ Do the code unconditionally if debugging }
{$ifndef DEBUG}
if SomeCondition then
{$endif}
begin
...
end
end;
La mayor�a de las veces encontrar� una forma m�s bonita y no menos eficiente de escribir las mismas sentencias. En este caso, puede hacerse de esta forma:
begin
if {$ifdef DEBUG} True {$else} SomeCondition {$endif} then
begin
...
end
end;
O mucho mejor:
{ globally }
const
DebugFlag = {$ifdef DEBUG} True {$else} False {$endif};
begin
if DebugFlag or SomeCondition then
begin
...
end
end;
La mayor�a de las reglas que hemos cubierto no se aplican alas cadenas. En general, los mensajes contenidos en cadenas deber�an seguir los Est�ndares de Codificaci�n GNU, por ejemplo, ponga los nombres entrecomillados dentro de ` y ', aunque esto significa que debe doblar el ' en una cadena Pascal. See Errores (est�ndares), para m�s informaci�n.
Normalmente deber�a usar cadenas encerradas en comillas simples, como 'esta cadena que est� leyendo'. Utilice cadenas en dobles comillas cuando necesite secuencias de escape tipo C como "\t". Note que NewLine ("\n") est� predefinido, as� que usar NewLine es preferible a no ser que tenga que usar una cadena del estilo de C por otros propositos.
Puede usar cadenas multilinea como la siguiente:
WriteLn ('Hello
world')
o (quiz� preferible, especialmente si el texto en la cadena contiene par�grafos y/o sangrado dentro de ella misma):
WriteLn (
'Hello
world')
Sin embargo, es posible tambi�n usar:
WriteLn ('Hello' + NewLine + 'world')
(Note que el ejemplo anterior no compilar� sin usar la unidad GPC.)
O, por supuesto:
WriteLn ('Hello');
WriteLn ('world')
Cuando quiera verificar si una cadena est� vac�a, use esta sintaxis:
if s = '' then
...
El Compilador Pascal de GNU eventualmente lo optimizar� eventualmente a la siguiente prueba m�s eficiente, as� que puede usar la anterior, m�s corta sin perjuicio:
if Length (s) = 0 then
...
Lo mismo se aplica para <>, desde luego, e incluso para asignaciones donde s := '' es la forma recomendada y ser� optimizada por GPC a SetLength (s, 0).
Vea el manual de gettext para informaci�n acerca de internacionalizaci�n y localizaci�n.
Hay un proyecto en marcha por Eike Lange (eike(at)g-n-u.de) que pretende proporcionar rutinas de internationalizaci�n para GNU Pascal Puede obtener el fuente en tarball desde http://www.gnu-pascal.de/contrib/eike/.
Adem�s de la unidad de internacionalizaci�n, puede encontrar otro paquete
que contiena una herramienta llamada pas2po, usada para extraer cadenas
desde los fuentes de GNU Pascal ej.. similarmente a lo que xgettext hace
para los fuentes C y C++. pas2po no es tan c�modo como xgettext, pero
el programa est� todav�a en desarrollo. Por favor lea la documentaci�n incluida con
el tarball y mant�ngase al tanto.
Esta secci�n de los Est�ndares de Codificaci�n GNU tambi�n se aplica a GNU Pascal. Recuerde que mmap actualmente significa MemoryMap e este contexto. See Mmap (est�ndares).
Recomendamos leer la secci�n respectiva en los Est�ndares de Codificaci�n GNU, todo ello es aplicable a este contexto, tambi�n. See Documentaci�n (est�ndares). �stas son algunas notas acerca de la escritura.
En lo que concierne a las p�ginas man, ser�a bueno tener una p�gina man refiri�ndose a la documentaci�n Info. Hay un programa GNU, llamado help2man, que genera una p�gina man basada en la salida --help de un programa. Funciona bien, excepto que siempre escribe FSF que no es correcto para todos los programas compilados con el Compilador Pascal de GNU, pero la salida puede cambiarse f�cilmente (por ejemplo, autom�ticamente usando sed).
Sin embargo, no ponga mucho esfuerzo en las p�ginas man. Puede ser posible en un principio, pero mantenerlas actualizadas junto con los fichero Texinfo significa mucho trabajo. Encima de �sto, si no las mantiene actualizadas le van a causar m�s confusi�n que ayuda.
Por un lado, si las p�ginas man se acortan mucho, van a perder informaci�n importante. Por el otro, si no se acortan, son dif�ciles de navegar.
En otras palabras, sea devoto de la documentaci�n Info (i.e., Texinfo).
Por favor, lea el cap�tulo respectivo en los est�ndares de Codificaci�n GNU. Note que el esfuerzod e herramientas automatizadas de C no es necesario para los programas Pascal normales. Adem�s los Makefiles son a menudo innecesarios en GNU Pascal. See Gesti�n de Liberaciones (est�ndares).
Para sus proyectos Pascal no necesita probablemente grandes Makefiles y no necesita usar autoconf o automake. Puede darle --automake al Compilador Pascal de GNU as� que �l se hace cargo de las dependencias por usted. (Cuando esto se estaba escribiendo la caracter�stica automake del Compilador de Pascal de GNU tiene algunos fallos peque�os, pero ser�n corregidos. Tambi�n, hay planeada una utilidad llamada gp, que est� en desarrollo ahora, que simplificar� el proceso de compilaci�n mucho m�s. En cualquier caso no necesita escribir complejos Makefiles usted mismo.)
Un Makefile sencillo podr�a ser como:
GPC_FLAGS=-O2
all: foo
foo: foo.pas unit1.pas
gpc --automake $(GPC_FLAGS) foo.pas
mostlyclean:
-rm -f *.o *.gpi *.gpm core
clean: mostlyclean
-rm -f foo
distclean: clean
extraclean: distclean
-rm -f *~*
maintainer-clean: extraclean
Quiz�, sin embargo, quiera poner otras reglas en un Makefile para construir documentaci�n, ficheros de datos, hacer distribuciones o lo que sea. Este tipo de cosas est�n fuera del �mbito de este texto. Puede normalmente hacer las compilaciones Pascal con una sola llamada gpc --automake por programa.
Rutinas son procedures, functions, constructors, destructors u operadores (definidos por el usuario).
Declaraciones son aquellas partes de un programa que “anuncian” la existencia de propiedades de ciertos objetos como constantes , tipos, variables, rutinas, unidades, m�dulos y el programa.
Sentencias son aquellas partes de un programa que “hacen” algo. Una sentencia simple es una asignaci�n, una llamada a procedimiento, una sentencia de salto (goto, Exit, Return, Break, Continue), una sentencia en ensamblador, o una sentencia compuesta (begin ... end, if, case, repeat, while, for, with) que en cambio puede contener una o varias sentencias.
Identificadore son aquellos elementos del lenguaje que dan nombres a objetos como rutinas, constantes, tipos, variables, unidades, m�dulos. Pueden ser redefinidos localmente, excepto las palabras clave que son parte de las construcciones sint�cticas fijas (por ejemplo if ... then ... else) y no pueden ser redefinidas. Las macros no son elementos del lenguaje debido a que son expandidas por el preprocesador y nunca son vistas por el compilador.
Endianidad significa el orden en que los bytes de un valor m�s grande que un byte se almacenan en memoria. Esto afecta, por ejemplo, a los valores enteros, y punteros mientras que los arrays de caracteres de un s�lo byte no est�n afectados. (see Endianidad (gpc))
Nota: Otros items ser�n incluidos aqu� cuando parezca �til. Si quiere una definici�n de alg�n otro t�rmino, d�ganoslo.
MemoryMap: MemoryMap|
|
Copyright © 1996-2005 GNU Pascal development team
Verbatim copying and distribution is permitted in any medium, provided that this notice and the disclaimer below are preserved.
This information is provided in the hope that it will be useful, but without any warranty. We disclaim any liability for the accuracy of this information.
We are not responsible for the contents of web pages referenced by this site.