¿Por qué Clang advierte: `’&&’ dentro de ‘||’`?

4 minutos de lectura

Tengo entendido que los paréntesis no hacen ninguna diferencia, entonces, ¿hay alguna razón (aparte de “mejorar” la claridad del código) por la que Clang advierte esto como predeterminado? Prefiero no agregar los paréntesis porque no me gusta agregar código por el código.

src/websocket.c:420:43: warning: '&&' within '||' [-Wlogical-op-parentheses]
        if (rv == 0 && N != 0 || rv == -1 && errno == ECONNRESET) {
                              ~~ ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
src/websocket.c:420:43: note: place parentheses around the '&&' expression to
      silence this warning
        if (rv == 0 && N != 0 || rv == -1 && errno == ECONNRESET) {
                                 ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~

  • ¿Qué tal agregar código para claridad ¿motivo? Los paréntesis aquí ayudarían a las personas que no recuerdan las reglas sobre la precedencia de && y || (que no todos los que a menudo surgen).

    – chao

    5 de junio de 2013 a las 12:30


  • Estoy a favor de agregar código para mejorar la claridad. Personalmente, sin embargo, creo que el ruido visual adicional de los paréntesis innecesarios reduce la claridad en este caso. Cuando veo los paréntesis adicionales, inmediatamente escaneo toda la línea buscando una razón para ellos, cuando no encuentro ninguno, entonces tengo que reflexionar por un momento si lo leí mal o si el código en cuestión simplemente está tratando de “ayudarme”. para entender la precedencia del operador, eso ya lo sabía. este codigo es definitivamente no apto para codificadores sin experiencia, la mayoría de las personas que lo lean estarán a mi nivel y, por lo tanto, supongo que sentirán lo mismo.

    – mxcl

    5 de junio de 2013 a las 12:33


  • @KingsIndian Compilers también advierten sobre if (x = 3), lo cual es perfectamente legal. El punto es que se considera algo en lo que las personas a menudo se equivocan, por lo que los escritores del compilador decidieron que vale la pena una advertencia.

    –Daniel Fischer

    5 de junio de 2013 a las 12:43

  • Siempre corrijo las advertencias también, y me parece ridículo que la gente abogue por agregar código innecesario para ayudar a las personas que no han podido aprender cosas importantes como precedencia del operador. Dios no permita que alguna vez emplee a un programador tan terrible.

    – mxcl

    5 de junio de 2013 a las 16:51

  • ¿Por qué todos defienden esta advertencia con tanta vehemencia? ¿Cómo te sentirías si el compilador te advirtiera cada vez que dices “2 + 3 * 4”? Es más que ridículo. La suposición es que los programadores tienen un básico comprensión del idioma con el que están trabajando y no necesitan desorden visual para comprender la precedencia. En otra nota, Xcode no parece proporcionar una opción para deshabilitar esto de forma predeterminada…

    – Felipe Guin

    17 de junio de 2013 a las 21:53


La tendencia natural es leerlo de izquierda a derecha y es fácil olvidar la precedencia del operador. Dicho esto, es solo una advertencia, y si sabes lo que estás haciendo y tu propio estilo te lo permite, siéntete libre de suprimirlo.

  • Para aquellos que deseen suprimirlo, agregue: -Wno-logical-op-parentheses a los CFLAGS de su sistema de compilación.

    – mxcl

    5 de junio de 2013 a las 12:29

Supongo que porque simplemente no está claro, a menos que el lector sea muy bueno en Reglas de precedencia de operadores de C.

Tu expresión es así:

if (A && B || C && D)

y desde && tiene mayor prevalencia que ||significa

if ((A && B) || (C && D))

que supongo que es lo que quieres decir, pero no está muy claro al leer.

  • En mi humilde opinión, cualquiera que haya estudiado lógica básica al menos un poco debería recordar que en matemáticas, Y tiene mayor precedencia que O. Creo que el compilador está siendo bastante paranoico aquí. (Es decir, este definitivamente no es el mismo caso que if (a = 0).)

    usuario529758

    28 de septiembre de 2013 a las 9:19


  • Totalmente de acuerdo: esta es la advertencia más inútil que he visto. ¿Por qué permite escribir 1+2*3 y no sugiere cambiarlo a 1+(2*3)?

    – Alejandro Kirillin

    30 de enero de 2014 a las 19:34

  • Probablemente porque en el mundo real la mayoría de los codificadores están bastante seguros de lo que 1+2*3 hace exactamente, mientras que la mayoría de ellos no están seguros de qué a && b || c && d hará exactamente.

    – Drax

    5 de agosto de 2014 a las 8:12

  • Cuando && y || no están sobrecargados, sin embargo, no lo es A && B || C && D interpretado más como if (A && B) { return true; } else if (C && D) { return true; } else { return false; }? Diciendo que && tiene mayor precedencia un poco implica que C && D será evaluado antes de la ||pero mi entendimiento actual es que una traducción más precisa sería A && (B || (C && D)). Esta distinción, por supuesto, solo es relevante para las nanooptimizaciones. De cualquier manera, la conclusión más importante de la advertencia es definitivamente que A && (B || C) && D es una interpretación incorrecta.

    – M-píxel

    19 de enero de 2018 a las 18:41

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad