¿Es i, j = 1 realmente engañoso? [cerrado]

11

Hay un argumento común sobre la inicialización de múltiples variables en un solo revestimiento, es decir:

Considere por ejemplo int i, j = 1; lo que podría llevar a algunas personas a creer erróneamente que ambas variables se están inicializando

Podríamos argumentar que alguien debería saber lo suficiente la sintaxis de su lenguaje para no equivocarse al respecto. Otro argumento podría ser, como desarrolladores, aprendemos tantos idiomas que podemos cometer errores entre las especificidades entre idiomas.

Sin embargo, para ese caso muy específico, me pregunto lo siguiente: ¿existe incluso un lenguaje en el que la sintaxis misma i, j = 1 inicialice ambas variables?

Si no ese argumento, entonces no se aplica.

Walfrat
fuente
2
Si su idioma es sensato, la posible confusión es inofensiva porque acceder a una variable no inicializada desencadena un error del compilador.
CodesInChaos
44
@CodesInChaos, ¿estás diciendo que C no está cuerdo?
Baldrickk
2
El hecho de que un lenguaje permita algo no significa que no estés causando dolor innecesario a los humanos. El único lugar para el que se solicita este código es durante las pruebas diseñadas para castigar a aquellos que no han memorizado la especificación del idioma. Siempre fallé este tipo de preguntas. Bleh
candied_orange
2
En Visual Basic 6 Dim Apple, Orange, Pear as Fruites una declaración legal. Supongamos que no sabes VB. ¿Tu primera impresión Applees de tipo Fruit? No lo es. Recuerde, los idiomas a menudo son leídos por personas que no son expertos en ese idioma; Si es un experto, use el lenguaje sabiamente para comunicar sus intenciones claramente incluso a los no expertos. Nunca uso múltiples inicializaciones en ningún idioma.
Eric Lippert
13
Del mismo modo: considere var x = 1, y = 1.5; ¿Es esto lo mismo int x = 1; double y = 1.5;o es lo mismo que double x = 1, y = 1.5;? Cuando agregamos vara C # 3.0, hice una encuesta y descubrí que aproximadamente la mitad de las personas creía que la primera era "obviamente" correcta y la otra mitad creía que la otra era "obviamente" correcta, por lo que lo hicimos ilegal. Una característica que engaña completamente a la mitad de la población es una mala característica.
Eric Lippert

Respuestas:

37

Creo que no, pero ese no es el punto. El punto es que i, j = 0se confunde muy fácilmente i = j = 0, lo que inicializa ambos. La claridad es el requisito más importante en el código fuente junto a la corrección, y el hecho de que esta pregunta incluso surja demuestra que la claridad es subóptima.

Kilian Foth
fuente
3
También diría que si tal declaración no inicializa ambas declaraciones, ¿por qué existe?
Berin Loritsch
2
@BerinLoritsch depende del idioma. Esto se hace con frecuencia en JavaScript debido al levantamiento de declaraciones: muchos consideran la mejor práctica declarar variables en la parte superior del alcance en el que están disponibles, incluso si no las inicializa hasta el lugar en que se usan en el código . Casi todas las herramientas de transformación de código salen de esta manera.
Jared Smith
1
Supongo que una cosa es que una herramienta de salida de código hiciera esto, ya que se supone que es confiable. Sin embargo, para los humanos, recomendaría que no combine la declaración y la inicialización del último elemento solo en una línea. Simplemente parece un error esperando a suceder.
Berin Loritsch
2
@JaredSmith Además de Maple, no puedo pensar en un lenguaje en el que esto se desee actualmente, incluso C ahora prefiere un alcance más cercano (como C ++ y la mayoría de los otros lenguajes con compiladores estáticos medio decentes) porque brinda el beneficio de detener posibles errores y permite el compilador para decidir qué hacer con la variable siempre que la funcionalidad no cambie, lo que posiblemente permita mejores optimizaciones dado que podría salirse con menos registros.
cuando
66
Independientemente del idioma, uno debe preguntarse "¿Cuál es el beneficio de la escritura int i, j=1versus int i; int j = 1(o incluso mejor, líneas separadas)?"
chepner
2

Creo que puedes argumentar por cualquier lado:

  • Kontra i, j = 0: Los
    matemáticos usan esto para significar que ambos iy jse supone que son cero.

  • Pro i, j = 0:
    es una simple cuestión de conocer la precedencia de sus operadores. Y si tiene dudas sobre su precedencia, ahora es el momento de buscarlo.

    Es la misma razón por la que escribimos cosas a.b += c[i]*d[i];sin paréntesis. Por supuesto, esto es equivalente a (a.b) += ((c[i])*(d[i]));, pero se puede esperar que los programadores sepan de antemano la precedencia de los operadores más utilizados y puedan buscar la precedencia de los operadores cuando no estén seguros. Por lo tanto, los paréntesis generalmente se consideran desorden inútil a menos que forcen un orden de evaluación diferente al que prescribiría la precedencia del operador.

    Por supuesto, hay excepciones. La precedencia de <<y +generalmente se considera lo suficientemente ambigua como para evitar paréntesis en cualquier caso. Pero esa es la excepción que prueba la regla.

Yo, por mi parte, caería más en el lado Pro, pero estoy preparado para apegarme a cualquier guía de estilo que prohíba tales declaraciones. Simplemente no es un asunto por el que valga la pena luchar.

cmaster - restablecer monica
fuente
77
Observo que int i, j = 0;no tiene operadores . La única expresión en esa declaración es 0y, por lo tanto , la precedencia del operador no entra en ella. El analizador no se trata ,como el operador de coma o =como el operador de asignación; más bien, estas son partes gramaticales de la declaración de declaración.
Eric Lippert
@EricLippert En lo que respecta a las reglas de precedencia, esa diferencia es irrelevante: cualquier lenguaje de estilo C que conozca utiliza las mismas precedencia en una declaración que en otras expresiones. Cualquier otra cosa invitaría al desastre.
cmaster - reinstalar a monica el
but programmers can be expected to know the precedence of the most used operators by heart, tu dices. En el ejemplo que da, no estoy seguro de que la mayoría de los programadores (promedio) conciban al operador de acceso de miembros o al operador del índice de matriz como operadores en absoluto en el sentido matemático, sino que los consideran más como sustantivos de lenguaje natural y la multiplicación operador como el verbo. ¡Es por eso que int i, j, k = 0;es una construcción tan diabólica, porque se presenta como el lenguaje análogo natural de "int variables i, j, y k, se declaran y se establecerán en 0"!
Steve
@Steve Cómo recuerda las reglas de precedencia como programador, depende completamente de usted. Si te ayuda a pensar en ellos como sustantivos del idioma, hazlo. Sin embargo, en ese caso te encontrarás con problemas cuando veas cosas como *a[i], no creo que puedas analizarlo lo suficiente con la analogía de los "sustantivos". En cuanto a int i, j, k = 0;eso, eso podría significar cualquier cosa si no busca las reglas: una tercera interpretación sería declarar int i, luego evaluar jy finalmente asignar k = 0. A menos que conozca la sintaxis de su idioma, no puede analizar tales construcciones. Es tu problema si lo haces de todos modos.
cmaster - reinstalar a monica el
@cmaster, no estaba expresando mi estrategia de memorización específica jaja. No soy un programador en C, por lo que mi familiaridad con la precedencia del operador en C es de segunda categoría. Pero lo que noté cuando vi su ejemplo es que ni siquiera pensé que el operador de multiplicación tuviera una precedencia relativa al operador de índice de matriz. Es decir, no leí a[i]como un operador de índice aplicado a, sino que leí ambos juntos como un elemento sintáctico irreducible que especifica el operando del operador de multiplicación, y por lo tanto ni siquiera me pidieron que evaluara la precedencia. (1/2)
Steve