为什么用C语言警告并且无法在C ++中编译?
-
10-07-2019 - |
题
为什么这段代码
int (*g)(int);
int (*h)(char);
h = g;
在C中,编译时给我这样的警告:
'警告:从不兼容的指针类型'
分配在C ++中,无法编译。
解决方案
原型不匹配。 g
是一个指向函数的指针,该函数接受int
并返回h
而char
是一个指向函数的指针,该函数接受<=>并返回<=>。它们是两种不同的类型,因此是警告(将苹果分配给橙子)。
其他提示
两个函数指针没有相同的签名,因为输入参数不同。
函数指针都返回 int ,而 g 接受 int 作为输入, h 接受 char 作为输入参数。
虽然你有时可以混合使用 int 和 char ,但是你正在混合函数指针,所以编译器正确地给你一个警告,告诉你可能做错了。
示例代码:
#include <stdio.h>
int gf(int n)
{
return printf("gf(%d)\n", n);
}
int hf(char c)
{
return printf("hf('%c')\n", c);
}
int main()
{
int (*g)(int) = gf; // pointer to gf
int (*h)(char) = hf; // pointer to hf
g = h; // warning: possibly incompatible functions
g(65); // cast 65 to char and call h
return 0;
}
编译:
$ gcc-4.exe -Wall a.c
a.c: In function 'main':
a.c:18: warning: assignment from incompatible pointer type
正在运行程序:
$ ./a.exe
hf('A')
如您所见,在C中,它运行良好,但编译器会给您一个适当的警告。如果我们尝试将其编译为C ++代码,编译器将不会接受我们的指针juggling:
$ g++-4.exe a.c
a.c: In function 'int main()':
a.c:18: error: invalid conversion from 'int (*)(char)' to 'int (*)(int)'
声明一个函数接受int
,另一个接受char
的函数。这些是不同的签名,因此指针是不兼容的。
你已经声明g是一个函数,它接受一个int类型的参数并返回一个int,而h是一个函数,它接受一个char类型的参数并返回一个int结果。这两个函数签名不可互换,因此您无法将指针指向一个指针指向另一个指针。
您已将g和h声明为函数。实际上,我的编译器给出了错误<!> quot; lvalue作为赋值<!>“的左操作数所必需的,并且看起来很奇怪你可以只用一个警告来编译这段代码吗?
编辑:最初,问题中的代码将g和h声明为函数。现在它们已被更改为函数指针,这确实只会发出警告。
因为您要分配不兼容的指针。一个函数指针将带符号的整数作为参数,另一个char(签名取决于您的系统)。虽然两者都返回相同,但它们完全不同。
忽略警告,使用函数指针(在转换时使其实际编译),你会看到我的意思:))
由于功能签名不同,这不是合法的C或合法的C ++。问题是为什么编译器会以不同的方式对待它。在两种标准中都没有关于如何处理违反标准的程序的指导,除了某些违规需要诊断(并且这两种情况都提供诊断消息)。标准通常涉及有效的C或C ++程序,以及在给定的程序时必须执行的操作。
C语言是一种比C ++更古老的语言,而且很多C代码都是用比现在更少的编译器编写的。 C ++从一开始就更加严格,因此预标准C ++代码往往是有效的标准C ++代码,只是不使用某些特性。
由于这个原因,假设编译器是为实际使用而编写的,C编译器比C ++编译器更宽松。毕竟,有很多C代码巧妙地假设这样的工作,其中一些是非常有用的,但C ++也是如此。
我可以补充的是,C中的函数匹配与C ++中的函数匹配是不同的。在C中,您只使用名称(因此参数重载不可行)。在C ++中,每个函数都有一个不同的<!>“签名<!>”,由params组成。 (他们必须实现参数重载。)。