为什么Eclipse CDT会说:’语法错误’,但编译没问题

我正在使用现有的C代码,它有几行语句类似于这一行:

struct collect_conn *tc = (struct collect_conn *) ((char *)c - offsetof(struct collect_conn, runicast_conn)); 

struct collect_conn沿着以下行:

 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; }; 

我正在使用Eclipse CDT,它将带有橙色波浪线的行标记为“语法错误”。 我认为它是由CDT索引者标记的。 但是,编译(在终端中手动)是没有问题的。

然而,这有点不方便,因为线上的元素没有被索引(因此调用层次结构树并不总是正确的,或者元素的突出显示等)

为什么Ecipse不喜欢这条线?

Eclipse CDT包含自己的预处理器/解析器,用于分析代码和构建索引。 但是,当您调用构建CDT调用系统编译器时,例如gcc。 CDT解析器接受的语法与编译器接受的语法之间可能存在细微差别。 当发生这种情况时,CDT解析器可能会混淆。

在我的系统上, offsetof宏扩展为使用__offsetof__关键字的表达式。 CDT无法识别此关键字,因此存在语法错误。 为了解决这个问题,CDT解析器内置了一个宏来处理__offsetof__ ,如下所示:

 #define __offsetof__(x) (x) 

这似乎不正确,至少在我的系统上,结果是从源中删除了__offsetof__关键字,这仍然导致语法错误。

我可以通过转到Paths and Symbols属性页并为__offsetof__添加一个映射到’foo’的宏来摆脱语法错误。 这使得解析器认为它只是调用它以前没有见过的函数,而不是语法错误。

或者,您可以通过转到窗口>首选项>常规>编辑器>文本编辑器>注释并取消选中C / C ++索引器标记的所有复选框来关闭编辑器中的语法错误报告。

我已经使用Preferences-> C / C ++ – >语言映射修复了eclipse CDT中的问题:添加内容类型:C-header语言:C ++

似乎CDT解析器不喜欢offsetof(struct …)。 如果使用typedef声明collect_conn,则错误消失。 至少对我来说,以下代码有效:

 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)); 

如果您无法更改原始声明,请执行以下操作:

 typedef struct collect_conn collect_conn_t; 

可能会混淆,例如,检查你是否有范围内的offsetof定义。 否则,您可以尝试简化表达式,使用例如带offset#define或其他东西将其分解。

我认为编译器可能提供了offsetof的内置版本,而Eclipses的编译器/代码解析器可能没有。 如果是这样,您需要确保定义,以便Eclipse能够正确解析您的代码。

尝试在索引器中将“索引器”切换为“完整的c / C ++索引器(完全解析)” – > c / C ++ – > indexer

我遇到了同样的问题。 offsetof有​​2个定义(一个用于C,一个用于C ++)。 IMO的问题来自于此

例如,如果我输入

 #ifndef __cplusplus #endif 

Eclipse将灰显。 这意味着定义了__cplusplus,但我的项目是C

不幸的是,我没有找到解决办法。

在新CDT项目向导中检查Makefile项目中的选项卡错误解析器,删除CDT Visual C错误解析器(我正在使用gcc)后,我修复了类似的问题

我最终解决了这个问题。 首先,我打开了项目属性,然后是C / C ++ general-> Paths and Symbols类别。 在符号选项卡下,我添加了以下条目:

 Symbol: offsetof(TYPE,MEMBER) Value: ((ssize_t) &((TYPE *)0)->MEMBER) 

这些符号由索引器使用但不传递给编译器(至少在Makefile项目中,我没有在其他类型的C项目中尝试过),因此它不会覆盖GCC的内置偏移量

有时,虽然代码编译没有错误,但是eclipse CDT的实时代码分析器显示了C / C ++文件中的一些错误(例如,’函数xxx无法解析)。 这是因为eclipse CDT使用自己的预处理器/解析器来分析代码并构建索引,而不是MinGW的(或任何其他GNU编译器)。 为了全局修复工作区中的所有eclipse项目,请按照下列步骤操作:(为了仅针对特定项目修复此问题,请按照菜单’ Project-> Preferences ‘中的步骤1,2和4进行操作)

1 – 在菜单’ Window-> Preferences-> C / C ++ – > Language Mappings ‘中,添加正确的映射,如下所示:(例如,对于内容类型:C ++ Source / Header File,使用GNU C ++语言等) 全局语言映射设置

2 – 在菜单’ Window-> Preferences-> C / C ++ – > Indexer ‘中,通过选中所有复选框(但不是’Skip’复选框)来设置完整索引,如下所示: Global Indexer Settings

3 – 在每个项目的特定属性中,菜单“ 项目 – >属性 – > C / C ++通用 – >索引器 ”,取消选中“启用项目特定设置”,如下所示: 项目索引器设置

4 – 重建索引,菜单’ Project-> C / C ++ Index->​​ Rebuild ‘。

我见过Eclipse有时会这样做,我将它用于Java。 通常关闭并打开文件再次为我修复它(重置任何错误)。 它通常似乎是一个错误WAS那里但已修复,“错误缓存”没有正确更新。