O código:
int main(void)
{
auto a=1;
return 0;
}
é compilado sem erros pelo compilador do MS Visual Studio 2012, quando o arquivo tem a extensão .c. Eu sempre pensei que, quando você usa a extensão .c, a compilação deve estar de acordo com a sintaxe C e não com o C ++. Além disso, até onde eu sei, auto sem um tipo é permitido apenas em C ++ desde C ++ 11, onde significa que o tipo é deduzido do inicializador.
Isso significa que meu compilador não está aderindo a C ou o código está realmente correto na linguagem C?
int
foi removido do padrão C em 1999.Respostas:
auto
é uma palavra-chave C antiga que significa "escopo local".auto a
é o mesmo queauto int a
, e como o escopo local é o padrão para uma variável declarada dentro de uma função, também é o mesmo queint a
neste exemplo.Essa palavra-chave é, na verdade, uma sobra do predecessor de C, B, onde não havia tipos de base: tudo era
int
, ponteiro paraint
, matriz deint
. (*) As declarações seriamauto
ouextrn
[sic]. C herdou o "tudo éint
" como regra padrão, então você pode declarar números inteiros comO ISO C se livrou disso, mas muitos compiladores ainda o aceitam como compatibilidade com versões anteriores. Se não lhe parecer familiar, você deve perceber que uma regra relacionada está em funcionamento em
o que ainda é comum no código moderno.
O C ++ 11 reutilizou a palavra-chave, que poucos ou nenhum programador C ++ estava usando com o significado original, para sua inferência de tipo. Isso é mais seguro porque a
int
regra "tudo é " de C já havia sido descartada no C ++ 98; a única coisa que quebra éauto T a
que ninguém estava usando de qualquer maneira. (Em algum lugar em seus trabalhos sobre a história da linguagem , Stroustrup comenta isso, mas não consigo encontrar a referência exata no momento.)(*) O tratamento de strings em B foi interessante: você usaria matrizes
int
e empacotaria vários caracteres em cada membro. B era na verdade BCPL com sintaxe diferente.fonte
-Werror
.Esta é uma resposta e um comentário estendido a Não, isso não é C legal desde 1999. Nenhum compilador C decente moderno permite isso.
Sim,
auto a=1;
é ilegal em C1999 (e também em C2011). Só porque isso agora é ilegal, não significa que um compilador C moderno deva rejeitar o código que contém essas construções. Eu argumentaria exatamente o contrário, que um compilador C decente e moderno ainda deve permitir isso.Tanto o clang quanto o gcc fazem exatamente isso ao compilar o código de exemplo na pergunta com relação às versões de 1999 ou 2011 do padrão. Ambos os compiladores emitem um diagnóstico e, em seguida, continuam como se a declaração censurável tivesse sido
auto int a=1;
.Na minha opinião, é isso que um compilador decente deve fazer. Ao emitir um diagnóstico, o clang e o gcc são totalmente compatíveis com o padrão. O padrão não diz que um compilador deve rejeitar código ilegal. O padrão diz apenas que uma implementação em conformidade deve produzir pelo menos uma mensagem de diagnóstico se uma unidade de tradução contiver uma violação de qualquer regra ou restrição de sintaxe (5.1.1.3).
Dado o código que contém construções ilegais, qualquer compilador decente tentará entender o código ilegal para que o compilador possa encontrar o próximo erro no código. Um compilador que para no primeiro erro não é um compilador muito bom. Existe uma maneira de entender
auto a=1
, que é aplicar a regra "int implícita". Esta regra força o compilador a interpretarauto a=1
como se fosseauto int a=1
quando o compilador é usado no modo C90 ou K&R.A maioria dos compiladores geralmente rejeita o código (rejeitar: recusar-se a gerar um arquivo de objeto ou um executável) que contém sintaxe ilegal. Este é um caso em que os autores do compilador decidiram que deixar de compilar não é a melhor opção. A melhor coisa a fazer é emitir um diagnóstico, corrigir o código e continuar. Há muito código legado repleto de construções como
register a=1;
. O compilador deve poder compilar esse código no modo C99 ou C11 (com um diagnóstico, é claro).fonte
-ffs-please-stop-allowing-constructs-from-some-previous-millennium
opção de compilador, ou mais sucintamente, uma-fstrict-compliance
opção. Resmungando com o compilador: "Quando usei -std = c11, não esperava que o antigo K&R kruft fosse compilado. Na verdade, eu queria que ele não fosse compilado!"-std=c99
mais rigorosa seja seria um passo na direção certa :)gcc -g -O3 -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror
(que é o que eu uso rotineiramente, mesmo no código de perguntas sobre SO), você fica bastante próximo do que deseja. Eu gostaria que o GCC tivesse como padrão, pelo menos-std=c99
e de preferência-std=c11
(ou-std=gnu11
,; é mais provável que eles fizessem isso), mas até então, ... Você pode ajustar essas opções;-pedantic
,-Wshadow
,-Wold-style-declaration
E alguns outros pode ser útil, mas este é um bom ponto de partida um conjunto de opções.-pedantic-errors
auto
tem um significadoC
eC++
antes da Norma de 2011. Isso significa que uma variável tem vida útil automática, ou seja, vida útil determinada pelo escopo . Isso se opõe, por exemplo, aostatic
tempo de vida, em que uma variável dura "para sempre", independentemente do escopo.auto
é a vida útil padrão e quase nunca é explicitamente explicitada. É por isso que era seguro alterar o significado emC++
.Agora
C
, antes do 99 Standard, se você não especificar o tipo de uma variável, o padrão seráint
.Assim,
auto a = 1;
você está declarando (e definindo) umaint
variável, com a vida útil determinada pelo escopo.("tempo de vida" é mais apropriadamente chamado de "duração do armazenamento", mas acho que isso talvez seja menos claro).
fonte
main
função".auto
estatic
são as duas únicas possibilidades. Eu estava tentando escrever minha resposta de uma maneira direcionada ao solicitante, que parece bastante novo emC++
(eC
), então encaminhei um pouco os detalhes. Talvez tenha sido uma má ideia; eles precisam ser cobertos mais cedo ou mais tarde.int
material é removido a partir de C desde 1999.Em C, e dialetos históricos de C ++,
auto
é uma palavra-chave que significaa
armazenamento automático. Como ele só pode ser aplicado a variáveis locais, que são automáticas por padrão, ninguém as usa; é por isso que o C ++ agora reformulou a palavra-chave.Historicamente, C permitiu declarações de variáveis sem especificador de tipo; o tipo padrão é
int
. Portanto, esta declaração é equivalente aEu acho que isso foi preterido (e possivelmente proibido) no C moderno; mas alguns compiladores populares assumem o padrão C90 (o que, penso, o permite) e, irritantemente, apenas ativam avisos se você os solicitar especificamente. Compilar com o GCC e especificar C99 com
-std=c99
ou ativar o aviso com-Wall
ou-Wimplicit-int
dá um aviso:fonte
Em C,
auto
significa o mesmoregister
que em C ++ 11: significa que uma variável tem duração de armazenamento automática.E em C anterior ao C99 (e o compilador da Microsoft não suporta C99 ou C11, embora possa suportar partes dele), o tipo pode ser omitido em muitos casos, para o padrão
int
.Ele não aceita o tipo do inicializador. Por acaso, você escolheu um inicializador compatível.
fonte
auto
eregister
tinha exatamente o mesmo significado (eu comentei anteriormente que havia restrições em usarregister
o endereço de uma variável qualificada, mas isso estava incorreto para o C ++).register
, embora descontinuado, mantém seu antigo significado por enquanto.auto
em C significa o mesmo queregister
em C ++, o que significa (ambos significam duração automática do armazenamento e nada mais).O tipo de compilação do Visual studio está disponível em
right click on file -> Properties -> C/C++ -> Advanced -> Compile As
. Para garantir que ele seja compilado como opção de força C,/TC
então é o que Larsmans disse (antigaauto
palavra-chave C ). Pode ser compilado como C ++ sem você saber.fonte
Uma classe de armazenamento define o escopo (visibilidade) e o tempo de vida de variáveis e / ou funções dentro de um programa C.
Existem as seguintes classes de armazenamento que podem ser usadas em um programa C
auto
é a classe de armazenamento padrão para todas as variáveis locais.O exemplo acima define duas variáveis com a mesma classe de armazenamento. auto só pode ser usado dentro de funções, ou seja, variáveis locais.
int
é o tipo padrãoauto
no código abaixo:O código abaixo também é legal:
fonte