2010-01-02 11 views
8

De acuerdo con this stack overflow answer, el postfix "_t" en los nombres de tipo está reservado en C. Cuando se usa typedef para crear un nuevo tipo opaco, estoy acostumbrado a tener algún tipo de indicación en el nombre que este es un tipo. Normalmente iría con algo como hashmap_t pero ahora necesito algo más.Qué estilo usar al nombrar tipos en C

¿Hay algún esquema de nomenclatura estándar para los tipos en C? En otros idiomas, el uso de CapsCase como Hashmap es común, pero una gran cantidad de código C que veo no usa mayúsculas. CapsCase funciona bastante bien con un prefijo de biblioteca también, como XYHashmap.

¿Existe una regla o estándar común para nombrar tipos en C?

Respuesta

6

Sí, POSIX reserva los nombres que terminen en _t si incluye cualquiera de los encabezados POSIX, por lo que le aconsejamos que se mantenga alejado de ellos, en teoría. Trabajo en un proyecto que ha tropezado con esos nombres dos o tres veces en los últimos veinte años. Puede minimizar el riesgo de colisión utilizando un prefijo corporativo (el TLA de su empresa y un guión bajo, por ejemplo) o usando nombres de casos mixtos (así como el sufijo _t); todas las colisiones que he visto han sido cortas y en minúsculas (dec_t, loc_t, ...).

Aparte del sufijo proporcionado por el sistema (y reservado por el sistema) _t, no existe una convención específica ampliamente utilizada. Uno de los sistemas de casos mixtos (camelCase o InitialCaps) funciona bien. Un prefijo sistemático también funciona bien: las mejores bibliotecas tienden a tener cuidado con esto.

Si decide utilizar minúsculas y el sufijo _t, asegúrese de utilizar nombres lo suficientemente largos y de comprobar con diligencia el estándar POSIX, las plataformas principales en las que trabaja y las que considere que podría trabajar para evitar conflictos innecesarios Los peores problemas surgen cuando liberas algún nombre example_t a los clientes y luego encuentras que hay un conflicto en alguna plataforma nueva. Luego debe pensar en hacer que los clientes cambien su código, algo que siempre son reacios a hacer. Es mejor evitar el problema por adelantado.

5

El Indian Hill style guidelines tener algunas sugerencias:

proyectos individuales, sin duda, tienen sus propias convenciones de nomenclatura. Hay son algunas reglas generales sin embargo.

  • Nombres con guiones bajos delantero y trasero están reservados para el sistema fines y no debe utilizarse para ningún nombres creados por el usuario. La mayoría de los sistemas los usan para nombres que el usuario no debería tener que conocer. Si debe tener sus propios identificadores privados, empiece con una letra o dos que identifiquen el paquete al que pertenecen .

  • #define las constantes deben estar en MAYÚSCULAS.

  • constantes de enumeración se capitalizan o en todos los CAPS

  • función, typedef, y los nombres de variables, así como la estructura, unión y nombres de las etiquetas enumeración deben estar en la parte baja caso.

  • Muchas "funciones" macro están en todos los CAPS. Algunas macros (como getchar y putchar) están en minúsculas, ya que también pueden existir como funciones. Los nombres de macro en minúsculas son solo aceptables si las macros se comportan como una llamada a función , es decir, evalúan sus parámetros exactamente una vez y no asignan valores a parámetros con nombre. A veces es imposible escribir una macro que se comporte como una función aunque los argumentos sean evaluados exactamente una vez.

  • Evite los nombres que difieren solo en el caso, como foo y Foo. Del mismo modo, evita foobar y foo_bar. El potencial de confusión de es considerable.

  • De forma similar, evite los nombres que se parecen entre sí. En muchos terminales y impresoras , 'l', '1' e 'I' parecen bastante similares. Una variable llamada 'l' es particularmente mala porque se ve tan como la constante '1'.

En general, los nombres globales generales (incluyendo enumeraciones) debería tener un prefijo común identificar el módulo que pertenecen con. Globales pueden alternativamente agruparse en una estructura global. Los nombres de tipo de letra a menudo tienen "_t" anexado a su nombre.

Evite los nombres que puedan entrar en conflicto con varios nombres de biblioteca estándar. Algunos sistemas incluirán más código de biblioteca del que desee. Además, su programa puede extenderse algún día al .

+2

¿No sugiere esto utilizar exactamente la misma convención con la que el OP tiene un problema? Parece estar respondiendo una pregunta diferente a la preguntada, que se centra en los tipos. –

3

C solo reserva algunos utiliza un sufijo _t. Por lo que puedo decir, esto es solo identificadores actuales que terminan en _t más cualquier identificador que comience en int o uint (7.26.8). Sin embargo, POSIX puede reservar más.

Es un problema general en C, ya que tiene espacios de nombres extremadamente planos, y no hay una bala de plata. Si está familiarizado con los nombres de CapCase y funcionan bien para usted, entonces debe continuar usándolos. De lo contrario, tendrá que evaluar los objetivos del proyecto actual y ver qué solución los satisface mejor.

+0

+1 para CapCase. Mejora las cosas si luego también migras a un idioma con clases, y es familiar para los nombres de tipos. –

2

CapsCase se utiliza a menudo para este tipo en C.

Por ejemplo, si nos fijamos en proyectos en el ecosistema de GNOME (GTK +, GDK, GLib, GObject, desorden, etc.), verá como tipos GtkButton o ClutterStageWindow. Ellos solo usan CapsCase para tipos de datos; los nombres de las funciones y las variables están en minúsculas con los separadores de subrayado, p. clutter_actor_get_geometry().

Los esquemas de denominación de tipo son como las convenciones de sangría: generan guerras de religión con personas que afirman algún tipo de superioridad moral por su enfoque preferido. Sin duda, es preferible seguir el estilo en el código existente o en proyectos relacionados (por ejemplo, para mí, GNOME en los últimos años.)

Sin embargo, si está empezando desde cero y no tiene plantilla, no hay una regla rígida. Si está interesado en programar eficientemente y dejar el trabajo a una hora razonable para que pueda irse a casa y tomar una cerveza o lo que sea, sin duda debe escoger un estilo y atenerse a él para su proyecto, pero no importa exactamente qué estilo elija. .

0

Hay muchas ideas y opiniones sobre este tema, pero no hay un estándar universal para nombrar tipos. Lo más importante es ser consistente. En ausencia de estándares de codificación, al mantener el código, resista la necesidad de utilizar otra convención de nomenclatura. La introducción de una nueva convención de nomenclatura, incluso si es perfecta, puede agregar una complejidad innecesaria.

Esto es realmente un gran tema para plantear al entrevistar personas. Nunca me he encontrado con un buen programador que no haya tenido una opinión al respecto. Ninguna opinión o ninguna pasión en la respuesta indica que la persona no es un programador experimentado.

2

Una solución alternativa que funciona razonablemente bien es usar mayúsculas para todos los nombres de tipos y macros. Las variables globales pueden ser CapCase (CamelBack) y todas las variables locales en minúsculas.

Esta técnica ayuda a mejorar la legibilidad y también aprovecha la sintaxis del lenguaje que reduce el número de caracteres contaminantes en los nombres de las variables; p.ej. gvar, kvar, type_t, etc. Por ejemplo, los tipos de datos no se pueden confundir sintácticamente con ningún otro tipo.

Las variables globales se distinguen fácilmente de las locales al tener al menos una letra mayúscula.

Acepto que los subrayados prefijados o postfijo deben evitarse en todos los nombres de tokens.

Veamos el ejemplo a continuación.

Está claro que InvertedCount es global debido a su caso. Está igualmente claro que INT32U y RET_ERR son tipos debido a su sintaxis. También está claro que INVERT_VAL() es una macro debido a que está en el lado derecho y no hay ningún molde, por lo que no puede ser un tipo de datos.

Una cosa es segura. Cualquiera que sea el método que use, debe estar en línea con el estándar de codificación de su organización. Para mí, la menor cantidad de desorden, mejor.

Por supuesto, el estilo es un problema diferente.

#define INVERT_VAL(x) (~x) 
#define CALIBRATED_VAL 100u 

INT32U InvertedCount; 

typedef enum { 
    ERR_NONE = 0, 
    ... 
} RET_ERR; 

RET_ERR my_func (void) 
{ 
    INT32U val; 
    INT32U check_sum; 


    val   = CALIBRATED_VAL; // --> Lower case local variable. 
    check_sum  = INVERT_VAL(val); // --> Clear use of macris. 

    InvertedCount = checksum;   // --> Upper case global variable. 
             //  Looks different no g prefix required. 

    ... 

    return (ERR_NONE); 
} 
Cuestiones relacionadas