paulo1205
(usa Ubuntu)
Enviado em 31/03/2020 - 02:57h
adrisiq escreveu:
Sempre que eu tenho dúvida eu consulto esse site:
https://en.cppreference.com/w/
No canto superior direito tem uma pequena barra de busca, muito eficiente, ela retorna tanto resultados para
C quanto
C++ .
Sobre a sua dúvida especificamente:
https://en.cppreference.com/w/ c/io/fputs
A função
fputs retorna um
int e possui uma assinatura sobrecarregada, ou seja, pode ser usada de
duas formas diferentes .
Oops! Aqui você errou. Não são duas assinaturas diferentes devidas a sobrecarga, até porque não existe sobrecarga em C (existem umas macros para funções
type-generic , que é uma forma de mapear um mesmo nome para várias funções diferentes, mas estas são verborrágicas e manuais, não comparáveis ao que o C++ ou o Java fazem automaticamente).
O que acontece de verdade é que a assinatura da função foi mudando com o tempo, na medida em que o C foi ganhando novos recursos.
A palavra reservada
restrict , que indica para o compilador que dois ponteiros no mesmo escopo nunca vão ter acesso aos mesmos elementos, só surgiu no C a partir do padrão de 1999. É por isso que a assinatura
int fputs(const char *restrict s, FILE *restrict f) só passou a ser usada depois de 1999. Ali o uso de
restrict é para indicar que nenhum dos elementos indicados como parte de
s pode também ser obtido através do acesso a dados internos obtidos através de
f , e vice-versa (em outras palavras, não existe superposição de memória entre os dados apontados por
s e dos dados apontados por
f ), e o compilador pode (mas não é obrigado a) usar essa informação para produzir otimizações relativas à forma como faz acessos à memória apontada por cada um desses ponteiros.
Antes disso, não havia a palavra reservada
restrict . Desse modo, a primeira versão padronizada da função
fputs , que surgiu junto com o primeiro padrão do C, em 1989, tinha a seguinte assinatura.
int fputs(const char *s, FILE *f)
A outra forma mostrada pelo colega, “
int fputs(char *s, FILE *f) ”, nunca chegou a fazer parte de nenhum padrão. Antes de 1989, o que de mais próximo existia de um padrão para o C era a descrição da linguagem que havia na primeira edição do K&R, e essa descrição não trazia assinaturas para funções. Todas as funções eram declaradas de modo semelhante:
nome_do_tipo nome_da_funcao(); sendo que “
nome_do_tipo ” podia ser omitido se esse tipo fosse
int . A definição da função também era diferente do que estamos acostumados hoje, pois os tipos dos parâmetros não ficavam dentro dos parênteses, mas apenas seus nomes, e a informação dos tipos de cada parâmetro vinha, em qualquer ordem e podendo omitir aqueles com tipo igual a
int , após o fechamento dos parênteses e antes da abertura das chaves contendo o corpo da função. O exemplo abaixo mostra como poderiam ser a declaração e um esboço da definição de
fputs () no C do K&R.
/* Declaração */
fputs(); /* Tipo e retorno é int, logo podia ser omitido. */
/* Definição */
fputs(s, f) /* tipo de retorno omitido, já que é int. */
FILE *f;
char *s;
/* Note como a ordem da informação de tipo não precisa casar com a ordem dos parâmetros. */
{
/* Corpo da função aqui. */
}
Mas pode ser que tenha havido compiladores que tenham usado a forma sem
restrict nem
const . O esforço para a primeira padronização do C levou mais de seis anos para se completar (inciando em meados de 1983 e terminando em dezembro de 1989). Nesse meio tempo, os compiladores que iam sendo produzidos recebiam alguns dos recursos que ainda estavam sendo discutidos pelo comitê de padronização. Protótipos de função foram adotados antes do atributo
const (ambos oriundos do C++, que também ainda era relativamente embrionário naquela época), e isso pode ter se refletido tanto em implementações quanto em documentação produzida nesse ínterim. De fato, fuçando
on-line , eu consegui ver que o Turbo C 1.5 (produzido em 1987 e lançado em 1988) tinha uma
fputs () cujo primeiro argumento não tinha o atributo
const (uma cópia
on-line do manual do Turbo C 1.5 existe em
https://archive.org/details/bitsavers_borlandturuide1987_12272000/page/n123/mode/2up ; se você navegar para a página 110, vai ver a forma que ele mostra para
fputs ). Mas a versão seguinte do Turbo C, a 2.0, lançada mais perto do final do mesmo ano de 1988, já traz o atributo, de acordo com o que o padrão iria oficializar apenas no ano seguinte (veja
https://archive.org/details/bitsavers_borlandturReferenceGuide1988_19310204/page/n161/mode/2up , página 139).
Mas eu me alonguei contando história. A pergunta era qual poderia ser uma fonte confiável de documentação sobre o C. Eu compartilho a apreciação pelo
cppreference.com
, mas com um pouco de pé atrás porque, embora em média o conteúdo seja muito bom, como todo wiki, alguns artigos são melhores do que outros. Uma coisa boa dele é que ele costuma apresentar diferenças entre as implementações de cada versão do padrão (como no caso de
fputs ()), em vez de apenas trazer a versão mais nova ou de uma versão intermediária específica (como a MSDN e as manpages do Linux, pois ambas usam apenas o padrão de 1999 com variações, não o de padrão de 2011).
... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)