2010-07-01 16 views
8

autogenerado C++ función "principal" tiene al finalCorchetes alrededor de 0 en "return (0);" declaración en la función 'principal': ¿para qué sirven? Por lo general,

return (0); 

o

return (EXIT_SUCCESS); 

Pero por qué hay paréntesis en declaraciones anteriores? ¿Está relacionado con el lenguaje C o algo así?

// EDITAR

Sé que esto es correcto, pero alguien puso estos soportes por una razón. ¡¿Cual es la razón?!

+0

¿Qué herramienta genera este código? Regresar de 'main' no es necesario en absoluto. – Philipp

+0

Netbeans, Código :: Bloques, Eclipse ... – adf88

+0

Sí, tienes razón, EXIT_SUCCESS, corregido. – adf88

Respuesta

10

No son necesarios (incluso en c). Creo que algunas personas los usan para hacer que el 'retorno' se parezca más a una llamada a función, pensando que es más consistente.

Editar: Es probable que el generador lo haga por sus propios motivos. Puede ser más seguro o más fácil que funcione de esta manera.

+0

¿Pero cuál es el punto si está en el código generado? Pensé en ello de algún tipo de protección. – slaphappy

+3

Quizás el código generado contenga un punto y coma.Entonces, la versión entre paréntesis causaría un error de compilación, mientras que la versión sin paréntesis fallaría silenciosamente o simplemente produciría una advertencia. – Philipp

+0

Encuentro que hay algunas cosas que no me gustan sobre el generador de código particular al que probablemente se está refiriendo ... ej. abrir llaves en la siguiente línea. En #defines, siempre es bueno poner corchetes alrededor de las expresiones, p. Ej. '#defina X (x) (x-2x)' ya que generalmente ayuda cuando haces '3 * X (2)'. No puedo pensar en ninguna buena razón para hacer esto para las devoluciones. – sje397

5

Como se puede pasar cualquier expresión válida para devolver, esos corchetes se pueden agregar si se desea. Es como hacer esto:

int i = (0); 

puede anidar una expresión en otros tantos soportes como le gustaría:

return (((((0))))); 
+6

También puede hacer: devolver (42 - 42); – nas

2

Los que no son obligatorios. Tal vez provienen de la tendencia a preferir más corchetes a menos corchetes when writing macros. Como mencionas el código generado automáticamente, puede ocurrir que el código utilizado para generar macros se haya escrito reutilizando el código para generar macros o por una persona que pensó que no dañarían más corchetes, pero menos corchetes pueden ser fatales.

9

¿Pero por qué hay paréntesis en las declaraciones anteriores ? ¿Está relacionado con el lenguaje C o algo así?

No. Por lo que puedo decir, C nunca ha requerido paréntesis para declaraciones de devolución. Esto parece haber sido el caso incluso antes del primer estándar ANSI C.

Esto es realmente una pregunta muy interesante, sin embargo, como he visto ese estilo prevalece entre ciertos programadores de C.

Creo que la suposición más probable sobre por qué se creó este estilo es porque todas las demás instrucciones de bifurcación (para, while, if, cambiar) requieren paréntesis alrededor de las expresiones. Las personas podrían haber ignorado que podían omitir los paréntesis para las declaraciones de devolución o que estaban al tanto de esto, pero querían lograr un aspecto más uniforme de su código.

El operador ternary?: Es una especie de excepción, ya que es un operador y no requiere paréntesis alrededor de la expresión condicional, sin embargo, las personas suelen escribir paréntesis allí, independientemente de si es necesario. Algunos podrían encontrar que sirve para 'agrupar' una expresión en una sola unidad visualmente.

Mi segunda mejor suposición es que este estilo fue influenciado por otros idiomas populares en ese momento.Sin embargo, las alternativas populares de procedimiento en ese momento como Pascal tampoco requerían esa sintaxis (Pascal ni siquiera tenía valores de retorno en el sentido C, sino solo parámetros de salida), si este es el caso, no estoy al tanto de ningún lenguaje en particular de donde se originó este estilo.

[Subjetivo] Prefiero los estilos que requieren la menor cantidad de decoración superflua para el código, ya se trate de convenciones de nomenclatura o cómo formatearlo o si se usan paréntesis adicionales cuando no es necesario. Creo que cualquier tipo de decoración tiende a ser una cuestión de preferencias personales únicas y enamorarse de una forma de decorar el código solo significa que algún día tendrá que lidiar con una forma completamente diferente (a menos que trabaje estrictamente solo, en cuyo caso Te envidio). [/ Subjetivo]

+0

Usted señaló una muy buena suposición de que esto puede ser un resto de otros tiempos. Si alguien pudiera confirmarlo ... Si se trata de un caso de estilo de codificación y decoración de código adicional, ¿por qué no podemos encontrar este estilo en ningún otro lugar (al menos yo)? Hmm, ¿tal vez esto es una reliquia, algún tipo de tradición? – adf88

+0

@ adf88 Supongo que sí. retorno expr; y return (expr); siempre será el mismo, sin embargo. No podría haber un caso en el que se evaluaría un resultado diferente o no se construiría sin los paréntesis, por lo que es estrictamente una cuestión de preferencia y la gente de hoy podría elegir ese estilo por las mismas razones que algunos programadores de la vieja escuela eligieron ese estilo antes (O tal vez los nuevos programadores solo están mirando su código y lo están imitando). – stinky472

+0

Otro posible factor influyente relacionado con la segunda hipótesis sobre otros lenguajes podría ser los lenguajes funcionales como lisp o sus sucesores. En lisp, todo sigue un formato estricto donde todo está escrito entre paréntesis. Este tipo de uniformidad tenía un gran atractivo para algunos y era odiado por otros, pero aquellos a los que les gustó pudieron haber adaptado su estilo para lograr una mayor sensación de uniformidad visual en su código cuando migraron a C. – stinky472

0

Una de las razones que puedo ver para esto:

return (ERROR_SUCCESS); 

es que está expresando el concepto de que ERROR_SUCCESS es opaca. Todos sabemos que es 0L, pero no deberíamos tener para.

Esa es una razón bastante débil.

Otra es que es estéticamente agradable usar paréntesis para consistencia, otra razón débil.

Por lo tanto, en otras palabras, no lo uso yo mismo, pero no se apagará si alguien más lo hizo. :)

+0

¿Cómo eso "expresa el concepto de que 'ERROR_SUCCESS' es opaco? ¿Qué se supone que significa eso? Pero sea lo que sea, los paréntesis no hacen precisamente nada para cambiarlo. –

1

Sólo mi especulación tonta:

#define RETURN(val) { if (val) printf("Main Exit With Error %d\n", val); return val; } 

int main(argc, argv) 
{ 
    ... 
    RETURN (E_FILENOTFOUND); 
} 
+0

La pregunta era sobre' return', no 'RETURN'. ... Alguien que intenta adoptar un estilo unificado que funcione tanto con la palabra clave real como con una sustitución macro -que justificaría vagamente los paréntesis que de otra manera no servirían de nada- usaría el caso correcto. Si se usan casos diferentes, entonces seguramente solo recordarían usar el paréntesis donde sea necesario. –

2

Hay una razón tonta - para que el retorno se parezca más a una llamada de función.

Hay una razón más inteligente: si el código se genera, los generadores de código a menudo "juegan a lo seguro" poniendo expresiones de paréntesis para que nunca tengan que preocuparse por la filtración de precedencia.

7

Esto es realmente un requisito para el estilo de archivo de fuente del núcleo BSD.

man 9 style dice:

espacio después de las palabras clave (si, mientras que, para, retorno, interruptor).

y

Los valores en sentencias de retorno deben estar encerrados entre paréntesis.

+0

Muy interesante. ¡Gracias! – Kolyunya

+0

Citar a un atuendo que usa el modismo no responde a la pregunta de si logra algo, pero no es así. ¿Su guía de estilo incluso se molesta en intentar justificar esto? –

5

Las cosas cambian con el uso de decltype(auto) en C++ 14 para deducir el tipo de devolución. Si se utilizan paréntesis, se deduce que el tipo devuelto es una referencia:

decltype(auto) foo1() { 
    int n; 
    return (n); // parentheses causes return type to be int& 
} 

decltype(auto) foo2() { 
    int n; 
    return n; // no parentheses causes return type to be int 
} 

template<typename T> struct TD; 

int main() 
{ 
    // main.cpp:19:22: error: aggregate 'TD<int&()> f1' has incomplete type and cannot be defined TD<decltype(foo1)> f1; 
    TD<decltype(foo1)> f1; 

    // main.cpp:20:22: error: aggregate 'TD<int()> f2' has incomplete type and cannot be defined TD<decltype(foo2)> f2; 
    TD<decltype(foo2)> f2; 
} 
Cuestiones relacionadas