简体   繁体   English

为什么在C语言中发出警告而在C ++中不能编译?

[英]Why warning in C and can't compile in C++?

Why does this code 为什么这样的代码

int (*g)(int);
int (*h)(char);
h = g;

In C, give me such warning when compiling: 在C中,在编译时给我这样的警告:

'warning: assignment from incompatible pointer type' “警告:来自不兼容指针类型的赋值”

In C++, can't be able to compile. 在C ++中,无法编译。

Prototypes don't match. 原型不匹配。 g is a pointer to a function which takes an int and returns an int whereas h is a pointer to a function which takes a char and returns an int . g是指向采用int并返回int的函数的指针,而h是指向采用char并返回int的函数的指针。 They are two separate types and hence the warning (assigning apples to oranges). 它们是两种不同的类型,因此是警告(将苹果分配给橙子)。

The two functions pointers do not have the same signature, since the input parameters are different. 由于输入参数不同,因此两个函数指针没有相同的签名。

The function pointers both return an int , while g accepts an int as input, and h accepts a char as input parameters. 函数指针都返回一个int ,而g接受一个int作为输入, h接受一个char作为输入参数。

Although you can sometimes mix int and char , you are mixing function pointers, so the compiler correctly gives you a warning that you might be doing something wrong. 尽管有时可以混合使用intchar ,但是您可以混合使用函数指针,因此编译器会正确地警告您可能做错了事。

Example code: 示例代码:

#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;
}

Compiling: 编译:

$ gcc-4.exe -Wall a.c
a.c: In function 'main':
a.c:18: warning: assignment from incompatible pointer type

Running program: 运行程序:

$ ./a.exe
hf('A')

As you see, in C, it works nicely, but the compiler gives you a proper warning. 如您所见,在C语言中,它可以很好地工作,但是编译器会向您发出适当的警告。 If we try to compile this as C++ code, the compiler won't accept our pointer juggling: 如果我们尝试将其编译为C ++代码,则编译器不会接受我们的指针处理:

$ g++-4.exe a.c
a.c: In function 'int main()':
a.c:18: error: invalid conversion from 'int (*)(char)' to 'int (*)(int)'

One is declared to point to a function accepting an int , the other one - to a function accepting a char . 一个声明为指向接受int的函数,另一个声明为指向接受char的函数。 Those are different signatures, so the pointers are incompatible. 这些是不同的签名,因此指针不兼容。

You've declared g to be a function taking one argument of type int and returning an int, and h to be a function taking one argument of type char and returning an int result. 您已经将g声明为一个接受一个类型为int的参数并返回int的函数,将h声明为一个接受一个类型为char的参数并返回一个int结果的函数。 The two function signatures are not interchangeable and so you can't assign from a pointer to one to a pointer to the other. 这两个函数签名不可互换,因此您不能从一个指向一个的指针分配给另一个指向的指针。

You have declared g and h as functions. 您已将g和h声明为函数。 Actually, my compiler gives the error "lvalue required as left operand of assignment", and it seems strange that you could get this code to compile with just a warning? 实际上,我的编译器给出了错误“需要左值作为赋值的左操作数”,并且您可以仅通过警告就可以编译此代码,这似乎很奇怪?

EDIT: Originally, the code in the question declared g and h as functions. 编辑:最初,问题中的代码将g和h声明为函数。 Now they have been changed to function pointers, which will indeed just give a warning. 现在,它们已更改为函数指针,实际上确实会发出警告。

Because you are assigning incompatible pointers. 因为您正在分配不兼容的指针。 One function pointer takes a signed integer as an argument, the other char (signedness depends on your system). 一个函数指针将一个带符号的整数作为参数,另一个字符(带符号取决于您的系统)。 Even though both return the same, they are quite different. 即使两者返回的结果相同,它们也有很大不同。

Ignore the warnings, use the function pointers (while casting to make it actually compile) and you'll see what I mean :) 忽略警告,使用函数指针(同时进行强制转换以使其实际编译),您将明白我的意思:)

Since the function signatures are different, this isn't legal C or legal C++. 由于函数签名不同,因此不是合法的C或合法的C ++。 The question is why the compilers treat it differently. 问题是为什么编译器将其区别对待。 In neither standard is there much guidance on what to do with programs that violate the standard, except that certain violations require a diagnostic (and both of these cases do supply a diagnostic message). 在这两个标准中,都没有关于如何处理违反该标准的程序的大量指南,只是某些违例需要诊断(并且这两种情况均提供了诊断消息)。 The standards are normally concerned with what a valid C or C++ program is, and what the implementation has to do when given one. 这些标准通常与有效的C或C ++程序有关,以及实现时必须执行的操作。

C is a considerably older language than C++, and a whole lot of C code was written on much less strict compilers than exist nowadays. C是比C ++更为古老的语言,并且许多C代码是用比当今更不严格的编译器编写的。 C++ was stricter from the start, and so pre-standard C++ code tends to be valid standard C++ code that just doesn't use certain features. C ++从一开始就更加严格,因此预标准C ++代码往往是有效的标准C ++代码,只是不使用某些功能。

For this reason, a C compiler is more likely to be lenient than a C++ compiler, assuming the compilers were written for practical use. 因此,假定C编译器是为实际用途而编写的,则C编译器比C ++编译器更宽容。 After all, there's a lot of C code that blithely assumes things like this work, and some of that is very useful, but the same is not true of C++. 毕竟,有很多C代码巧妙地假定了这项工作,其中有些非常有用,但C ++却并非如此。

What i may add, is that function matching in C is different than in C++. 我可能要补充的是,C语言中的函数匹配与C ++中的函数匹配不同。 In C you use only the name (thus parameter overloading is not feasible). 在C语言中,仅使用名称(因此参数重载是不可行的)。 In C++ each function has a different "signature", made up off the params. 在C ++中,每个函数都有一个不同的“签名”,由参数组成。 (They had to realize parameter overloading.). (他们必须实现参数重载。)。

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

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