A function is an address

  • Thread starter Julienne Walker
  • Start date
J

Julienne Walker

Ignoring implementation details and strictly following the C99
standard in terms of semantics, is there anything fundamentally flawed
with describing the use of a (non-inline) function as an address[1]? I
keep feeling like I'm missing something obvious.


-Jul

[1] To keep things in context, this is in reference to describing
functions to a beginner.
 
E

Eric Sosman

Julienne said:
Ignoring implementation details and strictly following the C99
standard in terms of semantics, is there anything fundamentally flawed
with describing the use of a (non-inline) function as an address[1]? I
keep feeling like I'm missing something obvious.

It would probably be better to describe a function as
a custard pie.
-Jul

[1] To keep things in context, this is in reference to describing
functions to a beginner.

Oh, a beginner? In that case, "custard pie" is by far
the best way to introduce the topic. Later, when the pupil
has gained some understanding and experience, you can go
back and explain that "custard pie" is really a simplification;
in full generality a function can be any kind of dessert or
comedic prop whatsoever.

(In other words, have you taken leave of your senses,
or have they taken leave of you? Or are you a disciple of
Humpty Dumpty, determined to make words mean whatever you
want them to and without regard to what others may think
they mean?)
 
J

jameskuyper

Julienne said:
Ignoring implementation details and strictly following the C99
standard in terms of semantics, is there anything fundamentally flawed
with describing the use of a (non-inline) function as an address[1]? I
keep feeling like I'm missing something obvious.

A function typically has an associated memory address indicating the
entry point for the function. A function is not an address, any more
than your house is an address.
 
C

Chris Torek

Ignoring implementation details and strictly following the C99
standard in terms of semantics, is there anything fundamentally flawed
with describing the use of a (non-inline) function as an address[1]? ...
[1] To keep things in context, this is in reference to describing
functions to a beginner.

I think the biggest problem with that is that it will just confuse
the beginner.

A (non-inline) function is, after all, compiled to a bunch of
executable instructions, on most of today's machines with most
of today's compilers. Those instructions eventually wind up
with "code-space addresses", but you get more than just *an*
address, you get a whole range of addresses. It makes more sense,
I think, to say that the function itself occupies that entire
range. Of cours, after declaring "void f(void);", the line:

sizeof f

produces a compile-time error, but this is due to the language
decreeing that no C compiler has to be able to divine the eventual
final size of a function at the point that the "sizeof" occurs.
(This is natural enough, since the function may not even have been
compiled yet. Of course, there are ways to deal with this, by
making "sizeof f" be a link-time constant instead of a compile-time
constant, but the language does not require that.)

The language specifies that, once you have declared that a some
identifier refers to a function, simply naming the function (without
actually calling it) normally produces a pointer to that function.
This pointer is a form of "address value", and the address you get
on real machines is, in general, the address of the first instruction
-- or the first byte of the first instrution -- of the function.
(Even this is not guaranteed. On the VAX, for instance, the first
*executable* byte of the function is two bytes *after* the start
of the function. Functions begin with a two-byte "register save
mask" word. The function pointer points to this word. On other
machines, a function pointer may point to a "function descriptor",
rather than to the actual code for the function. Descriptors may
be collected together at compile and/or link time, or may simply
precede each function.)

Ultimately, the C beginner -- in order to become a non-beginner --
has to grasp the idea that the C language "likes to" take something
that covers a large range of machine addresses, like an array or
a function, and "squish it down" to a pointer to the *start* of
that large range. This is the origin of the idea of the "decay"
of an array or function name, which both *usually* turn into a
pointer value, pointing to the "start" of the larger entity. But
this "decay" is suppressed in particular cases, such as using
the "sizeof" operator.
 
K

Keith Thompson

Julienne Walker said:
Ignoring implementation details and strictly following the C99
standard in terms of semantics, is there anything fundamentally flawed
with describing the use of a (non-inline) function as an address[1]? I
keep feeling like I'm missing something obvious.

[1] To keep things in context, this is in reference to describing
functions to a beginner.

I can't think of anything *not* fundamentally flawed about describing
the use of a function as an address.

I suspect what you're thinking of is the fact that an expression of
function type (including the name of a function) is, unless it's the
operand of a unary "sizeof" or "&" operator, implicitly converted to
the function's address, and the first operand of a function call
operator is actually a pointer-to-function, not necessarily a
function. I'm sure this is covered in the FAQ.

But this does not imply that a function *is* an address (it isn't),
and it's not necessarily something I'd mention to beginners.

Until a beginner starts to use function pointers explicitly, it
probably sufices to say that a function call func(arg1, arg2) calls
the specified function and passes it the specified arguments. The
fact that there's a conversion to a function pointer happening behind
the scenes can probably wait until later.
 
J

Julienne Walker

Julienne Walker said:
Ignoring implementation details and strictly following the C99
standard in terms of semantics, is there anything fundamentally flawed
with describing the use of a (non-inline) function as an address[1]? ...
[1] To keep things in context, this is in reference to describing
functions to a beginner.

I think the biggest problem with that is that it will just confuse
the beginner.

I think my provocative thread title may have confused everyone. ;-) I
have no intention of saying "A function is an address" and leaving it
at that. That would be stupid, and completely pointless when one is
trying to teach C. Rather, I was intending to use the concept of a
function identifier resolving to an address when used as a way to
avoid confusion long enough to get started. But in avoiding confusion
I also don't want to be thoroughly incorrect according to the
standard.

Naturally I wouldn't dream of suggesting that the whole function is a
single address, as replies so far seem to have misinterpreted despite
my careful wording of the actual post. In fact, that would defeat the
purpose.

So please allow me to refine my question: In what cases would the use
of a function name *not* evaluate to a pointer to that function?
 
C

Charlton Wilbur

JW> So please allow me to refine my question: In what cases would
JW> the use of a function name *not* evaluate to a pointer to that
JW> function?

Why does a beginner care?

Have you ever tried to teach programming before? This is a concept
that beginners simply do not need to worry about, and making the
beginners worry about it when you introduce functions is a damn fine
way to confuse them.

Charlton
 
K

Keith Thompson

Julienne Walker said:
So please allow me to refine my question: In what cases would the use
of a function name *not* evaluate to a pointer to that function?

When it's the operand of a unary "sizeof" operator (which is a
constraint error, rather than yielding the size of a function
pointer), and when it's the operand of a unary "&" operator (which
yields the address of the function, rather than attempting to compute
the address of the address of the function, which would be a
constraint violation).

Note that this applies to any expression of function type, not just a
function name. For example, if ``p'' is an object of
pointer-to-function type, then ``*p'' is an expression of function
type, which then decays (back) to a pointer to the function.

It's quite similar to the hanlding of array names.
 
J

jameskuyper

Julienne said:
Julienne Walker said:
Ignoring implementation details and strictly following the C99
standard in terms of semantics, is there anything fundamentally flawed
with describing the use of a (non-inline) function as an address[1]? ...
[1] To keep things in context, this is in reference to describing
functions to a beginner.

I think the biggest problem with that is that it will just confuse
the beginner.

I think my provocative thread title may have confused everyone. ;-) I
have no intention of saying "A function is an address" and leaving it
at that. That would be stupid, and completely pointless when one is
trying to teach C. Rather, I was intending to use the concept of a
function identifier resolving to an address when used as a way to
avoid confusion long enough to get started. But in avoiding confusion
I also don't want to be thoroughly incorrect according to the
standard.

Naturally I wouldn't dream of suggesting that the whole function is a
single address, as replies so far seem to have misinterpreted despite
my careful wording of the actual post. In fact, that would defeat the
purpose.

I'm sorry, but I don't follow that. Looking back over you previous
message, and knowing now what it was that you actually meant, I can't
find a single word that contradicts my original reading of your
message: that you intended to teach students that a function is an
address. The correct statement is that a function name decays into a
function pointer in virtually all contexts. Your way of saying it is
incorrect because:

A function name names a function, it is not the same thing as the
function itself. A function pointer will typically contain an address,
but a function pointer is not an address. A function name will decay
into a function pointer in almost every context, but a function name
is not a function pointer.
So please allow me to refine my question: In what cases would the use
of a function name *not* evaluate to a pointer to that function?

The only cases where it does not happen are as an operand to sizeof,
where it's a constraint violation, or as the operand of a unary '&'
operator, in which case it is the result of the expression that is a
pointer, rather than the function name itself.
 
J

Julienne Walker

[SNIP]
So please allow me to refine my question: In what cases would the use
of a function name *not* evaluate to a pointer to that function?

When it's the operand of a unary "sizeof" operator (which is a
constraint error, rather than yielding the size of a function
pointer), and when it's the operand of a unary "&" operator (which
yields the address of the function, rather than attempting to compute
the address of the address of the function, which would be a
constraint violation).

Note that this applies to any expression of function type, not just a
function name. For example, if ``p'' is an object of
pointer-to-function type, then ``*p'' is an expression of function
type, which then decays (back) to a pointer to the function.

It's quite similar to the hanlding of array names.

--
Keith Thompson (The_Other_Keith) <[email protected]>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Thank you. That's what I thought, but a worry kept tickling the back
of my brain that there was something else.


-Jul
 
K

Keith Thompson

A function name names a function, it is not the same thing as the
function itself. A function pointer will typically contain an address,
but a function pointer is not an address. A function name will decay
into a function pointer in almost every context, but a function name
is not a function pointer.
[...]

Actually, a function pointer *is* an address; it's the address of the
function. (The standard uses the words "address" and "pointer" almost
interchangeably.)
 
J

Julienne Walker

JW> So please allow me to refine my question: In what cases would
JW> the use of a function name *not* evaluate to a pointer to that
JW> function?

Why does a beginner care?

A beginner doesn't care about this exact detail, but I'm intending to
use it to smooth the entire process of learning C. Rest assured that
I'm not going to tell a beginner something like that without a plan.
Have you ever tried to teach programming before?
Yes.

This is a concept
that beginners simply do not need to worry about, and making the
beginners worry about it when you introduce functions is a damn fine
way to confuse them.

I appreciate your concern, but I don't think you're in a position to
make that judgment given nothing more than a quick question from me to
the experts on clc.
 
J

Julienne Walker

Looking back over you previous
message, and knowing now what it was that you actually meant, I can't
find a single word that contradicts my original reading of your
message: that you intended to teach students that a function is an
address.

I'm sorry you didn't read the message in the way that it was intended,
but with the exception of the misleading thread title, I disagree with
you thoroughly. However, I doubt anything I say from now on will
change your mind, so thank you for your time.


-Jul
 
J

jameskuyper

Keith said:
A function name names a function, it is not the same thing as the
function itself. A function pointer will typically contain an address,
but a function pointer is not an address. A function name will decay
into a function pointer in almost every context, but a function name
is not a function pointer.
[...]

Actually, a function pointer *is* an address; it's the address of the
function. (The standard uses the words "address" and "pointer" almost
interchangeably.)

I think that, to the extent that the standard does so, it is
defective. Treating the two terms as interchangeable would, if
normative, prohibit the implementation of pointers as structures which
contain, among other things, the address of the location in memory
that they point at. I doubt that it was the intent of the committee to
prohibit such fat-pointer implementations.

Cross-posting to comp.std.c
 
E

Eric Sosman

Julienne said:
[...]
So please allow me to refine my question: In what cases would the use
of a function name *not* evaluate to a pointer to that function?

Keith Thompson mentioned the curious case of `& fname',
and there's an equally curious `(*fname)'. With those
exceptions, I can think of no valid uses of function names
in expressions that do not evaluate to pointers to the
named functions.

Non-expression uses do not evaluate to anything at all:

int func(void); /* declares func, evaluates nothing */

void gunk(int) {} /* defines and declares gunk,
* evaluates nothing */

However, as you're talking to a beginner I'd suggest that
you not speak about "function pointers" or "function addresses"
at all. A function name is a name for a bunch of code that
expresses a bunch of operations to be performed, and there's
no need to fret about the details of how the machine represents
those operations. You don't need to talk about "instructions"
or "instruction addresses" or any such; the beginner should be
more concerned with the idea that a piece of code "here" can
somehow use a different piece of code "there," and with the
mechanics of passing arguments and returning values. That
is, concentrate on what a function does and not on how some
machine happens to do it.

... and if you want to use custard_pie() as a function
name, that's fine with me.
 
K

Keith Thompson

Keith said:
A function name names a function, it is not the same thing as the
function itself. A function pointer will typically contain an address,
but a function pointer is not an address. A function name will decay
into a function pointer in almost every context, but a function name
is not a function pointer.
[...]

Actually, a function pointer *is* an address; it's the address of the
function. (The standard uses the words "address" and "pointer" almost
interchangeably.)

I think that, to the extent that the standard does so, it is
defective. Treating the two terms as interchangeable would, if
normative, prohibit the implementation of pointers as structures which
contain, among other things, the address of the location in memory
that they point at. I doubt that it was the intent of the committee to
prohibit such fat-pointer implementations.

Cross-posting to comp.std.c

Not at all. In an implementation with fat pointers, a fat pointer
*is* an address. For example, the unary "&" operator yields a fat
pointer value, which is the address of the operand.
 
J

Jack Klein

A function name names a function, it is not the same thing as the
function itself. A function pointer will typically contain an address,
but a function pointer is not an address. A function name will decay
into a function pointer in almost every context, but a function name
is not a function pointer.
[...]

Actually, a function pointer *is* an address; it's the address of the
function. (The standard uses the words "address" and "pointer" almost
interchangeably.)

Actually, although it does not do it well, I think the standard does
at least attempt to distinguish between the related concepts of
pointer and address.

6.2.5 P20:

"A pointer type may be derived from a function type, an object type,
or an incomplete type, called the referenced type. A pointer type
describes an object whose value provides a reference to an entity of
the referenced type. A pointer type derived from the referenced type T
is sometimes called ‘‘pointer to T’’. The construction of a pointer
type from a referenced type is called ‘‘pointer type derivation’’."

Note no mention whatsoever of "address".

Then 6.5.3.2 P3:

"The unary & operator returns the address of its operand. If the
operand has type ‘‘type’’, the result has type ‘‘pointer to type’’."

It's a subtle distinction, perhaps too subtle.

An int is a type that contains a value, not a collection of bits, even
when you are performing bit-wise operations on it.

So a pointer is not an address, but when properly initialized or
assigned, can contain a value.

I think this is important in the case of function pointers, as on some
platforms they are not addresses in the same sense that pointers to
objects are. They might be more complex objects, references to some
sort of activation sequences. Interpreting the contents as an
address, even assuming that it points into a different address space
than pointers to object do, could be misleading.

Of course that leaves the definition of '&' a little too broad.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
C

Charlton Wilbur

J> I appreciate your concern, but I don't think you're in a
J> position to make that judgment given nothing more than a quick
J> question from me to the experts on clc.

On the contrary; I think, as one of those experts with some teaching
experience, I'm in an excellent position to judge that.

But carry on; thoroughly confusing beginners is a fine way to make
sure the consulting rates for competent C programmers remain high.

Charlton
 
J

James Kuyper

Keith said:
Keith said:
(e-mail address removed) writes:
[...]
A function name names a function, it is not the same thing as the
function itself. A function pointer will typically contain an address,
but a function pointer is not an address. A function name will decay
into a function pointer in almost every context, but a function name
is not a function pointer.
[...]

Actually, a function pointer *is* an address; it's the address of the
function. (The standard uses the words "address" and "pointer" almost
interchangeably.)
I think that, to the extent that the standard does so, it is
defective. Treating the two terms as interchangeable would, if
normative, prohibit the implementation of pointers as structures which
contain, among other things, the address of the location in memory
that they point at. I doubt that it was the intent of the committee to
prohibit such fat-pointer implementations.

Cross-posting to comp.std.c

Not at all. In an implementation with fat pointers, a fat pointer
*is* an address. For example, the unary "&" operator yields a fat
pointer value, which is the address of the operand.

No, it isn't an address, it contains an address. It also contains other
things: bound's checking data, or type info, or a reference count, or
something else entirely, depending upon what kind of fat pointer it is.
 
U

user923005

Ignoring implementation details and strictly following the C99
standard in terms of semantics, is there anything fundamentally flawed
with describing the use of a (non-inline) function as an address[1]? I
keep feeling like I'm missing something obvious.

We reference a function by its address. A function is no more its
address than an array is its address. It's simply a handy handle we
have to reference it with.
We can use a function pointer and a function interchangably on
invocation, so there is no real important difference there.
A function address is different from a data address. Despite the fact
that it sometimes works, we are not supposed to store function
addresses in void pointers.
So the address of a function is a special sort of address.
 

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
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top