Jump to content
Baptistazito

Warnings "typedef"

Recommended Posts

Baptistazito

Boas, Tou aqui a tirar uns warnings que nao percebo o que tem de mal.

Tenho esta estrutura

typedef struct FshardID{

int dados;
struct fshardID *next;

}fshardID;

e algumas funçoes, insere, percorre etc...

void insereFim(fshardID *LISTA, int dados)

{
fshardID *novo=(fshardID *) malloc(sizeof(fshardID));
fshardID *tmp;
if(!novo){
 printf("Sem memoria disponivel!\n");
 exit(1);
}
novo->dados= dados;
novo->next = NULL;

if(vazia(LISTA)==1)
	LISTA->next=novo;
else{
 tmp = LISTA->next;

 while(tmp->next != NULL)
	tmp = tmp->next;

 tmp->next = novo;
}
}



}void imprime_lista(fshardID * LISTA){

fshardID * percorre;


if(vazia(LISTA)){
printf("Lista vazia!\n\n");
return ;
}
percorre = LISTA->next;
while ( percorre != NULL)
{
	printf("%d\n", percorre->dados);
	percorre= percorre->next;

}


}

e tenho warnings deste género e n sei o que tou a fazer de mal nem como tirar isto uma vez que o programa faz tudo o que quero, e quero tirar os warnings para o prog ficar mais "limpo":

: incompatible pointer types assigning to 'fshardID *'

(aka 'struct FshardID *') from 'struct fshardID *'

[-Wincompatible-pointer-types]

PS: comcei agora a mexer no Xcode no MAC e gostava de saber como é que se mete a aparecer o numero da linha onde estamos, como no caso do gedit e não descubro o atalho, se alguém souber ficaria agradecido...

Edited by Baptistazito

Share this post


Link to post
Share on other sites
HappyHippyHippo

que tipo de dados é struct fshardID ?

antes de responder toma nota de certas questões :

- a pergunta é inteligente, por isso não insultes o fórum a responder com algo que não tem sentido

- em C, identificadores são case-sensitive

- a pergunta é inteligente, por isso não insultes o fórum a responder com algo que não tem sentido

- olha bem para o teu código

- a pergunta é inteligente, por isso não insultes o fórum a responder com algo que não tem sentido


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
Baptistazito

fshardID é do tipo FshardID. Já pensei que no malloc deveria pôr FshardID em vez de fshardID mas não percebo porquê nem acho q isso funcione

Share this post


Link to post
Share on other sites
pwseo

O malloc, apesar de nao estar muito correcto (em C nao se faz cast do resultado da malloc), não é o teu problema. Responde à questão do HappyHippyHippo quando a tiveres relido, e tem atenção ao fragmento onde defines a struct.

Share this post


Link to post
Share on other sites
pwseo

Essa nao foi a pergunta, e mesmo que fosse, essa nao seria a resposta. Perguntaram-te qual é o tipo de dados struct fshardID (repara bem: nao é apenas fshardID mas sim struct fshardID).

Share this post


Link to post
Share on other sites
KTachyon
PS: comcei agora a mexer no Xcode no MAC e gostava de saber como é que se mete a aparecer o numero da linha onde estamos, como no caso do gedit e não descubro o atalho, se alguém souber ficaria agradecido...

XCode > Preferences > Text Editing > Show: Line Numbers


“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

-- Tony Hoare

Share this post


Link to post
Share on other sites
Baptistazito

é do tipo typedef...LOL(é a unica que me ocorre) não faço ideia! Mas acho que o problema está nos cabeçalhos das funçoes. que deveriam ser

fshardID * insere(...)

Share this post


Link to post
Share on other sites
pwseo

Typedef não é um tipo de dados... Tu sabes como funciona a declaração de uma struct? E como funciona a definição de um typedef? Vê bem a definição da tua struct FshardID (que envolveste num typedef para lhe dar o nome fshardID) e lê com muita atenção. O campo next parece-te correcto? Lembra-te que as maiúsculas e minúsculas importam em C!

PS.: este é mais um caso em que as pessoas se metem em confusões só por causa dos typedefs.

Edited by pwseo

Share this post


Link to post
Share on other sites
HappyHippyHippo

faz assim : resolve o problema sem o typedef

(eu não estou a dizer para tirares o typedef, estou a dizer para resolver o problema sem o typedef)

  • Vote 1

IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
thoga31

Mais uma de typedef's? Estas escolas e universidades andam a ensinar muito bem os alunos. Dizem que é com typedef e vai disto :confused:

@Baptistazito, aqui vai uma dica acerca do que faz o typedef. Depois, analisa bem a estrutura que criaste no teu typedef, e vê o que é, afinal, struct fshardID.

typedef int inteiro;

inteiro i = 0;

ATENÇÃO! Este trecho de código é meramente exemplificativo e jamais deverá ser utilizado desta forma!

Edited by thoga31

Knowledge is free!

Share this post


Link to post
Share on other sites
Baptistazito

eu sei que o typedef não é um tipo de dados. Disse mesmo só por dizer, pois não sei a que se refere o tipo de dados Struct fshardID.

O comando typedef é usado para redefinirmos a estrutura dentro de uma nova estrutura certo, segundo me parece. tirando os typedefs deveriamos fazer qualquer coisa deste género certo?

struct estrutura {
   int		 conteudo;
   struct estrutura *next;
};

já sei que pa tirar os warnings tenho de fazer

typedef Estrutura{
 dados
 struct Estrutura * next;  /*com E maiusculo*/


}estrutura;

por acaso nem tinha reparado no E maiusculo pois quando acedemos à estrutura dentro dela devemos sempre usar a declaração e não a redefinição correto?

Mas porquê é que nunca percebi, qual o objetivo deste warning da "****" uma vez que o programa corre sempre sem erros, alguém me poderá dar um exemplo em que o programa deixe de correr ou dê seg fault ou qq outra coisa...

Edited by Rui Carlos

Share this post


Link to post
Share on other sites
thoga31

Não sabes a que se refere uma coisa que tu mesmo declaraste?

O typedef não é nada disso. A sua aplicação mais visível é, talvez, nas structs, mas o que ele faz é criar sinónimos de tipos. Reparaste no meu exemplo? Não era nenhuma estrutura.

Portanto, quando fazes...

typedef struct pessoa {
  // qq coisa
} tpessoa;

Definiste que tpessoa é sinónimo de struct pessoa, cuja definição está entre chavetas.

Agora repara nisto que fizeste:

typedef struct FshardID {
   // ...
   struct fshardID *next;
} fshardID;

fshardID (minúsculo) é sinónimo de struct FshardID (maiúsculo), e dentro da struct tu fazes struct fshardID.

Já te apercebeste do que está mal?

Já agora, os warnings fazem muito bem em lá estar, que o compilador não é parvo. Pode não dar sempre erro em execução, mas os warnings indicam que há ali uma possível fonte de problemas. Se eles não fossem precisos, não existiam. Portanto, os warnings talvez até te estejam a tentar alertar para os teus erros.

Edited by thoga31

Knowledge is free!

Share this post


Link to post
Share on other sites
Baptistazito

eu queria-me referir ao typedef neste caso em particular, mas claro a tua resposta está mais correta que a minha... e sim já me apercebi do que está mal mas não percebi porquê.

Já agora voltando aos warnings da "****", há algum exemplo prático em que dê algum erro em usar a redefinição dentro da estrutura ao invés de a sua declaração. Se não me conseguirem dar um exemplo prático em que haja um qualquer erro na compilação/execução do programa,para mim, continuará sempre a ser um warning da "****"(peço desculpa aos mais sensíveis).

E já agora tks pelos esclarecimentos até aqui dados ;)

Share this post


Link to post
Share on other sites
thoga31

Então viste o que está mal mas não percebes porquê? Explica lá qual é a tua dúvida. É extremamente importante esta questão dos typedef's ficar esclarecida e entendida, caso contrário voltaremos a ter-te aqui com um problema do género noutro typedef - é um clássico do C.

E não há "redefinições dentro de estruturas", whatever that means, há a criação de sinónimos.

Já agora, isto...

já sei que pa tirar os warnings tenho de fazer

typedef Estrutura{
 dados
 struct Estrutura * next;  /*com E maiusculo*/


}estrutura;

...não se deve fazer. Afinal, qual é o tipo de Estrutura (e não struct Estrutura)?

por acaso nem tinha reparado no E maiusculo pois quando acedemos à estrutura dentro dela devemos sempre usar a declaração e não a redefinição correto?

Errado.

Já agora, o warning que colocaste no início do tópico, faz todo o sentido e não é "da ****". A questão é que não o interpretaste e te dedicaste a perceber. O warning está-te a dizer tudo: apesar de não ser oficialmente um erro, tens uma possível fonte de problemas por teres incompatibilidade de apontadores devido a uma má definição do typedef. O programa pode até nem ir abaixo, mas quem te garante que não ocorre coisas "ocultas" como memory leak? Pois é... o programa não vai abaixo com isso, mas isso não significa que não estejam a acontecer coisas "menos próprias" na execução. E este warning está-te precisamente a avisar disso.


Knowledge is free!

Share this post


Link to post
Share on other sites
Baptistazito

não sei citar frase a frase como fizeste mas vou tentar, já agora se houver algum moderador que me edite ou me explique como se seleciona trechos do post anterior para ir respondendo ficaria agradecido.

E não há "redefinições dentro de estruturas", whatever that means, há a criação de sinónimos.

(falando no caso das estruturas)

Em qualquer página que vi sobre typedef o que encontrei foi que o tpedef permitia voltar a definir, voltar a dar um novo nome/renomear uma estrutura

...não se deve fazer. Afinal, qual é o tipo de Estrutura (e não struct Estrutura)?

eu acho que o tipo da estrutura e struct mas é apenas uma suposição pois não vejo ali mais nada que me possa indicar o tipo.

Errado.

Então quando é que podemos referir-nos à estrutura, quando usamos o comando typedef, usando o seu "sinónimo"

Já agora, o warning que colocaste no início do tópico, faz todo o sentido e não é "da ****". A questão é que não o interpretaste e te dedicaste a perceber. O warning está-te a dizer tudo: apesar de não ser oficialmente um erro, tens uma possível fonte de problemas por teres incompatibilidade de apontadores devido a uma má definição do typedef. O programa pode até nem ir abaixo, mas quem te garante que não ocorre coisas "ocultas" como memory leak? Pois é... o programa não vai abaixo com isso, mas isso não significa que não estejam a acontecer coisas "menos próprias" na execução. E este warning está-te precisamente a avisar disso.

Mas em casos semelhantes ou noutros haverá alguma altura em que o nosso programa simplesmente deixe de correr?

O programa faz exatamente o mesmo de alocações que é susposto com ou sem warning, não demora mais tempo, nem dá erro de execução.

Pergunta: Há algum exemplo prático em que isto ocorra? pelas vossas resposta já percebi que sim, seria possível mostrarem-mo?

Edited by Rui Carlos
Adicionadas tags de citação.

Share this post


Link to post
Share on other sites
thoga31

não sei citar frase a frase como fizeste mas vou tentar, já agora se houver algum moderador que me edite ou me explique como se seleciona trechos do post anterior para ir respondendo ficaria agradecido.

No canto inferior direito de cada post tens um botão que diz citar.

Estás à procura de algo invisível. Só um olho experiente detecta no código coisas como memory leak. O PC não se queixa, o compilador não detecta, o programa não vai abaixo. Se tu tens uma incompatibilidade de ponteiros e que não é um erro per se, o compilador dá um warning a dizer que aquilo pode dar problemas na execução, problemas esses que podem nem ser detectáveis ou visíveis.

Quanto ao typedef de uma struct, tu estás a criar um sinónimo, certo? Então, quando te quiseres referir à struct, das duas uma: ou usas o nome original ou o sinónimo. Aquilo que tu estavas a fazer era declarar uma struct do sinónimo, ou seja, uma struct de uma struct... vê bem o que faz o typedef com o exemplo simples que dei.


Knowledge is free!

Share this post


Link to post
Share on other sites
Baptistazito

Ty, e já agora eu sei a parte do citar não sei é seleccionar os pequenos trechos de um mesmo post pa ir respondendo como tu fzste no post anterior. Por agora percebi o typedef. Espero que quando aparecer outra coisa do género a consiga resolver!!!

Edited by Baptistazito

Share this post


Link to post
Share on other sites
HappyHippyHippo

Em qualquer página que vi sobre typedef o que encontrei foi que o tpedef permitia voltar a definir, voltar a dar um novo nome/renomear uma estrutura

podes dizer em que livro viste isso ? é só para juntar mais um para a lista de livros que já mandei o autor ir tirar um curso.

o typedef não volta a definir, não volta a dar um novo nome ou renomeia uma estrutura. todas as hipóteses que referiste implicaria a eliminação do nome original do tipo de dados.

o typedef cria um tipo de dados. em programação (sim, em todas) um tipo de dados é um conceito abstracto usado pelo compilador onde somente este sabe fazer a ligação entre um tipo de dados e os bits que se encontram em memória. claro que um bom programador também, mas o que estou a dizer é que uma segunda aplicação não saberá (à partida) como interpretar os bits de memória de uma outra aplicação, sejam eles um inteiro ou um conjunto de dados estruturados (struct).

só depois de saber que os tipos de dados não são mais as maneiras do compilador/aplicação interpretar os bits/bytes de memória, é que podes dizer que o typedef dá a possibilidade de um programador de C, de criar uma interpretação de um bloco de memória. abstracção essa que se encontra directamente relacionada com o tamanho de memória do bloco a ser interpretado.

um segundo ponto a ter em conta para este problema é saber que quando crias uma estrutura, a palavra reservada struct faz parte do nome do tipo de dados. no teu caso, não existe o tipo de dados FshardID mas sim struct FshardID

exemplos explicativos do que é um typedef :

void * ponteiro;         // um ponteiro (em máquinas de 32 bits são 4 bytes / 32 bits)

typedef void * Ponteiro; // O tipo de dados "Ponteiro" é uma maneira de interpretar um bloco de memória com o tamanho
                        // igual ao de uma variável do tipo "void *" (32 bits) de tal modo que esse espaço seja interpretado
                        // como fosse do tipo "void *"

struct Estrutura {
 int inteiro;
 struct Estrutura * estrutura;
};                                      // uma estrutura que ocupa 32 bits do inteiro mais 32 bits (em máquinas 32 bits) do
                                       // ponteiro, isto quer dizer que no total, uma estrutura destas ocupa em memória 64 bits
                                       // (em máquinas 32 bits)

typedef struct Estrutura Estrutura;     // O tipo de dados "Estrutura" (sim isto é válido) é uma maneira de interpretar um bloco
                                       // de memória com o tamanho igual ao de uma variável do tipo "struct Estrutura" (64 bits)
                                       // de tal modo que esse espaço seja interpretado como fosse do tipo "struct Estrutura" 

typedef struct Estrutura * PtEstrutura; // O tipo de dados "Estrutura" é uma maneira de interpretar um bloco de memória com o
                                       // tamanho igual ao de uma variável do tipo "struct Estrutura *" (ponteiro = 32 bits) de
                                       // tal modo que esse espaço seja interpretado como fosse do tipo "struct Estrutura *" 

Mas em casos semelhantes ou noutros haverá alguma altura em que o nosso programa simplesmente deixe de correr?

não, existe é casos em que o compilador nem sequer compila

exemplo:

#include <stdio.h>

typedef struct tipo {
   int i;
   struct Tipo * pt_next; // <--- struct Tipo ... não está definido em lado nenhum
                          //      no entanto o erro de compilação não será aqui
} Tipo;

int main(int argc, char ** argv) {
   Tipo v1, v2, v3;

   v1.i = 1010;
   v2.i = 2020;
   v3.i = 3030;

   v1.pt_next = (struct Tipo *) &v2;
   v2.pt_next = (struct Tipo *) &v3;

   printf("v1.i = %d\n", v1.i);
   printf("v2.i = %d\n", v2.i);
   printf("v3.i = %d\n", v3.i);

   printf("v1.i = %d\n", v1.i);
   printf("v1.pt_next->i = %d\n", v1.pt_next->i);                   // error: dereferencing pointer to incomplete type
                                                                    //        o compilador não sabe o que fazer porque
                                                                    //        struct tipo de dados "struct Tipo" não existe
   printf("v1.pt_next->pt_next->i = %d\n", v1.pt_next->pt_next->i); // error: dereferencing pointer to incomplete type
                                                                    //        o compilador não sabe o que fazer porque
                                                                    //        struct tipo de dados "struct Tipo" não existe

   return 0;
}

Ty, e já agora eu sei a parte do citar não sei é seleccionar os pequenos trechos de um mesmo post pa ir respondendo como tu fzste no post anterior.

corte e custura do resultado de quando carregas no botão citar

Edited by HappyHippyHippo

IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
pwseo
Se não me conseguirem dar um exemplo prático em que haja um qualquer erro na compilação/execução do programa,para mim, continuará sempre a ser um warning da "****"(peço desculpa aos mais sensíveis).

Antes de mais, aqui não se trata de haver pessoas mais sensíveis ou não, mas sim de uma questão de educação. Não sei o que te passou pela cabeça para utilizares esse tipo de linguagem, especialmente sem motivo nenhum para tal -- só por desconhecimento é que alguém falaria assim dos avisos emitidos pelo compilador.

Relativamente ao exemplo, acho que não estás a compreender bem a questão. Tu estás a escrever código errado, e o facto de não haver um erro de compilação não quer dizer que não haja problema.

O que te disseram foi que struct FshardID e fshardID são tipos de dados (que são sinónimos um do outro, como indicado pela utilização do typedef.

O tipo de dados struct fshardID não existe, e no entanto o teu programa continua a funcionar porque o compilador é muito tolerantee pensa da seguinte forma:

Bem, não conheço aquele tipo de dados struct fshardID, mas se calhar o programador sabe o que faz, por isso vamos em frente e emitimos apenas um aviso sobre este código duvidoso.

O problema é que neste caso, o programador não sabe o que faz, e por pura sorte o programa funciona bem. Só por sorte. O HappyHippyHippo até já deu exemplo de um caso em que nem sequer conseguirias compilar o programa.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.