为什么在没有语法错误的情况下不编译此代码?[关闭]

Why doesn't this code compile while there is no syntax error? [closed]

提问人:Faris 提问时间:5/9/2023 最后编辑:Jonathan LefflerFaris 更新时间:5/9/2023 访问量:210

问:


这个问题是由错别字或无法再现的问题引起的。虽然类似的问题可能在这里是主题,但这个问题的解决方式不太可能帮助未来的读者。

7个月前关闭。

我的代码中有一个问题,需要很长时间才能尝试修复它

  • 错误信息:

初始值设定项周围缺少大括号 [-Werror=missing-braces]

    struct entry {
       char *lexptr;
       int token;  
       };
    struct entry keywords[] = {
            "div", DIV,
            "mod", MOD,
            "if", IF,
            "while", WHILE,
            "then", THEN,
            "do", DO,
            "begin", BEGIN,
            "end", END,
                0, 0
        };

当我搜索时,我发现 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25137 有一个异常,但是在我的情况下如何解决它?

我认为这是一个很小的变化,但我没有得到它。

C++ C GCC 编译器错误 语法错误

评论

5赞 Quimby 5/9/2023
请发布一个最小的可重现示例并选择一种语言。
4赞 erik258 5/9/2023
"div", DIV,那应该是,不是吗?{"div", DIV},
0赞 Adrian Maire 5/9/2023
为我编译: onlinegdb.com/mYQGo44QD 您是否将 C 语法与 c++ 编译器混合在一起?
4赞 Ted Lyngmo 5/9/2023
你问的是 C 还是 C++?请选择一个。
1赞 Pete Becker 5/9/2023
@erik258 -- 编写的代码没问题。编译器读取初始值设定项列表,并将它们适当地打包出来。添加大括号可以使正在发生的事情更清楚,并且可以使代码不容易出错,但这不是必需的。

答:

3赞 Vlad from Moscow 5/9/2023 #1

似乎由于编译器选项 -Werror=missing-braces ,编译器不喜欢用于初始化类型元素的初始值设定项不包含在大括号中。struct entry

只需编写

struct entry keywords[] = {
    { "div", DIV },
    { "mod", MOD },
    { "if", IF },
    { "while", WHILE },
    { "then", THEN },
    { "do", DO },
    { "begin", BEGIN },
    { "end", END },
    {  0, 0 }
};

虽然初始化的第一个示例是有效的,但从 C11 开始,进行了以下更改

— 放宽了对聚合和联合初始化的约束

请注意,代码不会在 C++ 中编译,因为在 C++ 中字符串文字具有常量字符数组的类型。

因此,即使在 C 语言中,最好将结构声明为

struct entry {
   const char *lexptr;
   int token;  
};

评论

0赞 Jonathan Leffler 5/9/2023
在试行标准 C 中允许不带内括号的初始化。这不是您提到的宽松约束的特征。
0赞 Vlad from Moscow 5/9/2023
@JonathanLeffler我提供了 C11 Standard 的报价。也许这意味着其他什么,但我记得旧的编译器不允许这样的初始化。
0赞 Jonathan Leffler 5/9/2023
我想你记错了。但我们不需要进一步讨论它。
7赞 Ted Lyngmo 5/9/2023 #2

错误信息:
missing braces around initializer [-Werror=missing-braces]

事实上,这并不是一个真正的错误。这是一个警告,表明你已经通过编译器选项变成了一个错误。

您可以通过在应该填充的每对周围添加大括号来修复它:entry

struct entry keywords[] = {
    {"div", DIV},
    //...
};

但是,由于大括号省略,您的代码实际上是完全合法的......在 C 中。

对于 C++,不允许在字符串文字上提出要点。您需要将 的定义更改为:char*entry

struct entry {
    const char *lexptr;  // note: const char*
    int token;
};

有了这个,它在 C++ 中也是合法的:

entry keywords[] = {"div",   DIV,   "mod",  MOD,  "if", IF,
                    "while", WHILE, "then", THEN, "do", DO,
                    "begin", BEGIN, "end",  END,  0,    0};