简体   繁体   English

GCC报告包含的无关错误

[英]GCC reporting unrelated errors for include

I've added a new file to a project: 我在项目中添加了一个新文件:

#ifndef PLAYER_H
#define PLAYER_H
#include "enet/enet.h" //the problem
typedef struct Player
{
    ENetPeer * peer; //requires problematic include
    //void * peer; //works, since no include required
} Player;
const struct Player playerEmpty;
#endif //PLAYER_H

If the include is present, I get reams of error: expected ';', ',' or ')' before numeric constant in unrelated files. 如果include存在,我会得到大量error: expected ';', ',' or ')' before numeric constant在不相关文件中的error: expected ';', ',' or ')' before numeric constant If I remove the include and use void * peer instead, all is well. 如果我删除了include并使用了void * peer ,那么一切都很好。 The enet library is included in a source file elsewhere, and works fine. enet库包含在其他地方的源文件中,并且工作正常。 I am using enet 1.3.13 (latest) and its header guards appear to be in place. 我正在使用enet 1.3.13(最新版),其标题保护似乎已到位。 This is under gcc 4.9.2. 这是在gcc 4.9.2下。

For the record the errors are occurring in Point.h : 为了记录错误发生在Point.h

#ifndef POINT_H
#define POINT_H

#include <stdint.h>

#define X 0
#define Y 1
#define Z 2

typedef  int16_t  int16_Point2[2];
typedef  int32_t  int32_Point2[2];
typedef uint16_t uint16_Point2[2];
typedef uint32_t uint32_Point2[2];

typedef  int16_t  int16_Point3[3];
typedef  int32_t  int32_Point3[3];
typedef uint16_t uint16_Point3[3];
typedef uint32_t uint32_Point3[3];

#endif //POINT_H

I'm sure it's something simple - any idea what I am doing wrong? 我确定这很简单 - 任何想法我做错了什么?

Using single-letter macro names is a good idea in general. 一般来说,使用单字母宏名称是一个好主意。 They might very easily replace the letters in unexpected locations (note: Macros are actually textual replacement before the actual compilation phases). 它们可能很容易替换意外位置的字母(注意:在实际编译阶段之前,宏实际上是文本替换)。

You wrote the error is occuring in Point.h. 您写的错误发生在Point.h中。 I do not think they actually occur , but are only reported here. 我认为它们实际上并不存在 ,但仅在此报告 C is notoriously bad to detect grammar errors where they actually are. C在他们实际存在的地方检测语法错误是非常糟糕的。 Check the file which includes Point.h 检查包含Point.h的文件

Note: const struct Player playerEmpty; 注意: const struct Player playerEmpty; in a header is also likely unwanted, as that will create an object with external linkage in every compilation unit. 在标题中也可能不需要,因为这将在每个编译单元中创建一个具有外部链接的对象。 This is different from C++: in C, there are actually no constants, but only constant variables : const is just a promise by the programmer the variable will never be changed once initialized. 这与C ++不同:在C中,实际上没有常量,只有常量变量const只是程序员的承诺,变量一旦初始化就永远不会被改变。 Even worse: you do not assign it a value, thus making it effectively 0 - global variables are initialized to all bits 0. I'm quite sure this in not intended. 更糟糕的是:你没有给它赋值,从而使它有效地为0 - 全局变量被初始化为所有位0.我很确定这不是故意的。

Update: 更新:

If that is for points, how about: 如果这是积分,那么:

typedef union __attribute__ ((__packed__)) {
    struct {
        int16_t x,y,z;
    };    // anonymous union field (C99)
    int16_t vec[3];
} int16_Point3;

...

// usage:
int16_Point3 point = (int16_Point3){ .x = 5, .y = 3 }; // compound literal
point.z = point.x + point.vec[1]; // other word for point.y

to get rid of the #define s and getting proper syntax. 摆脱#define并获得正确的语法。

Note __attribute__ ((__packed__)) is gcc-specific to avoid padding bytes between struct fields. 注意__attribute__ ((__packed__))是特定于gcc的,以避免在struct字段之间填充字节。 That is non-standard, but other compilers often have similar features (eg pragma ). 这是非标准的,但其他编译器通常具有类似的功能(例如pragma )。 It is required to have identical layout for the struct and the array. 结构和数组必须具有相同的布局。

That might be more readable than the indexing. 这可能比索引更具可读性。 Note that anonymous struct and union fields are standard. 请注意, 匿名结构和联合字段是标准的。

The problem was single-character #define s. 问题是单字符#define s。 NEVER do this. 永远不要这样做。

I'd been using X , Y and Z for several months, but never had problems till my inclusion of Player.h , today, which must have finally - in a roundabout way - triggered some problems in the preprocessor / compiler. 几个月来我一直在使用XYZ ,但是直到我今天都包含Player.h之前一直没有问题,最终必须以迂回的方式触发预处理器/编译器中的一些问题。 Removing these returned compilation to (a semblance of) normality. 删除这些返回的编译为(外观)正常。

Thanks to those who helped in the comments. 感谢那些在评论中提供帮助的人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM