¿Hay alguna razón para usar la palabra clave 'auto' en C ++ 03?

85

Tenga en cuenta que esta pregunta se publicó originalmente en 2009, antes de que se ratificara C ++ 11 y antes de que el significado de la autopalabra clave cambiara drásticamente. Las respuestas proporcionadas pertenecen solo al significado de C ++ 03 de auto- que es una clase de almacenamiento especificada - y no al significado de C ++ 11 de auto- que es la deducción automática de tipos. Si está buscando un consejo sobre cuándo utilizar C ++ 11 auto, esta pregunta no es relevante para esa pregunta.

Durante mucho tiempo pensé que no había razón para usar la staticpalabra clave en C, porque las variables declaradas fuera del alcance del bloque eran implícitamente globales. Luego descubrí que declarar una variable como staticdentro del alcance del bloque le daría una duración permanente, y declararla fuera del alcance del bloque (en el alcance del programa) le daría el alcance del archivo (solo se puede acceder en esa unidad de compilación).

Así que esto me deja con una sola palabra clave que (quizás) todavía no entiendo completamente: la autopalabra clave. ¿Tiene algún otro significado que no sea "variable local"? ¿Algo que hace que no se haga implícitamente para usted donde quiera que desee usarlo? ¿Cómo se autocomporta una variable en el alcance del programa? ¿Qué pasa con una static autovariable en el ámbito del archivo? ¿Tiene esta palabra clave algún otro propósito que no sea simplemente existir para completar ?

Carson Myers
fuente

Respuestas:

74

autoes un especificador de clase de almacenamiento static, registery externtambién. Solo puede usar uno de estos cuatro en una declaración.

Las variables locales (sin static) tienen una duración de almacenamiento automático, lo que significa que viven desde el inicio de su definición hasta el final de su bloque. Poner auto delante de ellos es redundante, ya que de todos modos ese es el valor predeterminado.

No conozco ninguna razón para usarlo en C ++. En las versiones antiguas de C que tienen la regla int implícita, puede usarla para declarar una variable, como en:

int main(void) { auto i = 1; }

Para que sea válida la sintaxis o eliminar la ambigüedad de una expresión de asignación en caso de que iesté dentro del alcance. Pero esto no funciona en C ++ de todos modos (debe especificar un tipo). Curiosamente, el estándar C ++ escribe:

Un objeto declarado sin un especificador de clase de almacenamiento en el alcance del bloque o declarado como un parámetro de función tiene una duración de almacenamiento automática por defecto. [Nota: por lo tanto, el especificador automático es casi siempre redundante y no se usa con frecuencia; un uso de auto es distinguir explícitamente una declaración-declaración de una expresión-declaración (6.8). - nota final]

que se refiere al siguiente escenario, que podría ser una conversión de ato into la declaración de una variable ade tipo que inttiene paréntesis redundantes alrededor a. Siempre se toma como una declaración, por autolo que no agregaría nada útil aquí, sino que lo haría para el humano. Pero, de nuevo, el humano estaría mejor si eliminara los paréntesis redundantes a, yo diría:

int(a);

Con el nuevo significado de autollegar con C ++ 0x, desaconsejaría usarlo con el significado de C ++ 03 en el código.

Johannes Schaub - litb
fuente
4
Los compiladores de C ++ solían tener int implícito para los valores de retorno de las funciones, en el ARM días antes del estándar ... Antes del EMPIRE ...
Daniel Earwicker
1
Lo reconocí como mi forma de compiladores de decirme que olvidé declarar una función. Me diría que mi uso de una función era diferente de la forma en que se declaró debido a int implícito.
Carson Myers
29
La mejor parte es que los programadores solían escribir "auto" (cuatro letras) para evitar escribir "int" (tres letras).
Max Lybbert
30
@Max - hey, mucha gente dice "doble-u-doble-u-doble-u" como abreviatura de "World Wide Web".
Daniel Earwicker
3
@smichak no, "volatile" es un calificador de tipo. En lugar de determinar dónde almacenar un valor, cambia el comportamiento de una escritura y lectura de un objeto del tipo calificado volátil. Puede haber variables de pila calificadas volátiles (clase de almacenamiento automático), así como variables de duración de almacenamiento estáticas calificadas volátiles (clase de almacenamiento 'estática' local, variables no locales). Aparte de eso, no sé si "registro volátil" es una combinación válida :)
Johannes Schaub - litb
86

En C ++ 11, autotiene un nuevo significado: le permite deducir automáticamente el tipo de una variable.

¿Por qué es eso útil? Consideremos un ejemplo básico:

std::list<int> a;
// fill in a
for (auto it = a.begin(); it != a.end(); ++it) {
  // Do stuff here
}

El autono crea un iterador de tipo std::list<int>::iterator.

Esto puede hacer que un código realmente complejo sea mucho más fácil de leer.

Otro ejemplo:

int x, y;
auto f = [&]{ x += y; };
f();
f();

Allí, autodedujeron el tipo requerido para almacenar una expresión lambda en una variable. Wikipedia tiene una buena cobertura sobre el tema.

std''OrgnlDave
fuente
4
Todavía no estoy seguro de si este es un gran uso de auto. ¡El código debe ser fácil de leer, no fácil de escribir!
DanDan
38
No sé ustedes, pero encuentro esto mucho más fácil de leer que el spam de tipo iterador.
Overv el
17
Y si por alguna resonancia decide cambiar la clase de la lista <int> a otra clase, no tiene que buscar cada declaración de iterador y cambiarla.
roslav
2
@KarateSnowMachine: Si quisieras la constante, usarías "const auto" en lugar de "auto".
darth happyface
4
@darth const auto it = a.begin();te daría una constante iterator, no una const_iterator. Aún podría cambiar el elemento, pero ++itfallaría al compilar. Para obtener un const_iterator, usaríaauto it = a.cbegin();
fredoverflow
35

La palabra clave auto no tiene ningún propósito en este momento. Tiene exactamente razón en que simplemente reafirma la clase de almacenamiento predeterminada de una variable local, siendo la alternativa realmente útil static.

Tiene un significado completamente nuevo en C ++ 0x. ¡Eso te da una idea de lo inútil que fue!

Daniel Earwicker
fuente
1
oh hombre, eso es siempre inútil. Aunque me gusta el nuevo significado. Hace que algunos códigos sean mucho menos detallados y redundantes.
Carson Myers
Sí, habiendo usado el equivalente en C # probablemente hará una gran diferencia. Más aún en C ++ si está utilizando plantillas de expresión donde los tipos son tan complejos que nunca se pensó que se escribieran a mano.
Daniel Earwicker
7

GCC tiene un uso especial de autopara funciones anidadas; consulte aquí .

Si tiene una función anidada que desea llamar antes de su definición, debe declararla con auto.

qrdl
fuente
esta es una gran implementación de auto, aunque depende del compilador. Gracias por la investigación :)
Carson Myers
3

"auto" supuestamente le dice al compilador que decida por sí mismo dónde colocar la variable (memoria o registro). Su análogo es "registro", que supuestamente le dice al compilador que intente mantenerlo en un registro. Los compiladores modernos ignoran ambos, por lo que usted también debería hacerlo.

TED
fuente
1
No exactamente - si lo declaras con "register", los compiladores no te permiten usar el operador address-of (& foo) en la variable porque, bueno, no existe en ninguna parte de la memoria (y por lo tanto no tiene dirección).
Tim Čas
3

Utilizo esta palabra clave para documentar explícitamente cuando es fundamental para la función, que la variable se coloque en la pila, para procesadores basados ​​en pila. Esta función puede ser necesaria cuando se modifica la pila antes de regresar de una función (o interrumpir la rutina de servicio). En este caso declaro:

auto unsigned int auiStack[1];   //variable must be on stack

Y luego accedo fuera de la variable:

#define OFFSET_TO_RETURN_ADDRESS 8     //depends on compiler operation and current automatics
auiStack[OFFSET_TO_RETURN_ADDRESS] = alternate_return_address;

Entonces, la autopalabra clave ayuda a documentar la intención.

lucas
fuente
Supongo que esto es solo una intención de señalización, ya que la palabra clave en realidad no impone la ubicación de la pila, más que simplemente omitirla.
underscore_d
2

Según Stroustrup, en "El lenguaje de programación C" (cuarta edición, que cubre C 11), el uso de 'auto' tiene las siguientes razones principales (sección 2.2.2) (se citan las palabras de Stroustrup):

1)

La definición tiene un gran alcance en el que queremos que el tipo sea claramente visible para los lectores de nuestro código.

¡Con 'auto' y su inicializador necesario podemos conocer el tipo de variable de un vistazo!

2)

Queremos ser explícitos sobre el rango o la precisión de la variable (por ejemplo, doble en lugar de flotante)

En mi opinión un caso que encaja aquí, es algo como esto:

   double square(double d)
    {
        return d*d; 
    }

    int square(int d)
    {
        return d*d; 
    }

    auto a1 = square(3);

    cout << a1 << endl;

    a1 = square(3.3);

    cout << a1 << endl;

3)

Usando 'auto' evitamos la redundancia y la escritura de nombres largos.

Imagine un nombre de tipo largo de un iterador con plantilla:

(código de la sección 6.3.6.1)

template<class T> void f1(vector<T>& arg) {
    for (typename vector<T>::iterator p = arg.begin(); p != arg.end();   p)
        *p = 7;

    for (auto p = arg.begin(); p != arg.end();   p)
        *p = 7;
}
wesley.mesquita
fuente
1

En el compilador antiguo, auto era una forma de declarar una variable local. No puede declarar variables locales en compiladores antiguos como Turbo C sin la palabra clave auto o algo así.

chaz
fuente
1

El nuevo significado de la palabra clave auto en C ++ 0x se describe muy bien por Stephan T. Lavavej de Microsoft en una conferencia en video sobre STL que se puede ver / descargar libremente que se encuentra en el sitio del Canal 9 de MSDN aquí. .

Vale la pena ver la conferencia en su totalidad, pero la parte sobre la palabra clave auto está aproximadamente en el minuto 29 (aproximadamente).

Sabuncu
fuente
0

¿Hay algún otro significado para 'auto' que no sea 'variable local'?

No en C ++ 03.

¿Algo que hace que no se haga implícitamente para usted donde quiera que desee usarlo?

Nada en absoluto, en C ++ 03.

¿Cómo se comporta una variable automática en el ámbito del programa? ¿Qué pasa con una variable automática estática en el alcance del archivo?

Palabra clave no permitida fuera del cuerpo de una función / método.

¿Tiene esta palabra clave algún propósito [en C ++ 03] que no sea simplemente existir para completar?

Sorprendentemente, sí. Los criterios de diseño de C ++ incluían un alto grado de compatibilidad con versiones anteriores de C. C tenía esta palabra clave y no había ninguna razón real para prohibirla o redefinir su significado en C ++. Entonces, el propósito era una incompatibilidad menos con C.

¿Esta palabra clave tiene algún propósito en C que no sea simplemente existir para completar?

Aprendí uno solo recientemente: la facilidad para portar programas antiguos de B. C evolucionó a partir de un lenguaje llamado B cuya sintaxis era bastante similar a la de C. Sin embargo, B no tenía ningún tipo. La única forma de declarar una variable en B era especificar su tipo de almacenamiento ( autoo extern). Me gusta esto:

auto i;

Esta sintaxis todavía funciona en C y es equivalente a

int i;

porque en C, la clase de almacenamiento es predeterminada autoy el tipo es predeterminado int. Supongo que todos los programas que se originaron en B y se portaron a C estaban literalmente llenos de autovariables en ese momento.

C ++ 03 ya no permite el int implícito del estilo C, pero conservó la autopalabra clave que ya no es exactamente útil porque, a diferencia del int implícito, no se sabía que causara ningún problema en la sintaxis de C.

Jirka Hanika
fuente