澄清在C函数指针 [英] Clarification on function pointers in C
问题描述
以下code来自例如 abo3.c从 不安全的编程 - 也见的为什么投的extern看跌
一个函数指针(无效(*)(字符*))及看跌
?:
INT主(INT的argv,焦炭**的argc){
EXTERN系统,看跌期权;
无效(* FN)(字符*)=(无效(*)(字符*))及系统; //< ==
焦炭BUF [256];
FN =(无效(*)(字符*))及看跌期权;
的strcpy(buf中,的argc [1]);
FN(的argc [2]);
出口(1);
}
特别是这一行:
无效(* FN)(字符*)=(无效(*)(字符*))及系统;
我觉得无效(* FN)(字符*)
听起来像是一个lambda,但我知道,这不是。
然后,也许这仅仅是带括号,其中无效* FN(字符*)
是函数的声明一出戏,这功能是引用系统
?但为什么在(字符*
)的参数没有名字?这是允许的?
无效(* FN)(字符*)=(无效(*)(字符*))及系统;
这行采取了错误声明符号的地址系统
(应 INT(为const char *)
,不隐 INT
),它施放到 FN
类型并初始化新的局部变量。结果
该类型是无效(*)(字符*)
或函数指针接收一个的char *
和返回什么。
-
前两个参数的传统命名为
主
颠倒:INT主(INT的argv,焦炭**的argc)
-
声明
系统
和看跌
使用隐式int标准库函数为INT
秒。这甚至不是错误的函数式,而是一种数据类型!的extern系统,提出;
-
铸造符号解决一个函数指针几乎是理智的。现在,只要它是正确的类型...无论如何,与数据指针和code三分球是同样大小的盒子,它的可能的不会丢失任何信息。
无效(* FN)(字符*)=(无效(*)(字符*))及系统; //< ==
FN =(无效(*)(字符*))及看跌期权; -
检查是否
的argv
至少2应该真正的不的从略[!]:的strcpy(BUF,ARGC [1]);
-
通过调用错误类型的函数指针的函数为UB。不要那样做。此外,检查是否
的argv
[!]至少为3之前这一点的不的可选的。
FN(ARGC [2]); -
这是隐式声明为依托
的strcpy
和退出
也非常糟糕。无论是具有与一致的原型! (他们不返回INT
)
The following code comes from example abo3.c from Insecure Programming — see also Why cast extern puts
to a function pointer (void(*)(char*))&puts
?:
int main(int argv,char **argc) {
extern system,puts;
void (*fn)(char*)=(void(*)(char*))&system; // <==
char buf[256];
fn=(void(*)(char*))&puts;
strcpy(buf,argc[1]);
fn(argc[2]);
exit(1);
}
Specifically this line:
void (*fn)(char*)=(void(*)(char*))&system;
I think that void (*fn)(char*)
sounds like a lambda, but I know that it's not.
Then, maybe this is only a play with parentheses, where void *fn(char*)
is a declaration of a function and this function is referencing system
? But why does the (char*
) parameter have no name? Is this permitted?
void (*fn)(char*)=(void(*)(char*))&system;
That line takes the address of the mis-declared symbol system
(should be int(const char*)
, not implicit int
), casts it to the type of fn
and initializes that new local variable.
The type is void(*)(char*)
or pointer to function receiving a single char*
and returning nothing.
Well, that code is all kinds of bad:
The traditional naming of the first two arguments to
main
is reversed:int main(int argv,char **argc)
Declaring the standard-library-functions
system
andputs
using "implicit int" asint
s. That's not even the wrong function-type, but a data-type!extern system,puts;
Casting the symbols address to a function-pointer is nearly sane. Now if only it was the right type... Anyway, on a box with data-pointers and code-pointers being the same size, it probably doesn't loose any information.
void (*fn)(char*)=(void(*)(char*))&system; // <== fn=(void(*)(char*))&puts;
Checking whether
argv
[!] is at least 2 should really not be omitted here:strcpy(buf,argc[1]);
Calling a function through a function-pointer of wrong type is UB. Don't do that. Also, checking whether
argv
[!] is at least 3 before this point is not optional. fn(argc[2]);Relying on implicit declaration for
strcpy
andexit
is also really bad. Neither has a prototype consistent with that! (they don't returnint
)
这篇关于澄清在C函数指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!