¿Dónde se usa la palabra clave C auto?

104

En mi época universitaria leí sobre la autopalabra clave y con el tiempo me olvidé de lo que es. Se define como:

define una variable local que tiene una vida útil local

Nunca encontré que se esté usando en ningún lugar, ¿se usa realmente y, de ser así, dónde se usa y en qué casos?

Vijay
fuente

Respuestas:

90

autoes un modificador como static. Define la clase de almacenamiento de una variable. Sin embargo, dado que el valor predeterminado para las variables locales es auto, normalmente no es necesario especificarlo manualmente.

Esta página enumera diferentes clases de almacenamiento en C.

Mehrdad Afshari
fuente
13
Estaba mirando esto nuevamente después de que alguien votó mi respuesta. Dice que "normalmente no es necesario especificarlo manualmente". Solo tengo que preguntar: ¿existe realmente una circunstancia en la que auto se pueda especificar pero no sucederá de forma predeterminada?
Jerry Coffin
2
@JerryCoffin No en C. En C ++ 11, se reutiliza y puede usarlo para obtener de manera efectiva la inferencia de tipo de variable local.
Mehrdad Afshari
2
Un uso posible es la declaración directa de funciones anidadas en GNU C, aunque esto es un secuestro de la definición original de auto. tigcc.ticalc.org/doc/keywords.html#auto
josiah
2
La página vinculada está desactualizada. Desde C11, también hay _Thread_localdetalles: en.cppreference.com/w/c/language/storage_duration y stackoverflow.com/a/14289720/6557621
MCCCS
132

Si hubiera leído la lista de IAQ (preguntas infrecuentes), sabría que el automóvil es útil principalmente para definir o declarar un vehículo:

auto my_car;

Un vehículo que se estaciona constantemente al aire libre:

extern auto my_car;

Para aquellos que carecen de sentido del humor y quieren "solo los hechos, señora": la respuesta corta es que nunca hay ninguna razón para usar auto. La única vez que se le permite usar autoes con una variable que ya tiene autouna clase de almacenamiento, por lo que solo está especificando algo que sucedería de todos modos. Si intenta utilizar autoen cualquier variable que no tenga la autoclase de almacenamiento, el compilador rechazará su código. Supongo que si quiere ponerse técnico, su implementación no tiene que ser un compilador (pero lo es) y teóricamente puede continuar compilando el código después de emitir un diagnóstico (pero no lo será).

Pequeño anexo de kaz :

También hay:

static auto my_car;

lo que requiere un diagnóstico según ISO C. Esto es correcto, porque declara que el coche está averiado. El diagnóstico es gratuito, pero apagar la luz del tablero le costará ochenta dólares. (Veinte o menos, si compra su propio dongle USB para diagnóstico a bordo en eBay).

Lo anterior extern auto my_cartambién requiere un diagnóstico, y por esa razón nunca se ejecuta a través del compilador, excepto por el personal de la ciudad encargado de hacer cumplir la ley de estacionamiento.

Si ve mucho extern static auto ...en cualquier base de código, está en un mal vecindario; busque un trabajo mejor inmediatamente, antes de que todo el lugar se convierta en Rust.

Jerry Coffin
fuente
@self .: La ISO no parece conocer una "ISO 2011". ¿Qué cree que podría estandarizar?
Jerry Coffin
6
Menos mal que no tenía café, cola, cerveza negra o algún otro líquido de color oscuro en la boca. Me deberías una pantalla de computadora, @JerryCoffin, si ese fuera el caso. ¡LA MEJOR RESPUESTA!
David Hammen
2
@Dan: Honestamente, te tomó "bastante tiempo" leer 5 líneas de texto y llegar a la parte donde dice: "la respuesta corta es que nunca hay ninguna razón para usar auto en absoluto". ¿Seriamente? Dado el comentario que precede al suyo, parece que al menos algunas personas lo encuentran una contribución positiva.
Jerry Coffin
@JerryCoffin Ya lo expliqué, lea mi comentario nuevamente. La retrospectiva es 20/20.
Dan Bechard
2
Recientemente pasé una grave conflagración (cerré dos carriles) que sugiere la necesidad dechar auto my_car;
marcado
46

La autopalabra clave es inútil en el lenguaje C. Está ahí porque antes del lenguaje C existía un lenguaje B en el que esa palabra clave era necesaria para declarar variables locales. (B se convirtió en NB, que se convirtió en C).

Aquí está el manual de referencia para B .

Como puede ver, el manual está plagado de ejemplos en los que autose utiliza. Esto es así porque no existe una intpalabra clave. Se necesita algún tipo de palabra clave para decir "esto es una declaración de una variable", y esa palabra clave también indica si es local o externa ( autoversus extrn). Si no usa uno u otro, tiene un error de sintaxis. Es decir, x, y;no es una declaración en sí misma, sino que lo auto x, y;es.

Dado que las bases de código escritas en B tenían que ser trasladadas a NB y a C a medida que se desarrollaba el lenguaje, las versiones más nuevas del lenguaje llevaban algo de equipaje para mejorar la compatibilidad con versiones anteriores que se traducía en menos trabajo. En el caso de auto, los programadores no tuvieron que buscar cada aparición autoy eliminarlo.

Es obvio a partir del manual que el ahora obsoleto "implícito int" cruft en C (poder escribir main() { ... }sin ninguno intal frente) también proviene de B. Esa es otra característica de compatibilidad con versiones anteriores para admitir el código B. Las funciones no tienen un tipo de retorno especificado en B porque no hay tipos. Todo es una palabra, como en muchos lenguajes ensambladores.

Observe cómo una función puede simplemente declararse extrn putchary luego lo único que la convierte en una función que usa el identificador : se usa en una expresión de llamada de función como putchar(x), y eso es lo que le dice al compilador que trate esa palabra sin tipo como un puntero de función.

Kaz
fuente
24

En C autoes una palabra clave que indica que una variable es local a un bloque. Dado que ese es el valor predeterminado para las variables de ámbito de bloque, es innecesario y se usa muy raramente (no creo que lo haya visto usar fuera de los ejemplos en los textos que discuten la palabra clave). Me interesaría si alguien pudiera señalar un caso en el que autose requiera el uso de para obtener un análisis o comportamiento correcto.

Sin embargo, en el estándar C ++ 11, la autopalabra clave ha sido 'secuestrada' para admitir la inferencia de tipos, donde el tipo de una variable se puede tomar del tipo de su inicializador:

auto someVariable = 1.5;   // someVariable will have type double

La inferencia de tipos se está agregando principalmente para admitir la declaración de variables en plantillas o la devolución de funciones de plantilla donde los tipos basados ​​en un parámetro de plantilla (o deducidos por el compilador cuando se crea una instancia de una plantilla) a menudo pueden ser bastante dolorosos de declarar manualmente.

Michael Burr
fuente
1
"La variable es local a un bloque" - eso no es del todo cierto. Todas las variables declaradas en un bloque son locales a ese bloque (con respecto al alcance). Pueden estar vinculados a otras variables del programa, pero la declaración solo es visible en ese bloque. autose trata de una clase de almacenamiento que no tiene nada que ver con la visibilidad.
fuz
12

Con el antiguo compilador Aztec C, era posible convertir todas las variables automáticas en variables estáticas (para aumentar la velocidad de direccionamiento) mediante un conmutador de línea de comandos.

Pero las variables declaradas explícitamente con autose dejaron como están en ese caso. (¡Imprescindible para funciones recursivas que de otro modo no funcionarían correctamente!)

Raphnet
fuente
7

La autopalabra clave es similar a la inclusión de punto y coma en Python, era requerida por un lenguaje anterior ( B) pero los desarrolladores se dieron cuenta de que era redundante porque la mayoría de las cosas lo eran auto.

Sospecho que se dejó para ayudar con la transición de B a C. En resumen, un uso es para la compatibilidad con el lenguaje B.

Por ejemplo en B y 80 C:

/* The following function will print a non-negative number, n, to
   the base b, where 2<=b<=10.  This routine uses the fact that
   in the ASCII character set, the digits 0 to 9 have sequential
   code values.  */

printn(n, b) {
        extrn putchar;
        auto a;

        if (a = n / b)        /* assignment, not test for equality */
                printn(a, b); /* recursive */
        putchar(n % b + '0');
}
Mikhail
fuente
1

La palabra clave auto es un ejemplo de clase de almacenamiento (algún tipo de técnica que decide la vida útil de la variable y el lugar de almacenamiento). Tiene un comportamiento por el cual la variable creada por la Ayuda de esa palabra clave tiene una vida útil (vida útil) que reside solo entre las llaves

{
    auto int x=8;        
    printf("%d",x);  // here x is 8

    { 
        auto int x=3;
        printf("%d",x);  // here x is 3
    }              

    printf("%d",x);  // here x is 8
}          
Atul Sharma
fuente
0

autosolo se puede utilizar para variables de ámbito de bloque. extern auto intes una tontería porque el compilador no puede determinar si esto usa una definición externa o si anular la extern con una definición automática (también auto y extern son duraciones de almacenamiento completamente diferentes, como static auto int, lo cual también es una tontería obviamente). Siempre puede optar por interpretarlo de una manera, pero en su lugar opta por tratarlo como un error.

Hay una característica que autoproporciona y que habilita la regla 'todo es un int' dentro de una función. A diferencia de fuera de una función, donde a=3se interpreta como una definición int a =3porque las asignaciones no existen en el alcance del archivo, a=3es un error dentro de una función porque aparentemente el compilador siempre lo interpreta como una asignación a una variable externa en lugar de una definición (incluso si hay hay extern int adeclaraciones adelantadas en la función o en el ámbito de archivo), pero un especificador como static, const, volatileo autoque implica que se trata de una definición y el compilador lo toma como una definición, excepto autono tiene los efectos secundarios de los otros especificadores. auto a=3es, por tanto, implícitamente auto int a = 3. Cierto es que,signed a = 3tiene el mismo efecto y unsigned a = 3siempre es un int sin firmar.

También tenga en cuenta que ' autono tiene ningún efecto sobre si un objeto se asignará a un registro (a menos que algún compilador en particular le preste atención, pero eso parece poco probable)'

Lewis Kelsey
fuente
-1

Estoy seguro de que está familiarizado con los especificadores de clases de almacenamiento en C, que son "extern", "static", "register" y "auto". La definición de "auto" se da prácticamente en otras respuestas, pero aquí hay un posible uso de la palabra clave "auto" que no estoy seguro, pero creo que depende del compilador. Verá, con respecto a los especificadores de clases de almacenamiento, hay una regla. No podemos utilizar varios especificadores de clases de almacenamiento para una variable. Es por eso que las variables globales estáticas no se pueden eliminar. Por lo tanto, solo los conoce su archivo. Cuando vaya a la configuración de su compilador, puede habilitar el indicador de optimización para la velocidad. una de las formas en que el compilador optimiza es, busca variables sin especificadores de clase de almacenamiento y luego realiza una evaluación basada en la disponibilidad de la memoria caché y algunos otros factores para ver si debe tratar esa variable usando un especificador de registro o no. Ahora, ¿qué pasa si queremos optimizar nuestro código para la velocidad sabiendo que una variable específica en nuestro programa no es muy importante y no queremos que el compilador ni siquiera la considere como un registro? Sin embargo, al poner auto, el compilador no podrá agregar un especificador de registro a una variable ya que escribe "register auto int a;" O "registro automático int a;" plantea el error de utilizar varios especificadores de clase de almacenamiento. Para resumir, pensé que auto puede prohibir que el compilador trate una variable como registro a través de la optimización. ¿Qué pasa si queremos optimizar nuestro código para la velocidad sabiendo que una variable específica en nuestro programa no es muy importante y no queremos que el compilador ni siquiera la considere como registro? Sin embargo, al poner auto, el compilador no podrá agregar un especificador de registro a una variable ya que escribe "register auto int a;" O "registro automático int a;" plantea el error de utilizar varios especificadores de clase de almacenamiento. Para resumir, pensé que auto puede prohibir que el compilador trate una variable como registro a través de la optimización. ¿Qué pasa si queremos optimizar nuestro código para la velocidad sabiendo que una variable específica en nuestro programa no es muy importante y no queremos que el compilador ni siquiera la considere como registro? Sin embargo, al poner auto, el compilador no podrá agregar un especificador de registro a una variable ya que escribe "register auto int a;" O "registro automático int a;" plantea el error de utilizar varios especificadores de clase de almacenamiento. Para resumir, pensé que auto puede prohibir que el compilador trate una variable como registro a través de la optimización. plantea el error de utilizar varios especificadores de clase de almacenamiento. Para resumir, pensé que auto puede prohibir que el compilador trate una variable como registro a través de la optimización. plantea el error de utilizar varios especificadores de clase de almacenamiento. Para resumir, pensé que auto puede prohibir que el compilador trate una variable como registro a través de la optimización.

Esta teoría no funcionó para el compilador GCC, sin embargo, no he probado otros compiladores.

Alireza Mirghasemi
fuente