¿Por qué auto a=1; compila en C?


El código:

int main(void)
{
    auto a=1;
    return 0;
}

Se compila sin errores por el compilador de MS Visual Studio 2012, cuando el archivo tiene el.c extensión. Siempre he pensado que cuando se utiliza el .extensión de c, la compilación debe estar de acuerdo con la sintaxis de C, y no C++. Además, por lo que sé auto sin tipo está permitido solo en C++ desde C++11, donde significa que el tipo se deduce del inicializador.

Eso significa que mi compilador no se adhiere a C, o es el código ¿realmente correcto en lenguaje C?

 122
Author: MD XF, 2014-05-01

7 answers

auto es una antigua palabra clave C que significa "ámbito local". auto a es lo mismo que auto int a, y debido a que local scope es el valor predeterminado para una variable declarada dentro de una función, también es lo mismo que int a en este ejemplo.

Esta palabra clave es en realidad un residuo del predecesor de C B, donde no había tipos base: todo era int, puntero a int, matriz de int.( * ) Las declaraciones serían auto o extrn [sic]. C heredó el "todo es int" como regla por defecto, por lo que podría declarar enteros con

auto a;
extern b;
static c;

ISO C se deshizo de esto, pero muchos compiladores todavía lo aceptan por compatibilidad con versiones anteriores. Si parece desconocido, entonces usted debe darse cuenta de que una regla relacionada está en funcionamiento en

unsigned d;  // actually unsigned int

Que todavía es común en el código moderno.

C++11 reutilizó la palabra clave, que pocos programadores de C++ usaban con el significado original, para su inferencia de tipo. Esto es principalmente seguro porque la regla "todo es int" de C ya se había eliminado en C++98; lo único que se rompe es auto T a, que nadie estaba usando de todos modos. (En algún lugar de sus documentos sobre la historia de la lengua, Stroustrup comenta sobre esto, pero no puedo encontrar la referencia exacta en este momento.)

(*) El manejo de cadenas en B era interesante: usarías matrices de int y empaquetarías varios caracteres en cada miembro. B era en realidad BCPL con sintaxis diferente.

 235
Author: Fred Foo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-06 18:50:39

Esto es tanto una respuesta como un comentario extendido a No, esto no es legal C desde 1999. Ningún compilador de C moderno decente permite esto.

Sí, auto a=1; es ilegal en C1999 (y también en C2011). El hecho de que ahora sea ilegal no significa que un compilador de C moderno deba rechazar el código que contiene tales construcciones. Yo diría exactamente lo contrario, que un compilador de C moderno decente aún debe permitir esto.

Tanto clang como gcc hacen precisamente eso al compilar el código de ejemplo en la pregunta contra las versiones de 1999 o 2011 de la norma. Ambos compiladores emiten un diagnóstico y luego continúan como si la declaración objetable hubiera sido auto int a=1;.

En mi opinión, esto es lo que un compilador decente debería hacer. Al emitir un diagnóstico, clang y gcc cumplen por completo con el estándar. El estándar no dice que un compilador debe rechazar el código ilegal. El estándar simplemente dice que una implementación conforme debe producir al menos un mensaje de diagnóstico si un translation unit contiene una violación de cualquier regla de sintaxis o restricción (5.1.1.3).

Dado el código que contiene construcciones ilegales, cualquier compilador decente intentará darle sentido al código ilegal para que el compilador pueda encontrar el siguiente error en el código. Un compilador que se detiene en el primer error no es un buen compilador. Hay una manera de darle sentido a auto a=1, que es aplicar la regla "int implícito". Esta regla obliga al compilador a interpretar auto a=1 como si fuera auto int a=1 cuando el el compilador se utiliza en modo C90 o K&R.

La mayoría de los compiladores normalmente rechazan código (reject: refuse to generate an object file or an executable) que contiene sintaxis ilegal. Este es un caso en el que los autores del compilador decidieron que no compilar no es la mejor opción. Lo mejor que puede hacer es emitir un diagnóstico, arreglar el código y continuar. Hay demasiado código heredado que está salpicado de construcciones como register a=1;. El compilador debería ser capaz de compilar ese código en C99 o C11 modo (con un diagnóstico, por supuesto).

 35
Author: David Hammen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-01 15:24:15

auto tiene un significado en C y C++ antes de la Norma de 2011. Significa que una variable tiene vida útil automática, es decir, vida útil determinada por el ámbito. Esto se opone a, por ejemplo, static lifetime, donde una variable dura "para siempre", independientemente del alcance. auto es la duración predeterminada, y casi nunca se especifica explícitamente. Es por eso que era seguro cambiar el significado en C++.

Ahora en C, antes del estándar 99, si no especifica el tipo de variable, por defecto es int.

Así que con auto a = 1; está declarando (y definiendo) una variable int, con vida determinada por el ámbito.

("lifetime" se llama más apropiadamente "storage duration", pero creo que es quizás menos claro).

 29
Author: BoBTFish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-07 15:21:45

En C, y dialectos históricos de C++, auto es una palabra clave que significa que a tiene almacenamiento automático. Dado que solo se puede aplicar a variables locales, que son automáticas por defecto, nadie lo usa; por lo que C++ ahora ha reutilizado la palabra clave.

Históricamente, C ha permitido declaraciones de variables sin especificador de tipo; el tipo predeterminado es int. Así que esta declaración es equivalente a

int a=1;

Creo que esto está en desuso (y posiblemente prohibido) en la C moderna; pero algunos los compiladores populares usan por defecto C90 (lo que, creo, lo permite), y, molestamente, solo habilita las advertencias si las solicita específicamente. Compilar con GCC y especificar C99 con -std=c99, o habilitar la advertencia con -Wall o -Wimplicit-int, da una advertencia:

warning: type defaults to ‘int’ in declaration of ‘a’
 8
Author: Mike Seymour,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-01 10:58:27

En C, auto significa lo mismo que register hace en C++11: significa que una variable tiene una duración de almacenamiento automática.

Y en C anterior a C99 (y el compilador de Microsoft no soporta ni C99 ni C11, aunque puede soportar partes de él), el tipo se puede omitir en muchos casos, donde por defecto será int.

No toma el tipo del inicializador en absoluto. Acabas de elegir un inicializador que sea compatible.

 5
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-01 10:54:22

El tipo de compilación de Visual studio está disponible en right click on file -> Properties -> C/C++ -> Advanced -> Compile As. Para asegurarse de que está compilado como la opción C force /TC.Entonces en este caso es lo que larsmans dijo (antigua palabra clave C auto). Puede ser compilado como C++ sin que lo sepas.

 3
Author: UmNyobe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-01 10:57:14

Una clase de almacenamiento define el alcance (visibilidad) y el tiempo de vida de las variables y/o funciones dentro de un Programa C.

Existen las siguientes clases de almacenamiento que se pueden usar en un programa C

auto
register
static
extern

auto es la clase de almacenamiento predeterminada para todas las variables locales.

{
        int Count;
        auto int Month;
}

El ejemplo anterior define dos variables con la misma clase de almacenamiento. auto solo se puede usar dentro de funciones, es decir, variables locales.

int es el tipo predeterminado para auto en la parte inferior código:

auto Month;
/* Equals to */
int Month;

El siguiente código también es legal:

/* Default-int */
main()
{
    reurn 0;
}
 3
Author: Amir Saniyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-07 16:11:24