Address of array and function, & is superfluous 
Author Message
 Address of array and function, & is superfluous

I mistakenly passed a pointer to a function to a function by putting an &
on it as shown below:

#include <stdio.h>

void callback(void) { return; }

void func(void (*pCallback)(void))
{
    pCallback();

Quote:
}

int main(void)
{
    func(&callback);  /* This works. */
    func(callback);   /* This works. */

    return 0;

Quote:
}

I see why it works, it just confused me for a moment. Please verify that I
haven't missed something. Same goes for an array.

--
- Mark A. Odell
- Embedded Firmware Design, Inc.
- http://www.*-*-*.com/



Sun, 14 Mar 2004 22:32:18 GMT  
 Address of array and function, & is superfluous

Quote:
> I mistakenly passed a pointer to a function to a function by putting an &
> on it as shown below:

> #include <stdio.h>

> void callback(void) { return; }

> void func(void (*pCallback)(void))
> {
>     pCallback();
> }

> int main(void)
> {
>     func(&callback);  /* This works. */
>     func(callback);   /* This works. */

>     return 0;
> }

> I see why it works, it just confused me for a moment. Please verify that I
> haven't missed something. Same goes for an array.

     callback (without &) is converted to an expression that has
type pointer to function returning void (C99 6.3.2.1 #4).

Tak-Shing



Mon, 15 Mar 2004 00:06:33 GMT  
 Address of array and function, & is superfluous

Quote:

> I mistakenly passed a pointer to a function to a function by putting an &
> on it as shown below:

> #include <stdio.h>

> void callback(void) { return; }

> void func(void (*pCallback)(void))
> {
>     pCallback();
> }

> int main(void)
> {
>     func(&callback);  /* This works. */
>     func(callback);   /* This works. */

>     return 0;
> }

> I see why it works, it just confused me for a moment. Please verify that I
> haven't missed something. Same goes for an array.

As part of an expression, the name of a function like "func" or
"callback" is something called a "function designator". And in some
situations a "function designator" is converted to a function pointer:
If the address operator & is applied to it, or if it is followed by an
expression list in brackets, or if it is evaluated on its own. In the
call func(callback), callback is converted to a function pointer, and
func is evaluated to a function pointer. As with arrays, this conversion
does NOT happen if a "function designator" is the operand of a sizeof
operator. The difference is that arrays are allowed as operands of the
sizeof operator, but function designators aren't. So if you also have

        int a  [10];

then
        sizeof (&callback)          -> size of a function pointer, often four or eight
        sizeof (callback)               -> not allowed
        sizeof (&a)                 -> size of a pointer to an array of 10 integers, often
four or eight
        sizeof (a)                      -> size of an array of 10 integers, often 20, 40 or 80



Mon, 15 Mar 2004 00:18:29 GMT  
 Address of array and function, & is superfluous

Quote:
>I mistakenly passed a pointer to a function to a function by putting an &
>on it as shown below:

>#include <stdio.h>

>void callback(void) { return; }

>void func(void (*pCallback)(void))
>{
>    pCallback();
>}

>int main(void)
>{
>    func(&callback);  /* This works. */
>    func(callback);   /* This works. */

>    return 0;
>}

>I see why it works, it just confused me for a moment. Please verify that I
>haven't missed something.

It works, the & operator is superfluous in this context.

Quote:
>Same goes for an array.

With arrays things are more subtle:

    char arr[10];

Except when used as the argument of sizeof, arr is a pointer to the
first char of an array of 10 char's.  &arr is a pointer to an array of
10 char's.  They have different types and cannot be used interchangeably,
even if they express the same address:

    ues5:~/tmp 27> cat -n test.c
         1  void foo(char *bar) {}
         2
         3  int main()
         4  {
         5      char arr[10];
         6      foo(arr);
         7      foo(&arr);
         8      return 0;
         9  }
    ues5:~/tmp 28> gcc test.c
    test.c: In function `main':
    test.c:7: warning: passing arg 1 of `foo' from incompatible pointer type

Dan
--
Dan Pop
CERN, IT Division

Mail:  CERN - IT, Bat. 31 1-014, CH-1211 Geneve 23, Switzerland



Sun, 14 Mar 2004 23:30:01 GMT  
 Address of array and function, & is superfluous
Thank you Dan, et al. I appreciate your answers.

--
- Mark A. Odell
- Embedded Firmware Design, Inc.
- http://www.embeddedfw.com



Mon, 15 Mar 2004 00:18:39 GMT  
 Address of array and function, & is superfluous

Quote:

> Except when used as the argument of sizeof, arr is a pointer to the
> first char of an array of 10 char's.  &arr is a pointer to an array of
> 10 char's.  They have different types and cannot be used interchangeably,
> even if they express the same address:

I was thinking about how to correctly use &arr which has type "pointer to
array 10 of char".

#include <stdio.h>

/* declare foo as function (pointer to array 2 of int)
 * returning pointer to array 2 of int
 */
int (*foo(int (*)[2]))[2];

int main (void)
{
    int a[2] = {3, 4};
    int (*b)[2];
    b = foo (&a);
    printf ("(*b)[0] = %i, (*b)[1] = %i\n", (*b)[0], (*b)[1]);
    return 0;

Quote:
}

int (*foo(int (*bar)[2]))[2]
{
    ++(*bar)[0];
    --(*bar)[1];
    return bar;

Quote:
}

Ralmin.


Mon, 15 Mar 2004 00:28:37 GMT  
 Address of array and function, & is superfluous

Quote:
>  I mistakenly passed a pointer to a function to a function by putting an &
>  on it as shown below:
> [snip]
>      func(&callback);  /* This works. */
>      func(callback);   /* This works. */

>  I see why it works, it just confused me for a moment. Please verify that I
>  haven't missed something.

You haven't. When it is *not* the operand of the unary &
(address-of) operator, a function designator is converted to a
pointer to the function it designates. If it *is* the operand of the
address-of operator, this implicit conversion doesn't take place,
but the same conversion is done by the & operator. It's the same
thing.
Note that while a single & operator is redundant here, you cannot
use more than one because the "decayed" function pointer is not an
lvalue.

Quote:
> Same goes for an array.

Nope. Consider
    int arr[10];
If this is not the operand of sizeof or unary &, it is implicitly
converted into a pointer (int *) to the first array element. If it
is the operand of the & operator, that operator converts it into a
pointer of type (int (*)[10]) to the *whole* array.

Gergo

--
"I don't need to fight to prove I'm right."
    -- Pete Townshend



Sun, 14 Mar 2004 23:08:46 GMT  
 Address of array and function, & is superfluous


Quote:
> #include <stdio.h>

> void callback(void) { return; }

> void func(void (*pCallback)(void))
> {
>     pCallback();
> }

> int main(void)
> {
>     func(&callback);  /* This works. */
>     func(callback);   /* This works. */

>     return 0;
> }

> I see why it works, it just confused me for a moment. Please verify
> that I haven't missed something. Same goes for an array.

They both are correct. On Borland C, the first case produces a warning
"superflous & with function"

--
-hs- emdel at noos.fr "support Afghans against Talebans"
"Car les bandits qui sont cause des guerres
 N'en meurent jamais, on n'tue qu'les innocents."
Gaston Monthus -- La Butte Rouge



Mon, 15 Mar 2004 03:15:33 GMT  
 Address of array and function, & is superfluous

Quote:


> > #include <stdio.h>

> > void callback(void) { return; }

> > void func(void (*pCallback)(void))
> > {
> >     pCallback();
> > }

> > int main(void)
> > {
> >     func(&callback);  /* This works. */
> >     func(callback);   /* This works. */

> >     return 0;
> > }

> > I see why it works, it just confused me for a moment. Please verify
> > that I haven't missed something. Same goes for an array.

> They both are correct. On Borland C, the first case produces a warning
> "superflous & with function"

They are not the same thing.  Only func(callback) is the correct form.
Similarly for an array.  For example:

void string_munger(char *s)
{
/* whatever */

Quote:
}

int main(int argc, char **argv)
{
if (argc)
{
char *s = argv[0];
string_munger(s);    /* Normal sort of call */
string_munger(&s[0]);/* This one is exactly equivalent */
string_munger(&s);   /* This is wrong.  It has the wrong level of
indirection. */

Quote:
}
return 0;
}

From the previous question about functions:
Quote:
> >     func(&callback);  /* This works. */

By accident.  Here func() is called with the address of the function pointer
(which is already an address).  I have seen this "work" too, but it isn't
the right way to do it.  Again, this is being called with the address of a
function pointer, which is the wrong level of indirection.

Quote:
> >     func(callback);   /* This works. */

As well it should.
--
C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
 "The C-FAQ Book" ISBN 0-201-84519-9
C.A.P. FAQ: ftp://cap.connx.com/pub/Chess%20Analysis%20Project%20FAQ.htm


Mon, 15 Mar 2004 04:52:52 GMT  
 Address of array and function, & is superfluous

Quote:

> the right way to do it.  Again, this is being called with the address of a
> function pointer, which is the wrong level of indirection.

     Not so.  See C99 6.3.2.1 #4.

Tak-Shing



Mon, 15 Mar 2004 06:00:10 GMT  
 Address of array and function, & is superfluous

Quote:





>> > #include <stdio.h>

>> > void callback(void) { return; }

>> > void func(void (*pCallback)(void))
>> > {
>> >     pCallback();
>> > }

[ snip ]

Quote:
>From the previous question about functions:
>> >     func(&callback);  /* This works. */
>By accident.  Here func() is called with the address of the function pointer
>(which is already an address).

callback is a function designator, which will ``decay'' to a pointer
when evaluated. It's not evaluated when it's the operand of &; in
that case, & will take the address of the function designator to obtain
a pointer.

Arrays are different, because & will yield a pointer to the whole
array, while the decay yields a pointer to the first element.
In the case of functions, & and decay yield the same thing.



Mon, 15 Mar 2004 06:16:06 GMT  
 Address of array and function, & is superfluous

Quote:

> > the right way to do it.  Again, this is being called with the address of
a
> > function pointer, which is the wrong level of indirection.

>      Not so.  See C99 6.3.2.1 #4.

"4 A function designator is an expression that has function type. Except
when it is the operand of the sizeof operator 54) or the unary & operator, a
function designator with type ''function returning type'' is converted to an
expression that has type ''pointer to function returning type''."

The above said "*Except* when it is the operand of .. or the unary &
operator ... is converted to an expression that has type ''pointer to
function returning type'' which indicates to me that it will NOT yield a
pointer to function returning type when the & operator is applied.  Rather,
it would yield the address of that pointer [well, that's what I would
expect].

My question is (therefore) to the gurus who inhabit the high halls of

Are these two calls [exhibit A and exhibit B] equivalent:

#include <stdio.h>
typedef void (*ftype) (void);

void foo(void)
{
    puts("hi.");

Quote:
}

void f(ftype a)
{
    a();

Quote:
}

int main(void)
{
/* Exhibit A: */
    f(foo);
/* Exhibit B: */
    f(&foo);
    return 0;

Quote:
}

/*
** Inquiring minds want to know.
** Please quote chapter and verse, so I may see where I went off.
*/
--
C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
 "The C-FAQ Book" ISBN 0-201-84519-9
C.A.P. FAQ: ftp://cap.connx.com/pub/Chess%20Analysis%20Project%20FAQ.htm


Mon, 15 Mar 2004 07:08:24 GMT  
 Address of array and function, & is superfluous

Quote:




>> > the right way to do it.  Again, this is being called with the address of
>a
>> > function pointer, which is the wrong level of indirection.

>>      Not so.  See C99 6.3.2.1 #4.

>"4 A function designator is an expression that has function type. Except
>when it is the operand of the sizeof operator 54) or the unary & operator, a
>function designator with type ''function returning type'' is converted to an
>expression that has type ''pointer to function returning type''."

>The above said "*Except* when it is the operand of .. or the unary &
>operator ... is converted to an expression that has type ''pointer to
>function returning type'' which indicates to me that it will NOT yield a
>pointer to function returning type when the & operator is applied.  Rather,
>it would yield the address of that pointer [well, that's what I would
>expect].

The point that the "except when..." clause is making is that you don't
convert the function designator to a pointer before applying the & operator
to it.  However, the & operator, applied to an object of type T, always
returns a value of type 'pointer to T'.  So, &<function designator> returns
a value of type 'pointer to function'.

Without that exception, the value of &<function designator> would be of
type 'pointer to pointer to function'.

Quote:
>My question is (therefore) to the gurus who inhabit the high halls of

>Are these two calls [exhibit A and exhibit B] equivalent:

Yes.  In Exhibit A, foo is converted to a pointer due to the normal
conversion.  In Exchibit B, foo designates the function itself, and the &
operator returns the function's address.

- Show quoted text -

Quote:

>#include <stdio.h>
>typedef void (*ftype) (void);

>void foo(void)
>{
>    puts("hi.");
>}

>void f(ftype a)
>{
>    a();
>}

>int main(void)
>{
>/* Exhibit A: */
>    f(foo);
>/* Exhibit B: */
>    f(&foo);
>    return 0;
>}

--

Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.


Mon, 15 Mar 2004 08:00:47 GMT  
 Address of array and function, & is superfluous

Quote:




>> > the right way to do it.  Again, this is being called with the
>> > address of a function pointer, which is the wrong level of indirection.

>>      Not so.  See C99 6.3.2.1 #4.

>"4 A function designator is an expression that has function type. Except
>when it is the operand of the sizeof operator 54) or the unary & operator, a
>function designator with type ''function returning type'' is converted to an
>expression that has type ''pointer to function returning type''."

Ok.

Quote:
>The above said "*Except* when it is the operand of .. or the unary &
>operator ... is converted to an expression that has type ''pointer to
>function returning type'' which indicates to me that it will NOT yield a
>pointer to function returning type when the & operator is applied.  Rather,
>it would yield the address of that pointer [well, that's what I would
>expect].

Either way it yields an address, via an (rvalue) pointer, the question
is what is the type of the address.

The thing is that the above talks about when it is not &'d.
So, IOWs, notwithstanding sizeof, in "T1 foo(T2);", foo
has type "T1(T2)", which if you don't & it, becomes through
the above conversion type "T1(*)(T2)"

Now, if you do & the foo, the conversion doesn't take place.
However, there is a conversion defined for &.  As per 6.5.3.2 in C99:
"The unary & operator returns the address of its operand. If the
operand has type 'type', the result has type 'pointer to type'."
Therefore &foo is a pointer to a "T1(T2)" which is also a "T1(*)(T2)".

Of course in the former, the function designator "itself" is converted,
whereas in the latter, the value of the expression is.

Quote:
>My question is (therefore) to the gurus who inhabit the high halls of

>Are these two calls [exhibit A and exhibit B] equivalent:

>#include <stdio.h>
>typedef void (*ftype) (void);

>void foo(void)
>{
>    puts("hi.");
>}

>void f(ftype a)
>{
>    a();
>}

>int main(void)
>{
>/* Exhibit A: */
>    f(foo);
>/* Exhibit B: */
>    f(&foo);
>    return 0;
>}

>/*
>** Inquiring minds want to know.
>** Please quote chapter and verse, so I may see where I went off.
>*/

As per above, 6.5.3.2p3.
--
Greg Comeau         export ETA: Dec 1    10% "End of Summer" Offer
Comeau C/C++ ONLINE ==>     http://www.comeaucomputing.com/tryitout
World Class Compilers:  Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?


Mon, 15 Mar 2004 11:22:58 GMT  
 Address of array and function, & is superfluous

Quote:

> So, IOWs, notwithstanding sizeof, in "T1 foo(T2);", foo
> has type "T1(T2)", which if you don't & it, becomes through
> the above conversion type "T1(*)(T2)"

Actually it has, before conversion, the abstract type (T1()(T2)).
(The inner parentheses are important, as a placeholder.)
Otherwise, the analysis was correct.


Tue, 16 Mar 2004 02:24:15 GMT  
 
 [ 22 post ]  Go to page: [1] [2]

 Relevant Pages 

1. Pointers & incrementing array address

2. Array of function addresses

3. array of function addresses

4. strings & function addresses

5. Which 2D array of 2D array addressing method?

6. Why I am getting Error C2091: function returns function

7. passing arrays to functions & other stuff

8. Newbie learning arrays&function ?

9. For Loops(Arrays&Functions)

10. Superfluous header ?

11. Passing the address of a member function to a C function

12. I am searching an algorithm for testing all possibilities in an 2D-array

 

 
Powered by phpBB® Forum Software