【问题标题】:Why does Eclipse CDT say: 'syntax error', but compilation no problem为什么 Eclipse CDT 说:'syntax error',但编译没问题
【发布时间】:2010-10-22 14:11:39
【问题描述】:

我正在使用现有的 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 不喜欢这条线?

【问题讨论】:

    标签: c indexing eclipse-cdt


    【解决方案1】:

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

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

    #define __offsetof__(x) (x)
    

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

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

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

    【讨论】:

    • 感谢迈克。我试图弄清楚如何关闭语法突出显示。感谢您指出!
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

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

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

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

      【讨论】:

        【解决方案4】:

        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;
        

        【讨论】:

        • 是的,确实有效。但这对我来说不是一个选择:-(
        【解决方案5】:

        这可能会让人感到困惑,例如,检查您是否在范围内定义了@987654321@。否则,您可以尝试简化表达式,使用例如分解它#defineoffset 之类的。

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

        【讨论】:

        • 在偏移量上按 F3(goto 声明),将我带到 stddef.h 文件,因此它似乎引用了正确的 offsetof 宏
        • 在有问题的行之前,您是否还#include 该文件?
        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

          我也遇到了同样的问题。 offsetof 有两种定义(一种用于 C,一种用于 C++)。 IMO问题出在那个

          例如,如果我输入

          #ifndef __cplusplus
          #endif
          

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

          很遗憾,我没有找到解决办法。

          【讨论】:

          • 检查您创建的是 c 项目而不是 c++ 项目。我没有你提到的问题。
          【解决方案8】:

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

          【讨论】:

          • 有人知道如何为现有项目而不是新项目执行此操作吗?
          【解决方案9】:

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

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

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

          【讨论】:

            【解决方案10】:

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

            【讨论】:

            • 是的,我知道你的意思。我有时也必须这样做。但在这种情况下,这样做并不能解决问题。
            猜你喜欢
            • 2018-01-28
            • 2014-05-02
            • 1970-01-01
            • 2019-04-19
            • 1970-01-01
            • 1970-01-01
            • 2011-12-30
            • 2012-01-02
            • 1970-01-01
            相关资源
            最近更新 更多