Existe alguma razão para usar a palavra-chave 'auto' em C ++ 03?

85

Observe que esta questão foi postada originalmente em 2009, antes que C ++ 11 fosse ratificado e antes que o significado da autopalavra - chave fosse drasticamente alterado. As respostas fornecidas referem-se apenas ao significado de C ++ 03 auto- sendo uma classe de armazenamento especificada - e não ao significado de C ++ 11 auto- de dedução automática de tipo. Se você está procurando conselhos sobre quando usar o C ++ 11 auto, esta questão não é relevante para aquela questão.

Por muito tempo, pensei que não havia razão para usar a staticpalavra - chave em C, porque as variáveis ​​declaradas fora do escopo do bloco eram implicitamente globais. Então descobri que declarar uma variável como staticdentro do escopo do bloco daria a ela uma duração permanente, e declarar fora do escopo do bloco (no escopo do programa) daria a ela o escopo do arquivo (só pode ser acessado naquela unidade de compilação).

Portanto, isso me deixa com apenas uma palavra-chave que eu (talvez) ainda não entendo completamente: a autopalavra-chave. Existe algum outro significado para isso além de 'variável local?' Alguma coisa que ele faz que não seja implicitamente feito para você, onde quer que você queira usá-lo? Como uma autovariável se comporta no escopo do programa? O que dizer de uma static autovariável no escopo do arquivo? Esta palavra-chave tem outra finalidade além de apenas ser completa ?

Carson Myers
fonte

Respostas:

74

autoé um especificador de classe de armazenamento, static, registere externtambém. Você só pode usar um desses quatro em uma declaração.

Variáveis ​​locais (sem static) possuem duração de armazenamento automático, o que significa que elas vivem desde o início de sua definição até o final de seu bloco. Colocar auto na frente deles é redundante, pois esse é o padrão de qualquer maneira.

Não sei de nenhum motivo para usá-lo em C ++. Em versões C antigas que têm a regra int implícita, você pode usá-la para declarar uma variável, como em:

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

Para tornar a sintaxe válida ou desambiguar de uma expressão de atribuição, caso iesteja no escopo. Mas isso não funciona em C ++ de qualquer maneira (você deve especificar um tipo). Engraçado, o C ++ Standard escreve:

Um objeto declarado sem um especificador de classe de armazenamento no escopo do bloco ou declarado como um parâmetro de função tem duração de armazenamento automática por padrão. [Nota: portanto, o especificador automático é quase sempre redundante e não é usado com frequência; um uso de auto é distinguir explicitamente uma instrução de declaração de uma instrução de expressão (6.8). - nota final]

que se refere ao seguinte cenário, que poderia ser uma conversão de apara intou a declaração de uma variável ado tipo inttendo parênteses redundantes ao redor a. É sempre considerado uma declaração, então autonão acrescentaria nada de útil aqui, mas sim para o humano. Mas, novamente, o humano estaria melhor removendo os parênteses redundantes ao redor a, eu diria:

int(a);

Com o novo significado de autochegar com C ++ 0x, eu desencorajaria usá-lo com o significado de C ++ 03 no código.

Johannes Schaub - litb
fonte
4
Compiladores C ++ costumavam ter int implícitos para valores de retorno de funções, nos dias anteriores ao ARM ... Antes do IMPÉRIO ...
Daniel Earwicker
1
Acabei de reconhecê-lo como a forma de meu compilador dizer que esqueci de declarar uma função. Isso me diria que meu uso de uma função era diferente da forma como foi declarada por causa do int implícito.
Carson Myers
29
A melhor parte é que os programadores costumavam escrever "auto" (quatro letras) para evitar escrever "int" (três letras).
Max Lybbert
30
@Max - hey, muitas pessoas dizem "double-u-double-u-double-u" como uma abreviatura de "World Wide Web".
Daniel Earwicker
3
@smichak não, "volátil" é um qualificador de tipo. Em vez de determinar onde armazenar um valor, ele muda o comportamento de uma gravação e leitura de um objeto do tipo qualificado volátil. Pode haver variáveis ​​de pilha qualificadas voláteis (classe de armazenamento automático), bem como variáveis ​​de duração de armazenamento estático qualificado volátil (classe de armazenamento 'estático' local, variáveis ​​não locais). Além disso, não sei se "registrar volátil" é uma combinação válida :)
Johannes Schaub - litb
86

Em C ++ 11, autotem um novo significado: permite deduzir automaticamente o tipo de uma variável.

Por que isso é sempre útil? Vamos considerar um exemplo básico:

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

O autolá cria um iterador do tipo std::list<int>::iterator.

Isso pode tornar alguns códigos seriamente complexos muito mais fáceis de ler.

Outro exemplo:

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

Lá, o autodeduziu o tipo necessário para armazenar uma expressão lambda em uma variável. A Wikipedia tem uma boa cobertura sobre o assunto.

std''OrgnlDave
fonte
4
Ainda não tenho certeza se esse é um ótimo uso do automóvel. O código deve ser fácil de ler, não fácil de escrever!
DanDan
38
Não sei sobre você, mas acho isso muito mais fácil de ler do que spam do tipo iterador.
Overv
17
E se por algum ressonador você decidir mudar a classe da lista <int> para alguma outra classe, você não precisa procurar por cada declaração do iterador e alterá-la.
roslav
2
@KarateSnowMachine: Se você quiser a const, deverá usar "const auto" em vez de "auto".
darth happyface
4
@darth const auto it = a.begin();daria a você um const iterator, não um const_iterator. Você ainda deve alterar o elemento, mas ++itnão conseguirá compilar. Para obter um const_iterator, você usariaauto it = a.cbegin();
fredoverflow
35

A palavra-chave auto não tem propósito no momento. Você está exatamente certo ao dizer que apenas reafirma a classe de armazenamento padrão de uma variável local, sendo a alternativa realmente útil static.

Ele tem um novo significado em C ++ 0x. Isso dá a você uma ideia de como era inútil!

Daniel Earwicker
fonte
1
oh cara, isso é sempre inútil. Eu gosto do novo significado, no entanto. Isso torna alguns códigos muito menos prolixos e redundantes.
Carson Myers
Sim, ter usado o equivalente em C # provavelmente fará uma grande diferença. Mais ainda em C ++ se você estiver usando modelos de expressão em que os tipos são tão complexos que nunca foram criados para serem escritos à mão.
Daniel Earwicker
7

O GCC tem um uso especial autopara funções aninhadas - veja aqui .

Se você tiver uma função aninhada que deseja chamar antes de sua definição, será necessário declará-la com auto.

qrdl
fonte
esta é uma excelente implementação de auto, embora dependente do compilador. Obrigado pela pesquisa :)
Carson Myers
3

"auto" supostamente diz ao compilador para decidir por si mesmo onde colocar a variável (memória ou registro). Seu análogo é o "registro", que supostamente diz ao compilador para tentar mantê-lo em um registro. Compiladores modernos ignoram ambos, então você também deve.

TED
fonte
1
Não exatamente - se você declarar com "registrar", os compiladores não permitem que você use o operador de endereço (& foo) na variável porque, bem, ele não existe em nenhum lugar na memória (e, portanto, não tem endereço).
Tim Čas
3

Eu uso esta palavra-chave para documentar explicitamente quando é crítico para a função, que a variável seja colocada na pilha, para processadores baseados em pilha. Esta função pode ser necessária ao modificar a pilha antes de retornar de uma função (ou interromper a rotina de serviço). Neste caso, declaro:

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

E então eu acesso fora da variável:

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

Portanto, a autopalavra - chave ajuda a documentar a intenção.

Lucas
fonte
1
Presumo que seja apenas uma sinalização de intenção, uma vez que a palavra-chave não impõe realmente o posicionamento da pilha, mais do que simplesmente omitir.
sublinhado_d
2

De acordo com Stroustrup, em "The C Programming Language" (4ª Edição, cobrindo C 11), o uso de 'auto' tem as seguintes razões principais (seção 2.2.2) (palavras de Stroustrup são citadas):

1)

A definição está em um amplo escopo onde queremos tornar o tipo claramente visível para os leitores de nosso código.

Com 'auto' e seu inicializador necessário podemos saber o tipo da variável em um piscar de olhos!

2)

Queremos ser explícitos sobre o intervalo ou precisão da variável (por exemplo, double ao invés de float)

Na minha opinião um caso que se encaixa aqui é algo assim:

   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 redundância e escrevemos nomes de tipo longos.

Imagine algum nome de tipo longo de um iterador com modelo:

(código da seção 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
fonte
Esses pontos se aplicam ao C ++ 11, mas não ao C ++ 03. A inferência de tipo era nova no C ++ 11.
Jirka Hanika
1

No compilador antigo, auto era uma forma de declarar uma variável local. Você não pode declarar variáveis ​​locais em compiladores antigos como Turbo C sem a palavra-chave auto ou algo parecido.

chaz
fonte
Receio que você esteja enganado. Nunca houve tal restrição, mesmo na versão original do Turbo C chamada Wizard-C em 1986, ou em qualquer de seus contemporâneos: MSC, Lattice C, Concurrent-C, High-C, Watcom-C ...
chqrlie
1

O novo significado da palavra-chave auto em C ++ 0x é descrito muito bem por Stephan T. Lavavej da Microsoft em uma palestra em vídeo que pode ser visualizada / baixada gratuitamente no STL, encontrada no site Channel 9 do MSDN aqui .

A palestra vale a pena assistir na íntegra, mas a parte sobre a palavra-chave auto está por volta da marca de 29 minutos (aproximadamente).

Sabuncu
fonte
1

Existe algum outro significado para 'auto' diferente de 'variável local?'

Não em C ++ 03.

Alguma coisa que ele faz que não seja implicitamente feito para você, onde quer que você queira usá-lo?

Absolutamente nada, em C ++ 03.

Como uma variável automática se comporta no escopo do programa? O que dizer de uma variável automática estática no escopo do arquivo?

Palavra-chave não permitida fora de um corpo de função / método.

Esta palavra-chave tem algum propósito [em C ++ 03] além de apenas existir para ser completo?

Surpreendentemente, sim. Os critérios de design do C ++ incluíam um alto grau de compatibilidade com versões anteriores de C. C tinha essa palavra-chave e não havia razão real para bani-la ou redefinir seu significado em C ++. Portanto, o objetivo era uma incompatibilidade a menos com C.

Essa palavra-chave tem algum propósito em C além de apenas existir para ser completo?

Aprendi um apenas recentemente: facilidade de portar programas antigos de B. C evoluiu de uma linguagem chamada B, cuja sintaxe era bastante semelhante à de C. No entanto, B não tinha nenhum tipo. A única maneira de declarar uma variável em B era especificar seu tipo de armazenamento ( autoou extern). Como isso:

auto i;

Esta sintaxe ainda funciona em C e é equivalente a

int i;

porque em C, o padrão da classe de armazenamento é auto, e o padrão do tipo é int. Acho que cada programa originado em B e portado para C estava literalmente cheio de autovariáveis ​​naquela época.

C ++ 03 não permite mais o int implícito do estilo C, mas preservou a autopalavra - chave não mais exatamente útil porque, ao contrário do int implícito, não era conhecido por causar nenhum problema na sintaxe de C.

Jirka Hanika
fonte