调用函数地址存储在size_t的类型中? [英] Call function address stored in type of size_t?

查看:44
本文介绍了调用函数地址存储在size_t的类型中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,


我是C的新手,但我有多年的Common Lisp编程

经验。我正在试图找出将高阶

概念(如闭包)转换为C的方法。代码不会是惯用的C.


GCC有ISO C的扩展,允许嵌套函数:

< http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html>


为了实现闭包,它们有一个严重的限制:


如果在

包含函数退出后尝试通过其地址调用嵌套函数,地狱会破碎。如果你尝试

在一个包含的范围级别退出后调用它,并且如果它将

引用到一些不再在范围内的变量,你可能会很幸运,

但承担风险是不明智的。但是,如果嵌套函数

没有引用超出范围的任何东西,那么你应该是

安全。


我希望如果我堆分配所有已关闭的变量,我将会b / b模拟闭包。我知道有些人对这个扩展感到厌恶:

< http://groups.google.co.nz/groups?selm = 1V6uS-Id-23%40gated-at。 bofh.it>


在这个阶段,我的问题是基本的:我如何在下面的代码中完全破坏

松散?


#include< stdio.h>


size_t glfn1(){

int x = 1;

int inc(){

返回printf("%d \ n",x = x + 1);

}

return(size_t)& inc;

}


int main(){

size_t fn_address = glfn1() ;

/ *一切都会破裂* /

fn_address();

返回0;

}


我理解size_t是存储指针的理想类型,因为它可以在具有32位整数的64位平台上运行。
也适用于具有32位整数的64位平台。 />

如何让编译器接受函数inc的地址为

a函数类型? size_t类型的被调用对象不是函数类型。


问候,

Adam

Hello all,

I''m very new to C but I have a number of years of Common Lisp programming
experience. I''m trying to figure out ways of translating higher order
concepts such as closures into C. The code will not be idiomatic C.

GCC has an extension to ISO C that permits nested functions:
<http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html>

For implementing closures they have a serious limitation:

If you try to call the nested function through its address after the
containing function has exited, all hell will break loose. If you try
to call it after a containing scope level has exited, and if it refers
to some of the variables that are no longer in scope, you may be lucky,
but it''s not wise to take the risk. If, however, the nested function
does not refer to anything that has gone out of scope, you should be
safe.

I''m hopeful that if I heap allocate all closed over variables that I will
simulate closures. I''m aware of the distaste some have for the extension:
<http://groups.google.co.nz/groups?selm=1V6uS-Id-23%40gated-at.bofh.it>

At this stage my question is elementary: How do I make all hell break
loose in the code below?

#include <stdio.h>

size_t glfn1() {
int x=1;
int inc() {
return printf("%d\n",x=x+1);
}
return (size_t) &inc;
}

int main() {
size_t fn_address=glfn1();
/* All hell will break loose */
fn_address();
return 0;
}

I understand size_t is the ideal type for storing a pointer because it
will also work upon 64-bit platforms that have 32-bit ints.

How do I induce the compiler to accept the address of the function inc as
a function type? The called object of type size_t is not a function type.

Regards,
Adam

推荐答案

" Adam Warner" <我们**** @ consulting.net.nz>在消息中写道

news:pa **************************** @ consulting.net .nz .. 。
"Adam Warner" <us****@consulting.net.nz> wrote in message
news:pa****************************@consulting.net .nz...
大家好,

我是C的新手,但我有多年的Common Lisp编程经验。我正在试图找出将高阶概念(如闭包)转换为C的方法。代码不会是惯用的C.

GCC对ISO C进行了扩展,允许嵌套功能:
< http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html>


当然这个问题不在这里,在gcc论坛上提问。

为了实现闭包,他们有一个严重的限制:
包含函数退出后通过它的地址调用嵌套函数,那么所有的地狱都将破裂。如果你在一个包含的范围级别退出后尝试调用它,并且如果它引用了一些不再在范围内的变量,那么你可能很幸运,
但它'承担风险是不明智的。但是,如果嵌套函数没有引用超出范围的任何东西,那么你应该是安全的。

我希望如果我堆分配所有关闭的变量我将模拟闭包。我知道一些人对扩展的厌恶:
< http://groups.google.co.nz/groups?selm = 1V6uS-Id-23%40gated-at.bofh.it>


不,那不行。

你可以通过存储所有变量来模拟闭包的分配

by你的函数在一个结构中,并且引用结构成员而不是

全局标识符,但这不是你真正想要的,而且C ++将提供

的语法糖它对你更有吸引力(但对我们大多数人来说更令人讨厌)。

在这个阶段我的问题是基本的:我如何让所有地狱破灭
在下面的代码中松散?

#include< stdio.h>

size_t glfn1(){
int x = 1;
int inc ()返回printf("%d \ n",x = x + 1);
}
return(size_t)& inc;
}


easy:函数inc()增加堆栈相对于框架的位置

指针作为隐式参数传递。 gcc实现在进入glfn1()时会在堆栈上动态生成代码,其中包含一个寄存器

赋值给帧指针和跳转到glfn1的代码。这是
称为蹦床。 & inc确实指向glfn1

激活中的自动存储。 glfn1返回后取消引用这个指针可能会崩溃!

如果没有,谁知道inc()会改变什么位置?

int main(){
size_t fn_address = glfn1();
/ *所有地狱都会破碎* /
fn_address();
返回0;
}

我明白了size_t是存储指针的理想类型,因为它也适用于具有32位整数的64位平台。


这不是一个好的假设。 intptr_t是你指的类型,但

不能解决你的问题。

如何让编译器接受函数inc的地址为
Hello all,

I''m very new to C but I have a number of years of Common Lisp programming
experience. I''m trying to figure out ways of translating higher order
concepts such as closures into C. The code will not be idiomatic C.

GCC has an extension to ISO C that permits nested functions:
<http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html>
Of course this question is off topic here, ask on a gcc forum.
For implementing closures they have a serious limitation:

If you try to call the nested function through its address after the
containing function has exited, all hell will break loose. If you try
to call it after a containing scope level has exited, and if it refers
to some of the variables that are no longer in scope, you may be lucky,
but it''s not wise to take the risk. If, however, the nested function
does not refer to anything that has gone out of scope, you should be
safe.

I''m hopeful that if I heap allocate all closed over variables that I will
simulate closures. I''m aware of the distaste some have for the extension:
<http://groups.google.co.nz/groups?selm=1V6uS-Id-23%40gated-at.bofh.it>
No, that won''t work.
You can simulate closures with allocation by storing all variables referred to
by your function in a structure, and refer to structure members instead of
global identifiers, but that is not what you really want, and C++ will provide
the syntactical sugar to make it more appealing to you (but more distasteful to
most of us).
At this stage my question is elementary: How do I make all hell break
loose in the code below?

#include <stdio.h>

size_t glfn1() {
int x=1;
int inc() {
return printf("%d\n",x=x+1);
}
return (size_t) &inc;
}
easy: the function inc() increments a location on the stack relative to a frame
pointer passed as an implicit argument. The gcc implementation generates code
dynamically on the stack upon entering glfn1() consisting of a register
assignment to the frame pointer and a jump to the code for glfn1. This is
called a trampoline thunk. &inc points indeed to automatic storage in the glfn1
activation. dereferencing this pointer after glfn1 returns may well crash !
if not, who knowns what location will be changed by inc() ?
int main() {
size_t fn_address=glfn1();
/* All hell will break loose */
fn_address();
return 0;
}

I understand size_t is the ideal type for storing a pointer because it
will also work upon 64-bit platforms that have 32-bit ints.
This is not a good assumption. intptr_t is the type you are referring to, but
that will not solve your problem.
How do I induce the compiler to accept the address of the function inc as
a function type? The called object of type size_t is not a function type.



带有演员的



(*(size_t(* )())fn_address)();


但是再次,这不足以让你的关闭站起来。


-

Chqrlie。



with a cast:

(*(size_t(*)())fn_address)();

but again, this will not suffice for your closure to stand.

--
Chqrlie.


>我理解size_t是存储指针的理想类型,因为它
>I understand size_t is the ideal type for storing a pointer because it
也可以工作具有32位整数的64位平台。


为什么它可以用于存储FUNCTION指针?如果函数指针

占用的位数多于size_t,则表示您遇到问题。


数据指针代码指针MS-DOS型号名称有效吗?

16位16位小是

32位16位压缩?是的

16位32位中间?不!

32位32位大号是

64位32位非常棒是

32位64位巨大的NO!

64位64位intergalactic yes

如何让编译器接受函数inc的地址作为函数类型? size_t类型的被调用对象不是函数类型。
will also work upon 64-bit platforms that have 32-bit ints.
Why will it work for storing a FUNCTION pointer? If a function pointer
takes more bits than a size_t, you have trouble.

Data Pointer Code Pointer MS-DOS Model Name Works?
16 bits 16 bits small yes
32 bits 16 bits compact? yes
16 bits 32 bits middle? NO!
32 bits 32 bits large yes
64 bits 32 bits humongous yes
32 bits 64 bits gigantic NO!
64 bits 64 bits intergalactic yes
How do I induce the compiler to accept the address of the function inc as
a function type? The called object of type size_t is not a function type.




如果丑陋的转换或赋值给类型的变量

指向 - function-returning-crap不起作用,考虑memmove()

之间的size_t和这样的函数指针。如果你要去

无论如何调用未定义的行为,这可能不会让它更糟糕。


Gordon L. Burditt



If ugly casts or assignment to a variable of type
pointer-to-function-returning-crap don''t work, consider memmove()
between a size_t and such a function pointer. If you''re going to
invoke undefined behavior anyway, this probably won''t make it that
much worse.

Gordon L. Burditt


Adam Warner写道:
Adam Warner wrote:

我是C的新手,但我有一个号码多年的Common Lisp
编程经验。我正在试图找出将高阶概念(例如闭包)转换为C的方法。
代码不是惯用的C.

GCC对ISO的扩展C允许嵌套函数:
< http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html>

I''m very new to C but I have a number of years of Common Lisp
programming experience. I''m trying to figure out ways of
translating higher order concepts such as closures into C. The
code will not be idiomatic C.

GCC has an extension to ISO C that permits nested functions:
<http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html>




你不能嵌套函数采用ISO标准C(这里讨论的唯一形式

)。根据定义,任何非标准C都是非可移植的,并且在c.l.c上是非主题的。您可以通过适当的分解到文件中获得一些

效果,并且仍然有标准的

C.这样的讨论将是主题。


如果你真的想要嵌套函数,请使用ISO

标准支持的语言。 Pascal,Extended Pascal和Ada都来了




-

Chuck F(cb **** ****@yahoo.com)(cb********@worldnet.att.net)

可用于咨询/临时嵌入式和系统。

< http://cbfalconer.home.att.net>使用worldnet地址!



You cannot nest functions in ISO standard C (the only form
discussed here). Any non-standard C is, by definition,
non-portable and off-topic on c.l.c. You can get some of the
effects by suitable break-up into files, and still have standard
C. Such a discussion would be on-topic.

If you really want nested functions use a language whose ISO
standard supports them. Pascal, Extended Pascal, and Ada all come
to mind.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!


这篇关于调用函数地址存储在size_t的类型中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆