我有以下代码:
struct something {
char *(*choices)[2];
};
char* arr[2] = {"foo", "bar"};
int main(void) {
struct something obj;
obj.choices = &arr;
return 0;
}
当我使用普通的C编译器(gcc)进行编译时,没有任何错误。但是,我正在为Z80进行编译,它会引发一个ERROR (152) Operands are not assignment compatible
,它被描述为:
试图将不能将其类型提升为目的地类型的值。
我无法理解&arr
和char *(*choices)[2]
的类型如何不同。我该怎么做才能解决此问题?
(我使用的是Zilog z80编译器,它是ZDS 5.2.0的一部分)
答案 0 :(得分:3)
这可能是某种奇怪的编译器错误。这段代码可以很好地编译:
struct something {
char *** choices;
};
char * arr[2] = {"foo", "bar"};
int main(void) {
struct something obj;
obj.choices = &arr;
return 0;
}
恐怕这是唯一与原始想法最兼容的解决方法。
答案 1 :(得分:0)
Zilog支持声称它实际上不是编译器错误,并且由于严格地不是ANSI C,所以原始代码无法编译。GCC接受了该代码,因为编译器“宽大”,并且添加了一些超出ANSI C规范的更多语法规则。这是完整的答复:
GCC编译器虽然很好,但不一定是完美的 C标准的实施。这些年来,我看到了一些 在广泛使用编译器(例如MSVC ++)的情况下, 当GCC接受的语法严格来说不是ANSI C 成为标准C的无害准扩展,并且没有危险 它以某种替代的合法含义来解释。这个 可能是另一个例子。
涉及C语法的要点,这是我的理解 关于这一点,以及为什么GCC可能允许客户 原始语法。一旦函数指针,例如正确定义 变量fnPtr,已经获取了一个定义,可以调用它 通过表达式没有前面的*间接运算符 喜欢
result = fnPtr(x); // This is legal syntax…
result = (*fnPtr) (x); // … even though this is “more correct”
之所以允许使用上面显示的第一种语法,是因为 包含参数x的括号被视为C运算符,其 类型是“功能指针”。所以那些括号的存在 函数指针使不必要的间接操作符 实际上用于进行函数调用。但是,在类似的情况下 此客户代码,您只在其中使用函数指针 作业说明,这不会起作用,所以那些 实际上,操作数并不严格兼容分配。但是, 不是专家语言争吵者的用户几乎不会被指责为 期望如果没有使用*可以使用函数指针 一个地方,在其他情况下也应该可以接受。这有可能 这就是为什么GCC开发人员显然决定接受用户的 语法。
这里是编译的替代版本:
struct something {
char *(*choices[2]);
};
char* arr[2] = {"foo", "bar"};
int main(void) {
struct something obj;
*obj.choices = &arr;
return 0;
}