I, j = 1 é realmente enganoso? [fechadas]

11

Existe um argumento comum sobre a inicialização de múltiplas variáveis ​​em um único liner, ou seja:

Considere, por exemplo, int i, j = 1; o que pode levar algumas pessoas a acreditar erroneamente que ambas as variáveis ​​estão sendo inicializadas

Poderíamos argumentar que alguém deveria conhecer a sintaxe suficiente de sua linguagem para não se enganar sobre isso. Outro argumento pode ser que, como desenvolvedores, aprendemos tantas línguas que podemos cometer erros entre as especificidades entre as línguas.

No entanto, para esse caso muito específico, estou me perguntando o seguinte: existe uma linguagem em que a própria sintaxe i, j = 1 inicializa as duas variáveis?

Caso contrário, esse argumento não se aplica.

Walfrat
fonte
2
Se o seu idioma estiver correto, a confusão potencial será inofensiva, pois o acesso a uma variável não inicializada aciona um erro do compilador.
CodesInChaos
4
@CodesInChaos você está dizendo que C não é são?
precisa
2
Só porque uma linguagem permite algo não significa que você não está causando dor desnecessária aos humanos. O único lugar em que esse código é necessário é durante os testes projetados para punir aqueles que não memorizaram a especificação de idioma. Eu sempre falhei nesses tipos de perguntas. Bleh.
68718 Marion
2
No Visual Basic 6 Dim Apple, Orange, Pear as Fruité uma declaração legal. Suponha que você não conheça o VB. Sua primeira impressão Appleé do tipo Fruit? Não é. Lembre-se de que os idiomas são frequentemente lidos por pessoas que não são especialistas nesse idioma; se você é um especialista, use o idioma com sabedoria para comunicar claramente suas intenções, mesmo para não especialistas. Eu nunca uso várias inicializações em qualquer idioma.
22818 Eric Clippert
13
Da mesma forma: considere var x = 1, y = 1.5; É o mesmo int x = 1; double y = 1.5;ou é o mesmo que double x = 1, y = 1.5;? Quando adicionamos varao C # 3.0, fiz uma pesquisa e descobri que cerca de metade das pessoas acreditava que a primeira estava "obviamente" correta e a outra metade acreditava que a outra estava "obviamente" correta, e por isso a tornamos ilegal. Um recurso que engana totalmente metade da população é um recurso ruim.
22818 Eric Clippert

Respostas:

37

Acho que não, mas esse não é o ponto. O ponto é que i, j = 0é muito facilmente confundido com i = j = 0, que faz initialize ambos. A clareza é o requisito mais importante no código-fonte, próximo à correção, e o fato de que essa questão ainda se coloca prova que a clareza é subótima.

Kilian Foth
fonte
3
Eu também argumentaria que, se essa afirmação não inicializa as duas, por que ela existe?
Berin Loritsch
2
@BerinLoritsch depende do idioma. Isso geralmente é feito no JavaScript por causa da elevação da declaração: muitos consideram a melhor prática declarar variáveis ​​no topo do escopo em que estão disponíveis, mesmo que você não as inicialize até o local em que elas são usadas no código . Quase todas as ferramentas de transformação de código são produzidas dessa maneira.
21418 Jared Smith #:
1
Suponho que seja uma coisa se uma ferramenta de saída de código fizer isso, já que isso é confiável. No entanto, para humanos, eu recomendaria não combinar a declaração e a inicialização do último elemento apenas em uma linha. Parece apenas um bug esperando para acontecer.
Berin Loritsch 6/0318
2
@JaredSmith Além do Maple, não consigo pensar em uma linguagem em que isso seja desejado atualmente, mesmo C agora prefere mais próximo do escopo (como C ++ e a maioria das outras linguagens com compiladores estáticos decentes) porque oferece o benefício de interromper possíveis bugs e permite o compilador para decidir o que fazer com a variável, desde que a funcionalidade não seja alterada, potencialmente permitindo melhores otimizações, pois você pode se safar com menos registros.
whn
6
Independentemente do idioma, deve-se perguntar "Qual é o benefício de escrever int i, j=1versus int i; int j = 1(ou melhor ainda, linhas separadas)?"
chepner
2

Eu acho que você pode argumentar de ambos os lados:

  • Kontra i, j = 0: Os
    matemáticos usam isso para significar que ambos ie jdeveriam ser zero.

  • Pro i, j = 0:
    É uma simples questão de conhecer a precedência de seus operadores. E se você tiver dúvidas sobre a precedência deles, agora é a hora de procurá-lo.

    É a mesma razão pela qual escrevemos coisas como a.b += c[i]*d[i];sem parênteses. É claro que isso equivale a (a.b) += ((c[i])*(d[i]));, mas é esperado que os programadores conheçam a precedência dos operadores mais usados ​​de cor e possam procurar a precedência dos operadores quando não tiverem certeza. Assim, os parênteses são geralmente considerados desordenados inúteis, a menos que forçam uma ordem de avaliação diferente da prescrita pela precedência do operador.

    Claro, há exceções. A precedência <<e +geralmente é considerada ambígua o suficiente para garantir parênteses em ambos os casos. Mas essa é a exceção que prova a regra.

Eu, por exemplo, cairia mais no lado profissional, mas estou preparado para seguir qualquer guia de estilo que proíba tais declarações. Simplesmente não vale a pena brigar.

cmaster - restabelece monica
fonte
7
Noto que int i, j = 0;não há operadores nele. A única expressão nessa declaração é 0e, portanto , a precedência do operador não entra nela. O analisador não trata ,como o operador de vírgula ou =como o operador de atribuição; pelo contrário, essas são partes gramaticais da declaração.
22618 Eric Clippert
@EricLippert No que diz respeito às regras de precedência, essa diferença é irrelevante: qualquer linguagem de estilo C que eu conheça usa as mesmas precedências em uma declaração que em outras expressões. Qualquer outra coisa convidaria desastre.
Cmaster - reinstate monica
but programmers can be expected to know the precedence of the most used operators by heart, você diz. No exemplo que você dá, não tenho certeza de que a maioria dos programadores (médios) concebe o operador de acesso a membros ou o operador de índice de matriz como sendo operadores no sentido matemático, mas pense neles mais como substantivos da linguagem natural e a multiplicação operador como o verbo. É por isso que int i, j, k = 0;é uma construção tão diabólica, porque se apresenta como o análogo da linguagem natural das "variáveis ​​int i, j e k, são declaradas e devem ser definidas como 0"!
Steve
@ Steve Como você se lembra das regras de precedência como programador, é totalmente sua. Se ajudar a pensar neles como substantivos da língua, faça-o. No entanto, nesse caso, você terá problemas quando vir coisas assim *a[i], não acho que você possa analisar isso suficientemente com a analogia dos "substantivos". Quanto a int i, j, k = 0;isso, isso pode significar qualquer coisa, se você não procurar as regras: uma terceira interpretação seria declarar int i, depois avaliar je finalmente atribuir k = 0. A menos que você conheça a sintaxe do seu idioma, não poderá analisar essas construções. O problema é seu se você fizer assim mesmo.
cmaster - restabelece monica
@ master, eu não estava expressando minha estratégia de memorização específica haha. Como não sou programador em C, minha familiaridade com a precedência do operador em C é de segunda categoria. Mas o que notei quando olhei para o seu exemplo é que eu nem pensava no operador de multiplicação como tendo uma precedência relativa ao operador de índice de matriz. Ou seja, eu não li a[i]como um operador de índice aplicado a, mas li os dois juntos como um elemento sintático irredutível, especificando o operando do operador de multiplicação e, portanto, nem fui solicitado a avaliar a precedência. (1/2)
Steve