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 la extensión .c. Siempre he pensado que cuando usas la extensión .c, la compilación debe estar de acuerdo con la sintaxis de C y no con C ++. Además, por lo que sé, auto sin tipo solo está permitido 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 el código es realmente correcto en lenguaje C?
int
se ha eliminado del estándar C en 1999.Respuestas:
auto
es una antigua palabra clave C que significa "ámbito local".auto a
es lo mismo queauto int a
, y dado que el ámbito local es el valor predeterminado para una variable declarada dentro de una función, también es lo mismo queint a
en este ejemplo.Esta palabra clave es en realidad un remanente del predecesor B de C, donde no había tipos base: todo era
int
, puntero aint
, matriz deint
. (*) Las declaraciones seríanauto
oextrn
[sic]. C heredó el "todo esint
" como regla predeterminada, por lo que podría declarar enteros conISO C se deshizo de esto, pero muchos compiladores todavía lo aceptan por compatibilidad con versiones anteriores. Si no le resulta familiar, entonces debe darse cuenta de que una regla relacionada está funcionando en
que todavía es común en el código moderno.
C ++ 11 reutilizó la palabra clave, que pocos o ningún programador de C ++ estaba usando con el significado original, para su inferencia de tipos. Esto es principalmente seguro porque la
int
regla "todo es " de C ya se había eliminado en C ++ 98; lo único que se rompe esauto T a
que nadie estaba usando de todos modos. (En algún lugar de sus documentos sobre la historia del idioma , Stroustrup comenta sobre esto, pero no puedo encontrar la referencia exacta en este momento).(*) El manejo de cadenas en B fue interesante: usaría matrices
int
y empaquetaría varios caracteres en cada miembro. B era en realidad BCPL con diferente sintaxis.fuente
-Werror
.Esto es tanto una respuesta como un comentario extendido a No, no es C legal desde 1999. Ningún compilador decente de C moderno lo permite.
Sí,
auto a=1;
es ilegal en C1999 (y también en C2011). El hecho de que esto 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 C decente y moderno aún debe permitir esto.Tanto clang como gcc hacen exactamente eso cuando compilan el código de muestra en la pregunta contra las versiones de 1999 o 2011 del estándar. 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 debe hacer un compilador decente. Al emitir un diagnóstico, clang y gcc cumplen totalmente 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 una unidad de traducción contiene una violación de cualquier regla o restricción de sintaxis (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 compilador muy bueno. Hay una manera de darle sentido
auto a=1
, que es aplicar la regla "implícita int". Esta regla obliga al compilador a interpretarauto a=1
como si fueraauto int a=1
cuando el compilador se usa en modo C90 o K&R.La mayoría de los compiladores generalmente rechazan el código (rechazar: rechazar generar un archivo de objeto o un ejecutable) que contenga una 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, corregir el código y continuar. Hay demasiado código heredado que está salpicado de construcciones como
register a=1;
. El compilador debería poder compilar ese código en modo C99 o C11 (con un diagnóstico, por supuesto).fuente
-ffs-please-stop-allowing-constructs-from-some-previous-millennium
opción de compilador, o más sucintamente, una-fstrict-compliance
opción. Gruñendo en el compilador: "Cuando usé -std = c11 no esperaba que compilara el antiguo K&R kruft. De hecho, ¡quería que no compilara!"-std=c99
ser más estricto sería un paso en la dirección correcta :)gcc -g -O3 -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror
(que es lo que uso habitualmente, incluso en el código de las preguntas sobre SO), entonces se acerca bastante a lo que desea. Me gustaría que GCC tenga el valor predeterminado al menos-std=c99
y preferiblemente-std=c11
(o,-std=gnu11
lo más probable es que lo hagan), pero hasta entonces, ... Puede modificar esas opciones;-pedantic
,-Wshadow
,-Wold-style-declaration
Y algunos otros pueden ser útiles, pero este es un buen punto de partida un conjunto de opciones.-pedantic-errors
auto
tiene un significado enC
yC++
antes de la Norma 2011. Significa que una variable tiene una vida útil automática, es decir, una vida útil determinada por el alcance . Esto se opone, por ejemplo, a lastatic
vida útil, donde una variable dura "para siempre", independientemente del alcance.auto
es la duración predeterminada y casi nunca se explica explícitamente. Es por eso que era seguro cambiar el significado enC++
.Ahora
C
, antes del Estándar 99, si no especifica el tipo de una variable, su valor predeterminado esint
.Entonces, con
auto a = 1;
usted está declarando (y definiendo) unaint
variable, cuya duración está determinada por el alcance.("vida útil" se denomina más correctamente "duración de almacenamiento", pero creo que quizás sea menos claro).
fuente
main
función".auto
ystatic
son las dos únicas posibilidades. Estaba tratando de escribir mi respuesta de una manera dirigida al autor de la pregunta, que parece ser bastante nuevo paraC++
(yC
), así que pasé por alto un poco los detalles. Tal vez esa fue una mala idea; necesitan ser cubiertos tarde o temprano.int
material implícito se elimina de C desde 1999.En C, y dialectos históricos de C ++,
auto
es una palabra clave que significa quea
tiene almacenamiento automático. Como solo se puede aplicar a las variables locales, que son automáticas por defecto, nadie lo usa; Es por eso que C ++ ahora ha reutilizado la palabra clave.Históricamente, C ha permitido declaraciones variables sin especificador de tipo; el tipo predeterminado es
int
. Entonces esta declaración es equivalente aCreo que esto está en desuso (y posiblemente prohibido) en la C moderna; pero algunos compiladores populares tienen el valor predeterminado C90 (que, creo, lo permite) y, molestamente, solo habilitan 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:fuente
En C,
auto
significa lo mismo queregister
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 admite C99 ni C11, aunque puede admitir partes de él), el tipo puede omitirse en muchos casos, donde el valor predeterminado será
int
.No toma el tipo del inicializador en absoluto. Acabas de elegir un inicializador que sea compatible.
fuente
auto
yregister
tenía exactamente el mismo significado (anteriormente comenté que había restricciones para tomarregister
la dirección de una variable calificada, pero eso era incorrecto para C ++).register
, aunque está en desuso, conserva su antiguo significado por ahora.auto
en C significa lo mismo queregister
en C ++, lo que significa (ambos significan la duración del almacenamiento automático y nada más).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 se compila como/TC
opción de fuerza C. Entonces, en este caso, es lo que dijo larsmans (antiguaauto
palabra clave C ). Podría compilarse como C ++ sin que usted lo sepa.fuente
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
es la clase de almacenamiento predeterminada para todas las variables locales.El ejemplo anterior define dos variables con la misma clase de almacenamiento. auto solo puede usarse dentro de funciones, es decir, variables locales.
int
es el tipo predeterminado para elauto
siguiente código:El siguiente código también es legal:
fuente