Por que Eclipse CDT dizer: 'erro de sintaxe', mas compilação nenhum problema
-
03-07-2019 - |
Pergunta
Eu estou trabalhando em código C existente que tem um par de linhas com declarações semelhantes a esta:
struct collect_conn *tc = (struct collect_conn *)
((char *)c - offsetof(struct collect_conn, runicast_conn));
O collect_conn struct vai ao longo das seguintes linhas:
struct collect_conn {
struct runicast_conn runicast_conn;
struct announcement announcement;
const struct collect_callbacks *cb;
struct ctimer t;
uint16_t rtmetric;
uint8_t forwarding;
uint8_t seqno;
};
Eu estou usando Eclipse CDT, e marca a linha com uma laranja linha ondulada como 'erro de sintaxe'. Eu acho que ele é marcado como tal pelo indexador CDT. No entanto, a compilação (manualmente em um terminal) não é problema.
Este é um pouco inconveniente no entanto, uma vez que os elementos na linha não indexados (para que a árvore de hierarquia de chamadas nem sempre é correto, ou o realce de elementos, etc.)
Por que Ecipse não como a linha como é?
Solução
Eclipse CDT contém o seu próprio pré-processador / analisador para analisar seu código e construção de um índice. No entanto, quando você chamar uma compilação CDT chama por seu compilador do sistema, como gcc, por exemplo. Pode haver pequenas diferenças entre a sintaxe aceito pelo analisador CDT ea sintaxe aceites pelo seu compilador. Quando isso acontece o analisador CDT pode ficar confuso.
No meu sistema as offsetof
se expande formando uma expressão que utiliza a palavra-chave __offsetof__
. Esta palavra-chave não é reconhecida pelo CDT é por isso que há um erro de sintaxe. Para lidar com este problema o analisador CDT tem uma macro construída para lidar com __offsetof__
que tem esta aparência:
#define __offsetof__(x) (x)
Este não parece ser correto, pelo menos no meu sistema, o resultado é a remoção da chave __offsetof__
da fonte que ainda leva a um erro de sintaxe.
Eu era capaz de livrar-se do erro de sintaxe, indo para a página de propriedades caminhos e símbolos e adicionando uma macro para __offsetof__
que mapeia para 'foo'. Isso engana o analisador em pensar é apenas uma chamada para uma função que não tenha visto antes, mas não um erro de sintaxe.
Como alternativa, você pode desativar o relatório de erro de sintaxe no editor, indo para Janela> Preferências> Geral> Editores> Editores de texto> Anotações e desmarcando todas as caixas de seleção C C ++ indexador Marcadores /.
Outras dicas
Eu fixo no CDT eclipse com Preferências-> C / C ++ -> Idioma Mapeamentos: Add Tipo de Conteúdo: C-header Idioma: C ++
Parece que o analisador CDT não gosta da parte offsetof (struct ...). Se você declarar collect_conn usando um typedef o erro desaparece. Pelo menos para mim, o seguinte código funciona:
typedef struct {
struct runicast_conn runicast_conn;
struct announcement announcement;
const struct collect_callbacks *cb;
struct ctimer t;
uint16_t rtmetric;
uint8_t forwarding;
uint8_t seqno;
} collect_conn;
...
struct collect_conn *tc = (struct collect_conn *)
((char *)c - offsetof(collect_conn, runicast_conn));
Se você não pode alterar a declaração anterior fazer algo como isto:
typedef struct collect_conn collect_conn_t;
Pode ser confuso, cheque se você tem uma definição de offsetof
no âmbito, por exemplo. Caso contrário, você pode tentar simplificar a expressão, dividindo-o usando, por exemplo um #define
com o offset
de, ou algo assim.
Eu estou pensando o compilador pode fornecer um built-in versão do offsetof
, enquanto compilador / code-analisador de Eclipses talvez não. Se assim for, você precisa ter certeza de que a definição, para Eclipse para ser capaz de analisar corretamente seu código.
tente trocar o indexador para "c completa indexador / C ++ (análise completa)" em Preferências> c / C ++ -> indexador
Às vezes, embora os compila o código com nenhum erro, eclipse em tempo real mostra analisador de código do CDT alguns erros em arquivos C / C ++ (ex. 'Xxx função não pôde ser resolvido). Isso ocorre porque eclipse CDT usa seu próprio pré-processador / analisador para analisar o código e construir os índices em vez de um do MinGW (ou qualquer outro compilador GNU). A fim de corrigir isso globalmente para todos os projetos Eclipse no espaço de trabalho, siga estes passos: (A fim de corrigir isso só para um projeto específico, siga os passos 1, 2 e 4 no menu de ' Projeto-> Preferências ')
1-No menu de ' Janela-> Preferências> C / C ++ -> Mapeamentos de idiomas ', adicione os mapeamentos corretos, conforme mostrado abaixo: (por exemplo, para tipos de conteúdo: C ++ Source / cabeçalho. arquivo, usar a linguagem GNU C ++ e assim por diante) globais Idioma Mapeamentos Configurações
2 No menu de ' Janela-> Preferências> C / C ++ -> indexador ', definir a indexação plena, verificando todas as caixas de seleção (mas não os 'Ignorar') como mostrado abaixo: globais Configurações indexador
3-In propriedades específicas de cada projeto, o menu ' Projeto-> Propriedades-> C / C ++ Geral-> indexador ', desmarque 'Permitir configurações específicas do projeto', como mostrado abaixo: Projeto Configurações indexador
4 reconstruir a indexação, o menu ' Projeto-> C / C ++ Index> Reconstruir '.
Iv tem o mesmo problema. Há duas definição de offsetof (um para C e uma para C ++). IMO o problema vem de que
Por exemplo, se eu digito
#ifndef __cplusplus
#endif
Eclipse vai cinza-lo. Ele __cplusplus média está definido, mas meu projeto é um C
Infelizmente eu não encontrar uma solução.
Eu fixo problema semelhante depois de verificar os Analisadores guia de erro no Makefile de projeto no Project Wizard New CDT, removendo CDT Visual C de erro do analisador (estou usando gcc)
acabei resolvendo o problema como este. Primeiro eu abriu as propriedades do projeto, em seguida, o C / C ++ Geral-> Caminhos e símbolos categoria. Na guia Símbolos eu adicionei esta entrada:
Symbol: offsetof(TYPE,MEMBER)
Value: ((ssize_t) &((TYPE *)0)->MEMBER)
Estes símbolos são usados ??pelo indexador, mas não passou para o compilador (pelo menos em projectos Makefile, eu não tentei em outro tipo de projeto C), por isso não substitui o built-in offsetof
Eu vi Eclipse fazer isso algumas vezes, e eu usá-lo para Java. Normalmente, fechando e abrindo o arquivo novamente resolve o problema para mim (redefine o que está errado). Ele geralmente parece ser um erro que estava lá, mas foi corrigido e o "cache de erro" não é atualizado corretamente.