15

我正在使用现有的 C 代码,其中有几行与此类似的语句:

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

结构 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 不喜欢这条线?

4

10 回答 10

28

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

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

#define __offsetof__(x) (x)

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

__offsetof__通过转到“路径和符号”属性页面并添加一个映射到“foo”的宏,我能够摆脱语法错误。这会诱使解析器认为它只是对以前从未见过的函数的调用,而不是语法错误。

或者,您可以通过转到 Window > Preferences > General > Editors > Text Editors > Annotations 并取消选中 C/C++ Indexer Markers 的所有复选框来关闭编辑器中的语法错误报告。

于 2009-05-07T14:35:15.293 回答
10

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

于 2012-10-05T16:06:00.867 回答
8

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

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

2-在菜单“ Window->Preferences->C/C++->Indexer ”中,通过选中所有复选框(但不是“跳过”复选框)设置完整索引,如下所示: 全局索引器设置

3-在每个项目的具体属性中,菜单' Project->Properties->C/C++ general->Indexer ',取消勾选'Enable project specific settings',如下图: 项目索引器设置

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

于 2018-05-02T06:05:23.787 回答
5

似乎 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;
于 2009-04-29T13:56:52.723 回答
2

可能会感到困惑,offsetof例如,检查您是否有范围内的定义。#define否则,您可能会尝试简化表达式,使用例如 a和offsetof 或其他东西来分解它。

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

于 2009-04-29T13:47:07.193 回答
2

尝试在 Preferences->c/C++ -> indexer 中将索引器切换到“Full c/C++ indexer (complete parse)”

于 2009-10-26T17:18:12.283 回答
1

我有同样的问题。offsetof 有两种定义(一种用于 C,一种用于 C++)。IMO的问题来自于此

例如,如果我输入

#ifndef __cplusplus
#endif

Eclipse 会将其变灰。这意味着 __cplusplus 已定义,但我的项目是 C

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

于 2009-04-29T21:44:05.563 回答
1

我最终解决了这样的问题。首先我打开项目属性,然后是 C/C++ 通用->路径和符号类别。在 Symbols 选项卡下,我添加了这个条目:

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

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

于 2012-12-06T02:36:35.700 回答
1

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

于 2011-08-10T12:30:11.563 回答
0

我已经看到 Eclipse 多次这样做了,我将它用于 Java。通常关闭并再次打开文件会为我修复它(重置任何错误)。通常似乎是一个错误,但已修复,并且“错误缓存”未正确更新。

于 2009-04-29T13:51:11.583 回答