about functions

M

Martin Johansen

take the function:

char f(){
return(-1);
}

f is the function pointer, i know how it is used to call a function.

But, what exactly does the pointer point to?
Where is the return value stored?
Is it possible to get the code segment address, data segment address or the
size of the whole function in memory?

Thanks!
 
M

Martin Dickopp

Martin Johansen said:
take the function:

char f(){
return(-1);
}

f is the function pointer, i know how it is used to call a function.

But, what exactly does the pointer point to?

It points to the function, in some unspecified way, i.e. the C standard
does not specify how it points to the function.
Where is the return value stored?

That depends on the implementation. The C standard does not specify how
the return value is returned.
Is it possible to get the code segment address, data segment address
or the size of the whole function in memory?

No, not in standard C. A code segment and/or data segment need not even
exist.

If you are interested in how these things are implemented on your
particular system, please ask in group dedicated to that system.

Martin
 
D

Dan Pop

In said:
take the function:

char f(){
return(-1);
}

f is the function pointer, i know how it is used to call a function.

But, what exactly does the pointer point to?

It provides the necessary information for calling that function. When
this information doesn't fit into a pointer, it points to a place
containig this information. For example, on the IA64 architecture, two
64-bit addresses are needed for this purpose and a function pointer
actually points to a function descriptor that contains these addresses.
So, it takes a double indirection to dereference a function pointer on
that platform.
Where is the return value stored?

That's entirely irrelevant to function pointers. Return values are
typically stored in registers, these days.
Is it possible to get the code segment address, data segment address or the
size of the whole function in memory?

On common implementations, function pointers store the function's entry
address in the text segment. The function itself "knows" the addresses
of the objects it has to manipulate. However, there are exceptions from
this simple and common model, AS/400 being even more exotic than IA64:
function pointers are 768-bit (or so) entities on this platform.

Dan
 
T

Thomas Matthews

Martin said:
take the function:

char f(){
return(-1);
}

f is the function pointer, i know how it is used to call a function.

As others have stated, f is not the function pointer. "f" reprents the
location of a function. The compiler may not use any pointers to the
function at all. Depends on the implementation. It is conceivable that
the address of the function is pushed on the stack, then "popped" into
the program counter (or ip -- instruction pointer).

But, what exactly does the pointer point to?

A function pointer is:
char (*Pointer_To_f)();
The above line declares a pointer to any kind of function that
has the same signature as your 'f' function.

One can take the location of the 'f' function and place it into
a pointer:
typedef char (*Pointer_To_f)();
Pointer_To_f p_f;
p_f = f;
Where is the return value stored?
The return value does not have to be stored.
A compiler could optimize this function and just assign the
calling variable to "-1".

Some implementations give you the freedom to place constant
data wherever you want to. Sometimes the constant data is
placed in the same region that the executable is, sometimes
not. Depends on the compiler and the implementation.

Is it possible to get the code segment address, data segment address or the
size of the whole function in memory?
I've already asked this group if the size of a function
could be determined using only portable C, but they
said no. Other platform dependent tricks must be used
to determine the size of a function.

As far as the starting location, yes it can be obtained
using C. However, the C language has no concepts of code
segments or data segments. That is an implementation issue.


--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
M

Martin Dickopp

Thomas Matthews said:
As others have stated, f is not the function pointer.

`f' is a function designator, but except when it is the operand of the
`sizeof' or unary & operator, it is converted to a function pointer.

Martin
 
A

Andrey Tarasevich

Martin said:
take the function:

char f(){
return(-1);
}

f is the function pointer, i know how it is used to call a function.

'f' is _not_ a pointer. When used in an expression, 'f' is an lvalue of
function type. That's quite different from a pointer.
But, what exactly does the pointer point to?

Not applicable. There's no pointer here.
Where is the return value stored?

You mean between the moment of 'return' and the moment it gets into the
variable you provided when calling the function? It is stored
"somewhere". Every implementation might do it differently.
Is it possible to get the code segment address, data segment address or the
size of the whole function in memory?

In general case - no.
 
M

Martin Dickopp

Andrey Tarasevich said:
'f' is _not_ a pointer. When used in an expression, 'f' is an lvalue of
function type. That's quite different from a pointer.

When used in an expression, `f' *is* a pointer, unless it is the operand
of a `sizeof' or unary & operator. See 6.3.2.1#4.

Martin
 
J

Jack Klein

When used in an expression, `f' *is* a pointer, unless it is the operand
of a `sizeof' or unary & operator. See 6.3.2.1#4.

Martin

Why is it that you got this right in your answer to Thomas a few hours
earlier, but wrong here?

'f' is a function designator and has function type. First, last, and
always. It is never a pointer, any more than the name of an array is
a pointer. No matter what expression it is used in.

In most expressions, in fact all but the two you mentioned above, the
implementation evaluates the function designator to extract its
address, and extraction of an address always results in an rvalue of
pointer type.

But 'f' never becomes a pointer, just as in:

int func(int *);

int array [10];

func(array);

....'array' never becomes a pointer. A pointer rvalue is created by
extracting the address of a[0], and that rvalue is passed to 'func'.
'array' itself never becomes a pointer, in fact cannot become anything
other than what it is, i.e., a non-modifiable lvalue with the type
pointer to array of 10 ints.

Likewise, passing 'f' to a function that accepts a pointer to function
creates an rvalue of type pointer to function by extracting the
address of 'f'. 'f' itself is unchanged, and cannot ever be anything
other than a function designator having function type, as is clearly
quoted in the first sentence of the paragraph you cite from the
standard.
 
M

Martin Dickopp

Jack Klein said:
Why is it that you got this right in your answer to Thomas a few hours
earlier, but wrong here?

Temporary brain hiccup. I should have written: When used in an
expression, `f' has pointer type, unless [...].

(Incidentally, this wouldn't have happend if I had adhered to my own
advice to never use words which can be an adjective with "object" and
"type" as nouns.)

Martin
 
J

James Kanze

(e-mail address removed) (Dan Pop) writes:

|> In <[email protected]> "Martin Johansen"

|> >take the function:

|> >char f(){
|> > return(-1);
|> >}

|> >f is the function pointer, i know how it is used to call a function.

|> >But, what exactly does the pointer point to?

|> It provides the necessary information for calling that function.
|> When this information doesn't fit into a pointer, it points to a
|> place containig this information.

Since the implementation decides just how big a function pointer is, it
can always make it big enough for whatever information is necessary.

|> For example, on the IA64 architecture, two 64-bit addresses are
|> needed for this purpose and a function pointer actually points to a
|> function descriptor that contains these addresses. So, it takes a
|> double indirection to dereference a function pointer on that
|> platform.

A much simpler solution would simply be to make a function pointer twice
as big.

I suspect here that the reason has nothing to do with C, but with the
broken interface which Posix imposes on dlsym (and maybe other
functions).

|> >Where is the return value stored?

|> That's entirely irrelevant to function pointers. Return values are
|> typically stored in registers, these days.

More often, it depends on the type being returned. Different types can
be, and usually are, returned in different ways.

|> >Is it possible to get the code segment address, data segment
|> >address or the size of the whole function in memory?

|> On common implementations, function pointers store the function's
|> entry address in the text segment.

On a lot of implementations, segments are just an artifice of the
compiler/loader anyway. At the hardware level, either there is no such
thing as a segment, or the OS and compiler work together to make it seem
that way (even when it means artificially limiting the capacities of the
processor, as is the case with IA-32 architectures). Actual addressing
is linear, so code segment address and data segment address have no real
meaning.

|> The function itself "knows" the addresses of the objects it has to
|> manipulate. However, there are exceptions from this simple and
|> common model, AS/400 being even more exotic than IA64: function
|> pointers are 768-bit (or so) entities on this platform.
 
A

Andrey Tarasevich

Martin said:
Why is it that you got this right in your answer to Thomas a few hours
earlier, but wrong here?

Temporary brain hiccup. I should have written: When used in an
expression, `f' has pointer type, unless [...].
...

Sorry, but that's still incorrect. The words "is" and "has" do not have
that meaning in formal C lingo. I can only suggest that you take a
closer look at 6.3.2.1/4 yourself. It states clearly that _the_ _result_
_of_ _the_ _implicit_ _conversion_ applied to expression 'f' has
"pointer to function" type, not 'f' itself. Once again, the implicit
conversion is applied to the result of expression 'f'. But 'f' itself
has function type, not pointer type.

Best regards,
Andrey Tarasevich
 
D

Dan Pop

In said:
(e-mail address removed) (Dan Pop) writes:

|> In <[email protected]> "Martin Johansen"

|> >take the function:

|> >char f(){
|> > return(-1);
|> >}

|> >f is the function pointer, i know how it is used to call a function.

|> >But, what exactly does the pointer point to?

|> It provides the necessary information for calling that function.
|> When this information doesn't fit into a pointer, it points to a
|> place containig this information.

Since the implementation decides just how big a function pointer is, it
can always make it big enough for whatever information is necessary.

Unless it has excellent reasons for not doing so.
|> For example, on the IA64 architecture, two 64-bit addresses are
|> needed for this purpose and a function pointer actually points to a
|> function descriptor that contains these addresses. So, it takes a
|> double indirection to dereference a function pointer on that
|> platform.

A much simpler solution would simply be to make a function pointer twice
as big.

Also a much slower solution, for programs dealing with a lot of such
pointers (as in large arrays of pointers to functions).
I suspect here that the reason has nothing to do with C, but with the
broken interface which Posix imposes on dlsym (and maybe other
functions).

The ultimate reason is that this is what the ABI requires.
|> >Where is the return value stored?

|> That's entirely irrelevant to function pointers. Return values are
|> typically stored in registers, these days.

More often, it depends on the type being returned. Different types can
be, and usually are, returned in different ways.

|> >Is it possible to get the code segment address, data segment
|> >address or the size of the whole function in memory?

|> On common implementations, function pointers store the function's
|> entry address in the text segment.

On a lot of implementations, segments are just an artifice of the
compiler/loader anyway.

And on some others, they aren't.
At the hardware level, either there is no such
thing as a segment, or the OS and compiler work together to make it seem
that way (even when it means artificially limiting the capacities of the
processor, as is the case with IA-32 architectures). Actual addressing
is linear, so code segment address and data segment address have no real
meaning.

Trivially false on *any* Harvard architecture, the high end PDP-11s
included. All the world's not a von Neumann architecture...

Dan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,183
Messages
2,570,977
Members
47,556
Latest member
the lucky frog

Latest Threads

Top