提问人:Faris 提问时间:5/9/2023 最后编辑:Jonathan LefflerFaris 更新时间:5/9/2023 访问量:210
为什么在没有语法错误的情况下不编译此代码?[关闭]
Why doesn't this code compile while there is no syntax error? [closed]
问:
我的代码中有一个问题,需要很长时间才能尝试修复它
- 错误信息:
初始值设定项周围缺少大括号 [-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 有一个异常,但是在我的情况下如何解决它?
我认为这是一个很小的变化,但我没有得到它。
答:
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};
评论
"div", DIV,
那应该是,不是吗?{"div", DIV},