En C / C ++, ¿debería usar 'const' en parámetros y variables locales cuando sea posible?

13

Esta pregunta está inspirada en una pregunta sobre finalen java .

En C / C ++, ¿debería usarlo constsiempre que sea posible?

Sé que ya hay una pregunta relacionada sobre el uso consten parámetros . Desafortunadamente, esa pregunta y sus respuestas no responden completamente a mi pregunta, porque solo se trata de parámetros de función, pero también me gustaría saber sobre otros casos (por ejemplo, variables locales).

Además, casi todas las respuestas a esa pregunta dicen que deberíamos usarla constporque contiene información útil sobre la accesibilidad de las variables. Pero esto parece estar en conflicto con una respuesta sobre el uso de final en Java, que finalpuede ser superfluo si no contiene información adicional, por lo que debe omitirse para mantener el código corto y limpio.

Entonces, ¿debería usarlo constsiempre que sea posible? Si es así, ¿por qué los consejos para constC ++ son diferentes de los consejos para finalJava?

ocomfd
fuente

Respuestas:

18

En primer lugar, dado que ha hecho referencia a Java final, esa es una bestia totalmente diferente a const. Final significa que la referencia no puede cambiar, pero no dice nada sobre la mutabilidad. Const va más allá al decir que "una referencia const no puede mutar", que es una garantía mucho más sólida. Para hacer esto en Java, el estado interno debe ser final y determinado en el momento de la construcción. Const es mucho más fácil de usar, y un objeto existente se puede "promocionar" en una referencia const.

Sí, debe usar const siempre que sea posible. Hace un contrato que su código no cambiará algo. Recuerde, una variable no const se puede pasar a una función que acepte un parámetro const. Siempre puede agregar const, pero no eliminarlo (no sin un elenco const, que es una muy mala idea).

La corrección del contraste puede ser tediosa a veces, pero ayuda a garantizar la inmutabilidad. Esto es crucial en el código multiproceso donde los subprocesos comparten objetos. Hace que ciertas tareas sean más eficientes: en lugar de copiar el estado, simplemente reutilice el mismo objeto inmutable. Las bibliotecas pueden aceptar parámetros constantes para proporcionar una garantía al programador de que no, su objeto no cambiará de manera impredecible en el agujero negro que es el intestino de la biblioteca.


fuente
1
Vota porque explicas eso finaly constno tienes las mismas garantías.
Bill Door,
2
Constness se trata de escritura, no de mutabilidad.
Basilevs
@Basilevs, ¿qué sucede si escribes en un objeto? Muta ¿Cómo mutas un objeto? Escríbele.
44
¿Qué sucede si escribes en una referencia constante? Un error de tiempo de compilación. ¿Qué sucede si escribe en el objeto al que se hace referencia en algún lugar por referencia constante a través de otra referencia no constante? Muta El objeto inmutable no puede mutar, por lo tanto, la referencia constante no necesariamente hace referencia al objeto inmutable.
Basilevs
@Basilevs su observación solo se aplica con las referencias constantes. Si un objeto en sí mismo se declara constante (no solo la referencia), entonces es más o menos inmutable (a menos que alguien deseche la constidad).
Matthew James Briggs el
4

Personalmente, constme lleva muy poco tiempo escribir, y muy poco tiempo leer, generalmente mucho menos de lo que se necesita para verificar si algún código muta la variable, y en realidad me impide escribir errores (¿alguien alguna vez incrementó su iterador final por accidente? Etc)

También encuentro que ser estricto sobre el uso de const me guía hacia un mejor código de otras maneras, como crear funciones de ayuda para hacer una inicialización no trivial.

Bwmat
fuente
4

No voy a estar de acuerdo con los otros carteles y le recomiendo que no use el nivel superior consten variables y parámetros locales. (Las referencias y punteros a constante, es decir const T&, son diferentes, y debe usarlos para la corrección en todo momento cuando sea apropiado).

Las ventajas del nivel superior constson:

  • Deja en claro que las variables locales no están destinadas a ser mutadas.
  • Da un error de compilación si accidentalmente intenta mutarlos.

Las desventajas son:

  • Desorden visual.
  • No se puede usar en variables "pseudoconst", es decir, variables que se inicializan de alguna manera más complicadas que la construcción directa, pero que no se modifican después, por ejemplo, usando getline:

    std::string line; // cannot be const
    std::getline(std::cin, line);
    // line should be const from here on out
  • Evita la optimización de movimiento en la llamada a la función y el retorno:

    std::string f1();
    std::string f2(std::string s);
    std::string f3() {
      const std::string s = f1(); // s is not meant to be modified
      // but I still want the move optimization here:
      const std::string result = f2(std::move(s)); // this doesn't move
      // and I want the compiler to move out here:
      return result; // this will probably RVO, but if not, the move
                     // constructor will not be used due to the const
    }

He trabajado en una base de código donde constse usaba mucho el local , y no lo encontré útil en absoluto, sin embargo, llenó el código con pesadas sutiles como se indicó anteriormente. Personalmente prefiero adoptar una política general de modificación de variables tan raramente como sea posible, y hacer que las funciones sean lo suficientemente pequeñas como para que el uso de una variable sea obvio, e incluso si se modifica, la complejidad de la función es lo suficientemente baja como para que no -problema.

Sebastian Redl
fuente
2
Su punto sobre la mudanza es mostrar dónde no está usando el local de manera constante, ya que (tiene la intención) de modificarlo con el movimiento
Caleth
1
@Caleth No, ese es el punto. No tengo la intención de modificarlo. Solo quiero pasar el valor, o devolverlo, y quiero que sea eficiente. Conceptualmente, la modificación es solo una optimización, que no debe ser observable (ya que las variables no se usan después). Prácticamente, sí, hay una modificación, ya que C ++ no tiene verdaderos movimientos destructivos (como Rust). Eso es exactamente por qué no quiero consten los locales: porque evita modificaciones técnicas, no solo modificaciones conceptuales.
Sebastian Redl
2
No desea modificar el valor , pero sí desea modificar la variable . En su lugar, puede usar const & en su lugar, y no modificar ninguno
Caleth
2

La constpalabra clave debe usarse para variables locales, al igual que los parámetros. Es útil porque:

  • Más fácil de leer el código. Cuando alguien lee la declaración de variable, sabe que no cambiará. Una cosa menos de qué preocuparse al leer su código.
  • Evitar que accidentalmente modifique la variable
  • Sin penalización de tiempo de ejecución, todo se verifica estáticamente. Es como un almuerzo gratis, constdebería tomar solo un segundo para escribir, así que no es gran cosa.
  • Siempre es una buena idea hacer sus variables / parámetros en sus aplicaciones de subprocesos múltiples. Incluso su aplicación no es multiproceso, sigue siendo un buen hábito.
  • Le da una oportunidad a su compilador de C ++ para optimizar su código.

Tenga en cuenta que no hay una respuesta correcta / incorrecta aquí. En su enlace, el respondedor que tuvo la mayor cantidad de votos argumentados finalno debe usarse localmente. Sin embargo, el siguiente respondedor lo recomendó encarecidamente.

Si su función es simple y trivial , no debe agregar constporque todos entienden su intención. Sin embargo, si la lógica en su función no es trivial, debe usar la palabra clave. Recuerde, hay poco que perder.

Hola Mundo
fuente