Estou usando o codeblocks-8.02mingw-setup.exe
Code::Blocks 8.02
#include <iostream>
void main(void)
{
cout << "Hello world!" << endl;
}
Ao compilar o fonte acima, pelo que sei 100% ANSI C++, recebi as
seguintes mensagens:
C++\hello.cpp 4 error: `main' must return `int'
C++\hello.cpp In function `int main(...)':
C++\hello.cpp 5 error: `cout' was not declared in this scope
C++\hello.cpp 5 error: `endl' was not declared in this scope
=== Build finished: 3 errors, 0 warnings ===
Detalhe se altero para:
#include <iostream.h>
int main(void)
{
cout << "Hello world!" << endl;
return 0;
}
Só é apresentada uma mensagem dizendo que o header iostream.h está
deprecated e recomenda a
utilização do header iostream ou usar -nodeprecated
Existe algo a fazer para que a primeira versão (ANSI C++) apresentada
compile e execute sem erros ou
warnings?
Um abração e desde já agradeço,
Sardano
Você pode colocar uma declaração:
using namespace std;
logo após o include ou usar dessa forma:
std::cout << "Hello world" << std::endl;
No padrão atual cout e endl (e outros) residem no namespace std.
#include <iostream>
int main()
{
std::cout << "Hello World!" << std::endl;
}
Veja que eh *int* main, nao void.
Se nao retornares nada no main ele assume return 0;
E veja as qualificacoes do namespace em cout e endl.
Voce pode usar using namespace std;
ou usar using std::cout; using std::endl;
Eu prefiro quase sempre qualificar, em alguns casos eu uso using
std::nomedoquequero;
Assim tenho controle do que estou trazendo pro meu namespace.
2008/6/9 <ari...@sardano.net>:
--
Felipe Magno de Almeida
--
Rafael Giusti
Laboratório de Inteligência Computacional - LABIC
Universidade de São Paulo - USP
Virgilio Fornazin escreveu:
> using namespace std;
>
> é necessario, pois cout , cin, estão geralmente nesse namespace. e
> geralmente declara-se main como
>
> int main(int argc, char ** argv);
>
> alguns compiladores aceitavam void main(), não sei se isso ainda é valido.
>
>
> 2008/6/9 <ari...@sardano.net <mailto:ari...@sardano.net>>:
Não, as unicas versões são:
Para C:
int main(void);
int main(int argc, char* argv[]);
E C++ declara (void) obsoleto para qualquer função, logo tendo
como preferencia
int main();
Mas int main(void) também é valido e significa a mesma coisa em C++.
ISO/ANSI C++
===========
Eu verifiquei no livro "The C++ Programming Language Third Editon -
Bjarne Stroustrup" que define o Standard C++ (ISO C++ e também chamado
ANSI C++), ele não diz que void é deprecated e inclusive incentiva e
recomenda o uso como boas práticas.
int main()
int main(int argc, char *argv[])
Apesar de não ocorrer no texto do livro outras construções também são
válidas em C++:
main()
main(int argc, char *argv[])
main(int argc, char **argv)
int main(void)
main(void)
int main(int argc, char **argv)
ANSI C
======
Por curiosidade no "The C Programming Languagem 2nd Editon (ANSI C)" a
maior ocorrência é da sintaxe:
main()
Também podemos encontrar no livro mas com freqüência muito menor:
main(int argc, char *argv[])
main(int argc, char **argv)
Apesar de não ocorrer no texto do livro as seguintes construções também
são válidas:
int main()
int main(void)
main(void)
int main(int argc, char *argv[])
int main(int argc, char **argv)
Felizmente abri os olhos (agradeço a vocês) e concluí que void antes de
main() além de não ser padrão não faz sentido (quem sabe em sistemas
dedicados...rss).
Terminar o programa com return 0 é a mesma coisa que exit(0) inclusive
também fecha todos os arquivos abertos.
Por default main() retorna para o sistema operacional "error level" 0
(zero), isso estando explícito no código ou não, o retorno int da main()
sempre é forçando por questões de retorno de erros de execução para o
sistema operacional, isso por padrão, até pouco tempo atrás não tinha me
tocado disso nem pesquisado, mas confesso que estou gostando de trocar
conhecimentos com vocês.
Uma curiosidade é que void foi definido inicialmente na especificação do
C++ mas primeiramente implementado no ANSI C.
A princípio o C++ era um pré-processador que convertia o código na
especificação C++ para C.
Desculpe, quis dizer deprecado.
[snip]
[snip]
>>>>
>>> Oi Felipe aonde viste que void é obsoleto no ISO/ANSI C++?
>>>
>>
>> Desculpe, quis dizer deprecado.
>>
>> [snip]
>>
>>
> OK, deprecated significaria que o uso de void seria então desaprovado e
> poderia não ser mais suportado pelas próximas versões no padrão ISO/ANSI
> C++, mas aonde você leu isso?
No padrão do C++03 em C.1.6
No padrão C++03 lista exatamente somente essas duas que mostrei.
Em 3.6.1.
[snip]
[snip]
>>>
>> OK, deprecated significaria que o uso de void seria então desaprovado e
>> poderia não ser mais suportado pelas próximas versões no padrão ISO/ANSI
>> C++, mas aonde você leu isso?
>
> No padrão do C++03 em C.1.6
Talvez eu tenha me equivocado. Não diz explicitamente que é deprecated.
Pelo que consta nos livros (clássicos) que listei, definiram o void para
substituir char em casos por exemplo de ponteiros genérios e explicitar
que uma função não tem retorno, já que estão sugerindo tornas void
deprecated o que eles recomendam usar no lugar de void?
Detalhe este padrão (C++03) ainda não saiu oficialmente, mas valeu por
esclarecer seu comentário.
[snip]
>> No padrão C++03 lista exatamente somente essas duas que mostrei.
>> Em 3.6.1.
>>
>> [snip]
>
> Pelo que consta nos livros (clássicos) que listei, definiram o void para
> substituir char em casos por exemplo de ponteiros genérios e explicitar
> que uma função não tem retorno, já que estão sugerindo tornas void
> deprecated o que eles recomendam usar no lugar de void?
Peraí, acho que você interpretou incorretamente o que disse.
Disse que uso de void no parametro de função era obsoleto.
Em C.1.6 ele diz obsolesce. O que vendo aki no dicionário:
ob·so·lesce (bs-ls)
intr.v. ob·so·lesced, ob·so·lesc·ing, ob·so·lesc·es
To undergo the process of becoming obsolete.
Aparentemente eu estava quase certo :P.
Mas para os outros usos void é normal.
Deixe-me ver como escrevi esta parte no email original.
>>>>>E C++ declara (void) obsoleto para qualquer função, logo tendo
É, realmente uma pobre escolha de palavras.
>
> Detalhe este padrão (C++03) ainda não saiu oficialmente, mas valeu por
> esclarecer seu comentário.
C++03 já saiu, em 2003...
Sabe aonde posso encontrar as diferenças do C++ apresentado no livro
"The C++ Programming Language - Third Editon" para o último padrão
oficial do C++?
Para eu me atualizar.
Mas se preferir assim, me desculpe realmente ninguém falou deprecated
talvez deveria ter me colocado de outra maneira.
Já havia entendido que não posso declarar main como void, mas de
qualquer forma valeu pelo dica!
Com relação a sua última colocação entendi que isso é uma recomendação
do C++0x (2009), o novo padrão consideraria void em lista de argumentos
como deprecated, é isso?
Sardano :-)
Já havia olhado no dicionário antes mas achei legal transcrever aqui:
deprecated = desaprovado, reprovado, condenado, censurado, protestado
(dicionário Webster's)
Não apropriado é você martelar um prego com um alicate, ao invés de usar
uma ferramenta como martelo.
Não apropriado, não apropriado para que?
Void foi criado com o propósito de explicitar três situações:
1) A função não retornará parâmetros;
2) A função não receberá parâmetros e;
3) O ponteiro não tem tipo definido, ou seja, apenas aponta para um
endereço cujo conteúdo não tem nenhuma interpretação e manipulação
pré-determinada.
Quais dos usos acima de void o novo padrão considera deprecated?
Estou fazendo essas perguntas pois sempre usei void nas três situações
acima e gostaria de saber se estou fazendo errado de acordo com o novo
padrão.
E fazer isso no padrão atual é certo?
Confesso que abolir o void para retorno e parâmetros de função iria até
deixar o programa mais limpo na minha opinião, agora void como ponteiro
já é uma outra história.
Seguir padrões é importante para garantir portabilidade, produtividade e
facilidade de manutenção.
Valeu Lamarão, um abraço,
Sardano
Eu disse sim Pedro.
Para o segundo caso. Fica em C.1.6 no Padrão C++03.
Ele diz obsolesce, que é equivalente a em processo de se tornar obsoleto.
Ou seja, deprecated.
>
> O que não se deve fazer é declarar a função main como retornando void,
> ou declarar funções com uma lista de argumentos (void).
>
> /'\
> |
> |
>
> --
> P.
--> int main(void)
Já que estamos falando do padrão: uma função...
...declara parametros
...recebe argumentos
...jamais *recebe* *parametros*.
Nada em C.1 torna algo em C++ obsoleto, C.1 lista as diferenças intencionais em relação à linguagem C.
C.1.6/1 diz que a semântica de que uma lista de parâmetros vazia especifica a passagem de número e tipo desconhecidos de argumentos tornou-se obsoleta em C. Nào em C++ porque isso nunca existiu em C++. Repare que esse parágrafo não está falando do uso de void.
As regras para a função main estão descritas em 3.6.1.
O padrão requer que as duas formas comuns sejam aceitas e não especifica que outras não são.
8.3.5/2 declara explicitamente a semântica do token "(void)" como uma lista de parâmetros. Se procurar por (void) encontrará vários exemplos no próprio padrão que usam essa sintaxe, embora ela seja redundante.
Todas as citações acima estão convertidas para os "endereços" no working-draft público:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf
Fiz o possível para me certificar de que minhas assumptions dos padrões passados estão corretas, mas recorri a memória mais de uma vez e terei prazer em ser corrigido.
Me referi à lista de parâmetros. O padrão é preciso com relação ao tipo do retorno e o valor implícito de retorno.
Effect on original feature: Change to semantics of well-defined
feature. This feature was marked as
"obsolescent" in C
[snip]
> As regras para a função main estão descritas em 3.6.1.
> O padrão requer que as duas formas comuns sejam aceitas e não especifica que outras não são.
Lógico, vc pode usar inclusive void em muitos compiladores.
Mas este não é padrão, e somente as duas listadas em 3.6.1 são.
[snip]
C.3.6.1:
O padrão diz que é implementation defined, e exije que duas sejam aceitas. O que você quer dizer é que não é portável, não que não é padrão. Para o padrão, não existem compiladores, computadores ou programadores. Ele simplesmente especifica um idioma para se comunicar idéias de um domínio. Para o padrão, existem infinitas versões de main aceitas (todas em que o tipo de retorno é int).
O que ele transforma obsolescent? O uso de void ou omissao dele?
Me parece que eh o uso dele. Tanto eh que em C99 temos a mesma
definicao que aki.
> C.3.6.1:
> O padrão diz que é implementation defined, e exije que duas sejam aceitas. O que você quer dizer é que não é portável, não que não é padrão. Para o padrão, não existem compiladores, computadores ou programadores. Ele simplesmente especifica um idioma para se comunicar idéias de um domínio. Para o padrão, existem infinitas versões de main aceitas (todas em que o tipo de retorno é int).
Meu entendimento de implementation defined 'e que nao eh padrao.
O padrao permite todo tipo de extensao que nao comprometa um codigo
estritamente conformante.
Ele fazendo uso de implementation defined ou undefined behavior.
Lendo novamente aki, acho que concordo contigo agora.
Ele na verdade diz que o antigo comportamento foi considerado
deprecado no padrão C para funcoes nao definidas
com lista de parametros void.
[snip]