Motivo para colocar el tipo de función y el nombre del método en diferentes líneas en C

16

Recién comencé en una empresa y uno de los comentarios de estilo en mi primera revisión de código fue que el tipo de devolución y el nombre del método deberían estar en diferentes líneas. Por ejemplo, esto

void foo() {
}

debería ser esto

void
foo() {
}

Siempre he usado el primer estilo, y me preguntaba si hay alguna otra razón que no sea la preferencia personal por qué la gente usa el segundo estilo. No creo que el primero perjudique la legibilidad en absoluto. ¿Es uno más común que el otro con los programadores de C y los grandes proyectos de código abierto?

gsingh2011
fuente
3
Esto está en el estándar GNU (no necesariamente diciendo que es algo bueno, el estilo de refuerzo es extraño). gnu.org/prep/standards/standards.html#Formatting
Gauthier

Respuestas:

19

se preguntaba si hay alguna otra razón que no sea la preferencia personal por qué las personas usan el segundo estilo.

Ese es un estilo que fue popular en los primeros días de C, por lo que la razón puede ser que así es como lo han hecho durante mucho tiempo, tienen mucho código que se ve así, y eso es lo que todos están acostumbrados. No tanto la preferencia personal como el impulso corporativo.

Otra razón es que los nombres de las funciones siempre comienzan en la primera columna. Los tipos de retorno varían en longitud y pueden ser algo complejos: poner el tipo en su propia línea hace que el nombre de la función sea más fácil de encontrar.

Si la empresa tiene un estilo establecido, también pueden tener un documento de estándares de codificación. Pregunta por ello. Puede explicar los motivos de esta elección, y tener una copia lo ayudará a evitar problemas similares en futuras revisiones.

Caleb
fuente
2
Supongo que también está conectado al límite de línea de 80 caracteres que todavía usan y defienden muchos programadores. Si desea tener un límite de 80 caracteres y desea utilizar métodos descriptivos / nombres de funciones, debe hacer algunos compromisos. Dividir el encabezado del método es uno de ellos.
Sulthan
La declaración también puede ser más larga: piense en diferentes modificadores (no estándar), como llamar a identificadores de convención (stdcall, etc.), información sobre visibilidad de símbolos (DLLEXPORT) o __attributes. Y luego, al mirar también C ++, puede tener tipos de retorno relativamente complejos, por lo que en algún lugar podría tener que agregar un salto de línea.
johannes
@Sulthan No solo los programadores (que están acostumbrados a las ventanas de terminal y usan editores de terminal), curiosamente. En la composición tipográfica, 72-80 caracteres generalmente se consideran el ancho ideal para una columna de texto en términos de legibilidad. (Por lo tanto, por qué TeX y sus derivados predeterminan lo que algunas personas consideran columnas extrañamente estrechas.)
JAB
1
@JAB En realidad ahora eso. También sé que leer un texto justificado y leer el código fuente son dos cosas muy diferentes y no tienen casi nada en común, por lo tanto, ese ancho ideal es irrelevante.
Sulthan
1
"Otra razón es que los nombres de las funciones siempre comienzan en la primera columna [y por lo tanto] son ​​más fáciles de encontrar". Y esto es mucho más que un simple beneficio visual: ahora podemos buscar la expresión regular ^start_of_a_long_funcy ser llevados inmediatamente a la función que estamos buscando.
underscore_d
7

Esta es prácticamente la única regla de formato de código que he encontrado que en realidad tiene un impacto notable en la legibilidad y casi no requiere esfuerzo (suponiendo que su editor de código no comience una pelea con usted por eso).

Es un buen diseño de lenguaje de programación que los nombres aparezcan en una posición coherente en las declaraciones / definiciones. La razón es directa: tiene un buen ancla visual (una llave o simplemente una sangría colgante) que puede usar para encontrar inmediatamente el comienzo del nombre. No tiene que analizar realmente el idioma cuando escanea a través de un archivo para encontrar el nombre.

Es lo mismo que cuando está formateando un documento: cuando comienza una nueva sección, pone el nombre al principio en negrita, a menudo en su propia línea, no enterrado en algún lugar, indiferenciado, en una oración larga.

Los primeros C tenían firmas muy concisas: los tipos de retorno eran opcionales y los tipos de argumentos se declararon después de la firma. Los nombres también tienden a ser muy cortos. Esto mitigó el impacto de tener un tipo de retorno ocasional que compensa el nombre.

double dot(x, y);

Sigue siendo bastante digerible.

C ++ hizo esto un poco peor. Movió las especificaciones de tipo de argumento a las firmas haciendo que las firmas fueran más largas. Esta sintaxis fue adoptada posteriormente durante la estandarización de C.

static struct origin *find_origin(struct scoreboard *sb,
                  struct commit *parent,
                  struct origin *origin)

Es menos digerible, pero no está tan mal. (Extracto de Git)

Ahora considere las prácticas modernas de programación con nombres largos y descriptivos y tipos parametrizados y vea cómo esta elección se ha vuelto desastrosa. Un ejemplo de un encabezado Boost:

template <class A1, class A2, class A3, class A4, class A5, class A6>
inline typename normalise<policy<>, A1, A2, A3, A4, A5, A6>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&)
{ 
   typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6>::type result_type;
   return result_type(); 
}

Si está escribiendo código genérico, las firmas como esa ni siquiera están fuera de lo común. Puede encontrar ejemplos de casos mucho peores que este sin esforzarse demasiado.

C, C ++ y sus derivados, Java y C #, parecen ser las excepciones a tener declaraciones / definiciones legibles. Sus predecesores y pares populares (Fortran, ALGOL, Pascal) colocaron nombres antes de los tipos de resultados y, afortunadamente, muchos de sus sucesores (Go, Scala, TypeScript y Swift, por nombrar algunos) también han elegido sintaxis más legibles.

usuario2313838
fuente
1
Agradezca que no tiene que escribir programas Fortran. Te digo que declarar por separado los argumentos de tu función te pondrá nervioso rápidamente una vez que te veas obligado a hacerlo. Especialmente cuando intenta leer una firma de función para comprender qué argumentos espera: C ++ coloca los tipos justo donde pertenecen, Fortran lo obliga a iniciar una búsqueda visual de palabras clave para el nombre de la variable para determinar su tipo.
cmaster - reinstalar a monica el
2
¿Poner los tipos en la declaración de función fue realmente inventado por C ++? Nunca había escuchado que ese fuera el caso, y estoy luchando por encontrar citas.
underscore_d
1
Ver El desarrollo del lenguaje C . En la sección de Normalización, Ritchie menciona que la sintaxis se tomó prestada de C ++.
user2313838
5

Conocí este estilo por primera vez en 19 años trabajando con C & C ++. Estaba bastante desconcertado sobre cómo alguien podría inventar esta cosa malvada.

El único punto (potencialmente) positivo que pude encontrar es que puedes encontrar la definición de función usando grep ^ FuncName. Podría ser un factor relevante hace más de una década en algunas comunidades reales que odian las herramientas ... En el lugar que vi, se aplicó a C ++ y funciones de miembros de clase, que matan incluso este atributo.

Adivina mi opinión. :)

Balog Pal
fuente
1
grep -P '^(\w+::)?FuncName'
Kyle Strand
Sí, los tipos de clase en los nombres de funciones no obstaculizan el uso de esto en absoluto. Por lo tanto, sigue siendo algo útil para navegar rápidamente por los archivos fuente. En cuanto a que se ve mal o lo que sea, las opiniones son opiniones: he llegado a pensar que se ve mejor.
underscore_d