By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,846 Members | 1,646 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,846 IT Pros & Developers. It's quick & easy.

main function address

P: n/a
hi,
Is main function address is 657.
its show in all compiler.
try it & say why?
bye,
Nov 14 '05 #1
Share this Question
Share on Google+
89 Replies


P: n/a
Sweety <sw************@yahoo.co.in> scribbled the following:
hi,
Is main function address is 657.
its show in all compiler.
try it & say why?
bye,


No, the main function's address may be whatever your implementation
wants it to be. You can't rely on it being any particular numeric value,
actually you can't rely it on being a numeric value at all.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"Keep shooting, sooner or later you're bound to hit something."
- Misfire
Nov 14 '05 #2

P: n/a
Sweety <sw************@yahoo.co.in> scribbled the following:
hi,
Is main function address is 657.
its show in all compiler.
try it & say why?
bye,


No, the main function's address may be whatever your implementation
wants it to be. You can't rely on it being any particular numeric value,
actually you can't rely it on being a numeric value at all.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"Keep shooting, sooner or later you're bound to hit something."
- Misfire
Nov 14 '05 #3

P: n/a
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Sweety wrote:
| hi,
| Is main function address is 657.

Perhaps, perhaps not. It depends on your compiler, linker, operating system, and
CPU.

| its show in all compiler.

No, it doesn't.

~ ~/code $ cat printmain.c
~ #include <stdio.h>
~ #include <stdlib.h>

~ int main(void)
~ {
~ printf("main() at %p\n",(void *)&main);

~ return EXIT_SUCCESS;
~ }

~ ~/code $ cc -o printmain printmain.c

~ ~/code $ printmain
~ main() at 0x8048328

~ ~/code $
| try it & say why?

I did, and it' didn't, so I can't say why 657.

| bye,
- --
Lew Pitcher

Master Codewright & JOAT-in-training | GPG public key available on request
Registered Linux User #112576 (http://counter.li.org/)
Slackware - Because I know what I'm doing.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFAc16aagVFX4UWr64RAvsiAJ9Tq3RBO4marGAqz3RWYx jcebFfuwCgry/M
5kAKhQe0/0006+/H6+GJp9I=
=qU+e
-----END PGP SIGNATURE-----

Nov 14 '05 #4

P: n/a
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Sweety wrote:
| hi,
| Is main function address is 657.

Perhaps, perhaps not. It depends on your compiler, linker, operating system, and
CPU.

| its show in all compiler.

No, it doesn't.

~ ~/code $ cat printmain.c
~ #include <stdio.h>
~ #include <stdlib.h>

~ int main(void)
~ {
~ printf("main() at %p\n",(void *)&main);

~ return EXIT_SUCCESS;
~ }

~ ~/code $ cc -o printmain printmain.c

~ ~/code $ printmain
~ main() at 0x8048328

~ ~/code $
| try it & say why?

I did, and it' didn't, so I can't say why 657.

| bye,
- --
Lew Pitcher

Master Codewright & JOAT-in-training | GPG public key available on request
Registered Linux User #112576 (http://counter.li.org/)
Slackware - Because I know what I'm doing.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFAc16aagVFX4UWr64RAvsiAJ9Tq3RBO4marGAqz3RWYx jcebFfuwCgry/M
5kAKhQe0/0006+/H6+GJp9I=
=qU+e
-----END PGP SIGNATURE-----

Nov 14 '05 #5

P: n/a
Em Tue, 06 Apr 2004 21:51:22 -0400, Lew Pitcher escreveu:
<snip>
~ printf("main() at %p\n",(void *)&main);

<snip>

Wouldn't simply
printf("main() at %p\n", (void *)main);
do? Notice the prunning of the & operator. For what I know,
the name of a function is a pointer to that function, am I right?

--
José de Paula Rodrigues Neto Assis Linux User 175920
Brasília - DF - Brasil counter.li.org

Nov 14 '05 #6

P: n/a
Em Tue, 06 Apr 2004 21:51:22 -0400, Lew Pitcher escreveu:
<snip>
~ printf("main() at %p\n",(void *)&main);

<snip>

Wouldn't simply
printf("main() at %p\n", (void *)main);
do? Notice the prunning of the & operator. For what I know,
the name of a function is a pointer to that function, am I right?

--
José de Paula Rodrigues Neto Assis Linux User 175920
Brasília - DF - Brasil counter.li.org

Nov 14 '05 #7

P: n/a
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

José de Paula wrote:
| Em Tue, 06 Apr 2004 21:51:22 -0400, Lew Pitcher escreveu:
| <snip>
|
|>~ printf("main() at %p\n",(void *)&main);
|
| <snip>
|
| Wouldn't simply
| printf("main() at %p\n", (void *)main);
| do? Notice the prunning of the & operator. For what I know,
| the name of a function is a pointer to that function, am I right?

You are correct. The & was unnecessary.
- --
Lew Pitcher

Master Codewright & JOAT-in-training | GPG public key available on request
Registered Linux User #112576 (http://counter.li.org/)
Slackware - Because I know what I'm doing.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFAc2o1agVFX4UWr64RAofEAKCScgoEuAKn8ci/cjeimsG01iyWXACgznfY
/2jtHAGq0Fpm6dHKZ1ZdP7E=
=ra40
-----END PGP SIGNATURE-----

Nov 14 '05 #8

P: n/a
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

José de Paula wrote:
| Em Tue, 06 Apr 2004 21:51:22 -0400, Lew Pitcher escreveu:
| <snip>
|
|>~ printf("main() at %p\n",(void *)&main);
|
| <snip>
|
| Wouldn't simply
| printf("main() at %p\n", (void *)main);
| do? Notice the prunning of the & operator. For what I know,
| the name of a function is a pointer to that function, am I right?

You are correct. The & was unnecessary.
- --
Lew Pitcher

Master Codewright & JOAT-in-training | GPG public key available on request
Registered Linux User #112576 (http://counter.li.org/)
Slackware - Because I know what I'm doing.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFAc2o1agVFX4UWr64RAofEAKCScgoEuAKn8ci/cjeimsG01iyWXACgznfY
/2jtHAGq0Fpm6dHKZ1ZdP7E=
=ra40
-----END PGP SIGNATURE-----

Nov 14 '05 #9

P: n/a
Lew Pitcher wrote:
Sweety wrote:
|
| Is main function address is 657.

Perhaps, perhaps not.
It depends on your compiler, linker, operating system, and CPU.

| its show in all compiler.

No, it doesn't.

~ ~/code $ cat printmain.c
~ #include <stdio.h>
~ #include <stdlib.h>

~ int main(void)
~ {
~ printf("main() at %p\n",(void *)&main);

~ return EXIT_SUCCESS;
~ }

~ ~/code $ cc -o printmain printmain.c

~ ~/code $ printmain
~ main() at 0x8048328

~ ~/code $
| try it & say why?

I did, and it' didn't, so I can't say why 657. cat printmain.c #include <stdio.h>
#include <stdlib.h>

int main(void) {
printf("main() at %p\n",(void *)&main);

return EXIT_SUCCESS;
}
gcc -Wall -std=c99 -pedantic -o printmain printmain.c
./printmain

main() at 0x8048328

Why 0x8048328? :-)

Nov 14 '05 #10

P: n/a
Lew Pitcher wrote:
Sweety wrote:
|
| Is main function address is 657.

Perhaps, perhaps not.
It depends on your compiler, linker, operating system, and CPU.

| its show in all compiler.

No, it doesn't.

~ ~/code $ cat printmain.c
~ #include <stdio.h>
~ #include <stdlib.h>

~ int main(void)
~ {
~ printf("main() at %p\n",(void *)&main);

~ return EXIT_SUCCESS;
~ }

~ ~/code $ cc -o printmain printmain.c

~ ~/code $ printmain
~ main() at 0x8048328

~ ~/code $
| try it & say why?

I did, and it' didn't, so I can't say why 657. cat printmain.c #include <stdio.h>
#include <stdlib.h>

int main(void) {
printf("main() at %p\n",(void *)&main);

return EXIT_SUCCESS;
}
gcc -Wall -std=c99 -pedantic -o printmain printmain.c
./printmain

main() at 0x8048328

Why 0x8048328? :-)

Nov 14 '05 #11

P: n/a
José de Paula wrote:
Lew Pitcher escreveu:

<snip>
~ printf("main() at %p\n",(void *)&main); <snip>

Wouldn't simply

printf("main() at %p\n", (void *)main); do? Notice the pruning of the & operator. For what I know,
the name of a function is a pointer to that function. Am I right?


Yes. There is an implicit conversion
from the name of a function to a pointer to the function.

Nov 14 '05 #12

P: n/a
José de Paula wrote:
Lew Pitcher escreveu:

<snip>
~ printf("main() at %p\n",(void *)&main); <snip>

Wouldn't simply

printf("main() at %p\n", (void *)main); do? Notice the pruning of the & operator. For what I know,
the name of a function is a pointer to that function. Am I right?


Yes. There is an implicit conversion
from the name of a function to a pointer to the function.

Nov 14 '05 #13

P: n/a
Lew Pitcher <lp******@sympatico.ca> writes:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
printf("main() at %p\n",(void *)&main);

return EXIT_SUCCESS;
}


Is the cast to `void *' valid? I cannot find anything in the standard
which allows a pointer to a function to be converted to type `void *'.

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #14

P: n/a
Lew Pitcher <lp******@sympatico.ca> writes:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
printf("main() at %p\n",(void *)&main);

return EXIT_SUCCESS;
}


Is the cast to `void *' valid? I cannot find anything in the standard
which allows a pointer to a function to be converted to type `void *'.

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #15

P: n/a
Martin Dickopp wrote:

Lew Pitcher <lp******@sympatico.ca> writes:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
printf("main() at %p\n",(void *)&main);

return EXIT_SUCCESS;
}


Is the cast to `void *' valid?


No.

In N869, it's one of the common extensions.

J.5.7 Function pointer casts
[#2] A pointer to a function may be cast to a pointer to an
object or to void, allowing a function to be inspected or
modified (for example, by a debugger) (6.5.4).

.... which makes it more obviously not part of standard C.

--
pete
Nov 14 '05 #16

P: n/a
Martin Dickopp wrote:

Lew Pitcher <lp******@sympatico.ca> writes:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
printf("main() at %p\n",(void *)&main);

return EXIT_SUCCESS;
}


Is the cast to `void *' valid?


No.

In N869, it's one of the common extensions.

J.5.7 Function pointer casts
[#2] A pointer to a function may be cast to a pointer to an
object or to void, allowing a function to be inspected or
modified (for example, by a debugger) (6.5.4).

.... which makes it more obviously not part of standard C.

--
pete
Nov 14 '05 #17

P: n/a

"Lew Pitcher" <lp******@sympatico.ca> wrote in message news:W6*******************@news20.bellglobal.com.. .
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Sweety wrote:
| hi,
| Is main function address is 657.

Perhaps, perhaps not. It depends on your compiler, linker, operating system, and
CPU.

| its show in all compiler.

No, it doesn't.

~ ~/code $ cat printmain.c
~ #include <stdio.h>
~ #include <stdlib.h>

~ int main(void)
~ {
~ printf("main() at %p\n",(void *)&main);

~ return EXIT_SUCCESS;
~ }

~ ~/code $ cc -o printmain printmain.c

~ ~/code $ printmain
~ main() at 0x8048328


F:\Vijay\C> bcc32 printmain.c
F:\Vijay\C> printmain
main() at 00401150
F:\Vijay\C> gcc printmain.c
F:\Vijay\C> a
main() at 15ee
Nov 14 '05 #18

P: n/a

"Lew Pitcher" <lp******@sympatico.ca> wrote in message news:W6*******************@news20.bellglobal.com.. .
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Sweety wrote:
| hi,
| Is main function address is 657.

Perhaps, perhaps not. It depends on your compiler, linker, operating system, and
CPU.

| its show in all compiler.

No, it doesn't.

~ ~/code $ cat printmain.c
~ #include <stdio.h>
~ #include <stdlib.h>

~ int main(void)
~ {
~ printf("main() at %p\n",(void *)&main);

~ return EXIT_SUCCESS;
~ }

~ ~/code $ cc -o printmain printmain.c

~ ~/code $ printmain
~ main() at 0x8048328


F:\Vijay\C> bcc32 printmain.c
F:\Vijay\C> printmain
main() at 00401150
F:\Vijay\C> gcc printmain.c
F:\Vijay\C> a
main() at 15ee
Nov 14 '05 #19

P: n/a
Lew Pitcher <lp******@sympatico.ca> writes:
José de Paula wrote:
| Em Tue, 06 Apr 2004 21:51:22 -0400, Lew Pitcher escreveu:
| <snip>
|
|>~ printf("main() at %p\n",(void *)&main);
|
| <snip>
|
| Wouldn't simply
| printf("main() at %p\n", (void *)main);
| do? Notice the prunning of the & operator. For what I know,
| the name of a function is a pointer to that function, am I right?

You are correct. The & was unnecessary.


It's unnecessary, but harmless, and some might argue that it's
clearer, since it makes it more explicit that the expression is an
address.

A function name is implicitly converted to a function pointer unless
it's the operand of a sizeof or unary & operator. (In the case of
sizeof, the resulting expression is illegal.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #20

P: n/a
Lew Pitcher <lp******@sympatico.ca> writes:
José de Paula wrote:
| Em Tue, 06 Apr 2004 21:51:22 -0400, Lew Pitcher escreveu:
| <snip>
|
|>~ printf("main() at %p\n",(void *)&main);
|
| <snip>
|
| Wouldn't simply
| printf("main() at %p\n", (void *)main);
| do? Notice the prunning of the & operator. For what I know,
| the name of a function is a pointer to that function, am I right?

You are correct. The & was unnecessary.


It's unnecessary, but harmless, and some might argue that it's
clearer, since it makes it more explicit that the expression is an
address.

A function name is implicitly converted to a function pointer unless
it's the operand of a sizeof or unary & operator. (In the case of
sizeof, the resulting expression is illegal.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 14 '05 #21

P: n/a
Martin Dickopp <ex****************@zero-based.org> wrote:
Lew Pitcher <lp******@sympatico.ca> writes:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
printf("main() at %p\n",(void *)&main);

return EXIT_SUCCESS;
}


Is the cast to `void *' valid?


No. Mind you, there is no better way to print the address of a function,
either. Where this works, it works; where it doesn't, nothing else is
likely to.

Richard
Nov 14 '05 #22

P: n/a
Martin Dickopp <ex****************@zero-based.org> wrote:
Lew Pitcher <lp******@sympatico.ca> writes:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
printf("main() at %p\n",(void *)&main);

return EXIT_SUCCESS;
}


Is the cast to `void *' valid?


No. Mind you, there is no better way to print the address of a function,
either. Where this works, it works; where it doesn't, nothing else is
likely to.

Richard
Nov 14 '05 #23

P: n/a
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

pete wrote:
| Martin Dickopp wrote:
|
|>Lew Pitcher <lp******@sympatico.ca> writes:
|>
|>
|>>#include <stdio.h>
|>>#include <stdlib.h>
|>>
|>>int main(void)
|>>{
|>> printf("main() at %p\n",(void *)&main);
|>>
|>> return EXIT_SUCCESS;
|>>}
|>
|>Is the cast to `void *' valid?
|
|
| No.
|
| In N869, it's one of the common extensions.
|
| J.5.7 Function pointer casts
| [#2] A pointer to a function may be cast to a pointer to an
| object or to void, allowing a function to be inspected or
| modified (for example, by a debugger) (6.5.4).
|
| ... which makes it more obviously not part of standard C.

In 9989-1999 (admittedly, just the draft C99 standard, and not the
/actual standard itself), the printf() function documentation in
7.19.6.3 refers the reader to the fprintf() documentation for a
description of it's input. The fprintf() documentation in 7.19.6.1 says
of the %p format

~ p The argument shall be a pointer to void. The value of the pointer is
~ converted to a sequence of printing characters, in an
~ implementation-defined manner.

So, to satisfy the %p format character, the argument to
fprintf()/printf() /must/ be a "pointer to void". Since main is a
"pointer to function returning int", and not a "pointer to void", I
interpreted the documentation as requiring a cast to void pointer.

- --

Lew Pitcher, IT Consultant, Enterprise Application Architecture
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed here are my own, not my employer's)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)

iD8DBQFAc+o1agVFX4UWr64RAgMKAJ9jpwGgLD0Ib6+SrFveX/B2DiSkQQCgn1b9
hcqV26vMzT9PW6/myM6CbsQ=
=jmLW
-----END PGP SIGNATURE-----
Nov 14 '05 #24

P: n/a
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

pete wrote:
| Martin Dickopp wrote:
|
|>Lew Pitcher <lp******@sympatico.ca> writes:
|>
|>
|>>#include <stdio.h>
|>>#include <stdlib.h>
|>>
|>>int main(void)
|>>{
|>> printf("main() at %p\n",(void *)&main);
|>>
|>> return EXIT_SUCCESS;
|>>}
|>
|>Is the cast to `void *' valid?
|
|
| No.
|
| In N869, it's one of the common extensions.
|
| J.5.7 Function pointer casts
| [#2] A pointer to a function may be cast to a pointer to an
| object or to void, allowing a function to be inspected or
| modified (for example, by a debugger) (6.5.4).
|
| ... which makes it more obviously not part of standard C.

In 9989-1999 (admittedly, just the draft C99 standard, and not the
/actual standard itself), the printf() function documentation in
7.19.6.3 refers the reader to the fprintf() documentation for a
description of it's input. The fprintf() documentation in 7.19.6.1 says
of the %p format

~ p The argument shall be a pointer to void. The value of the pointer is
~ converted to a sequence of printing characters, in an
~ implementation-defined manner.

So, to satisfy the %p format character, the argument to
fprintf()/printf() /must/ be a "pointer to void". Since main is a
"pointer to function returning int", and not a "pointer to void", I
interpreted the documentation as requiring a cast to void pointer.

- --

Lew Pitcher, IT Consultant, Enterprise Application Architecture
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed here are my own, not my employer's)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)

iD8DBQFAc+o1agVFX4UWr64RAgMKAJ9jpwGgLD0Ib6+SrFveX/B2DiSkQQCgn1b9
hcqV26vMzT9PW6/myM6CbsQ=
=jmLW
-----END PGP SIGNATURE-----
Nov 14 '05 #25

P: n/a
Lew Pitcher wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

pete wrote:
| Martin Dickopp wrote:
|
|>Lew Pitcher <lp******@sympatico.ca> writes:
|>
|>
|>>#include <stdio.h>
|>>#include <stdlib.h>
|>>
|>>int main(void)
|>>{
|>> printf("main() at %p\n",(void *)&main);
|>>
|>> return EXIT_SUCCESS;
|>>}
|>
|>Is the cast to `void *' valid?
|
|
| No.
|
| In N869, it's one of the common extensions.
|
| J.5.7 Function pointer casts
| [#2] A pointer to a function may be cast to a pointer to an
| object or to void, allowing a function to be inspected or
| modified (for example, by a debugger) (6.5.4).
|
| ... which makes it more obviously not part of standard C.

In 9989-1999 (admittedly, just the draft C99 standard, and not the
/actual standard itself), the printf() function documentation in
7.19.6.3 refers the reader to the fprintf() documentation for a
description of it's input. The fprintf() documentation in 7.19.6.1 says
of the %p format

~ p The argument shall be a pointer to void. The value of the pointer is
~ converted to a sequence of printing characters, in an
~ implementation-defined manner.

So, to satisfy the %p format character, the argument to
fprintf()/printf() /must/ be a "pointer to void". Since main is a
"pointer to function returning int", and not a "pointer to void", I
interpreted the documentation as requiring a cast to void pointer.


I interpret it as meaning that printing the address of a function
isn't something that you are guaranteed to be able to do.

--
pete
Nov 14 '05 #26

P: n/a
Lew Pitcher wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

pete wrote:
| Martin Dickopp wrote:
|
|>Lew Pitcher <lp******@sympatico.ca> writes:
|>
|>
|>>#include <stdio.h>
|>>#include <stdlib.h>
|>>
|>>int main(void)
|>>{
|>> printf("main() at %p\n",(void *)&main);
|>>
|>> return EXIT_SUCCESS;
|>>}
|>
|>Is the cast to `void *' valid?
|
|
| No.
|
| In N869, it's one of the common extensions.
|
| J.5.7 Function pointer casts
| [#2] A pointer to a function may be cast to a pointer to an
| object or to void, allowing a function to be inspected or
| modified (for example, by a debugger) (6.5.4).
|
| ... which makes it more obviously not part of standard C.

In 9989-1999 (admittedly, just the draft C99 standard, and not the
/actual standard itself), the printf() function documentation in
7.19.6.3 refers the reader to the fprintf() documentation for a
description of it's input. The fprintf() documentation in 7.19.6.1 says
of the %p format

~ p The argument shall be a pointer to void. The value of the pointer is
~ converted to a sequence of printing characters, in an
~ implementation-defined manner.

So, to satisfy the %p format character, the argument to
fprintf()/printf() /must/ be a "pointer to void". Since main is a
"pointer to function returning int", and not a "pointer to void", I
interpreted the documentation as requiring a cast to void pointer.


I interpret it as meaning that printing the address of a function
isn't something that you are guaranteed to be able to do.

--
pete
Nov 14 '05 #27

P: n/a
On Wed, 07 Apr 2004 07:47:04 -0400, Lew Pitcher <Le*********@td.com> wrote:
..

In 9989-1999 (admittedly, just the draft C99 standard, and not the
/actual standard itself), the printf() function documentation in
7.19.6.3 refers the reader to the fprintf() documentation for a
description of it's input. The fprintf() documentation in 7.19.6.1 says
of the %p format

~ p The argument shall be a pointer to void. The value of the pointer is
~ converted to a sequence of printing characters, in an
~ implementation-defined manner.

So, to satisfy the %p format character, the argument to
fprintf()/printf() /must/ be a "pointer to void". Since main is a
"pointer to function returning int", and not a "pointer to void", I
interpreted the documentation as requiring a cast to void pointer.


Curious -- I've never considered how implicit conversion rules ought to
play out in the arena of variadic functions... on one hand, pointers to
/anything/ implicitly convert to pointer-to-void, but on the other hand
there's no declaration for the receiving pointer-to-void.

Or, does the implicit conversion apply when the pointer value is extracted
and cast to void * in the receiving function?
-leor

--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Nov 14 '05 #28

P: n/a
On Wed, 07 Apr 2004 07:47:04 -0400, Lew Pitcher <Le*********@td.com> wrote:
..

In 9989-1999 (admittedly, just the draft C99 standard, and not the
/actual standard itself), the printf() function documentation in
7.19.6.3 refers the reader to the fprintf() documentation for a
description of it's input. The fprintf() documentation in 7.19.6.1 says
of the %p format

~ p The argument shall be a pointer to void. The value of the pointer is
~ converted to a sequence of printing characters, in an
~ implementation-defined manner.

So, to satisfy the %p format character, the argument to
fprintf()/printf() /must/ be a "pointer to void". Since main is a
"pointer to function returning int", and not a "pointer to void", I
interpreted the documentation as requiring a cast to void pointer.


Curious -- I've never considered how implicit conversion rules ought to
play out in the arena of variadic functions... on one hand, pointers to
/anything/ implicitly convert to pointer-to-void, but on the other hand
there's no declaration for the receiving pointer-to-void.

Or, does the implicit conversion apply when the pointer value is extracted
and cast to void * in the receiving function?
-leor

--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Nov 14 '05 #29

P: n/a
In <W6*******************@news20.bellglobal.com> Lew Pitcher <lp******@sympatico.ca> writes:
~ printf("main() at %p\n",(void *)&main);

^^^^^^^^^^^^^
Undefined behaviour. The standard doesn't define conversions between
function pointers and incomplete or object pointer types. And there is no
guarantee that the type pointer to void is wide enough to be able to
represent the result of such a conversion.

6.3.2.3 Pointers

1 A pointer to void may be converted to or from a pointer to any
incomplete or object type...
^^^^^^^^^^^^^^^^^^^^^^^^^

7 A pointer to an object or incomplete type may be converted to
a pointer to a different object or incomplete type...

8 A pointer to a function of one type may be converted to a pointer
to a function of another type and back again; the result shall
compare equal to the original pointer...

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #30

P: n/a
In <W6*******************@news20.bellglobal.com> Lew Pitcher <lp******@sympatico.ca> writes:
~ printf("main() at %p\n",(void *)&main);

^^^^^^^^^^^^^
Undefined behaviour. The standard doesn't define conversions between
function pointers and incomplete or object pointer types. And there is no
guarantee that the type pointer to void is wide enough to be able to
represent the result of such a conversion.

6.3.2.3 Pointers

1 A pointer to void may be converted to or from a pointer to any
incomplete or object type...
^^^^^^^^^^^^^^^^^^^^^^^^^

7 A pointer to an object or incomplete type may be converted to
a pointer to a different object or incomplete type...

8 A pointer to a function of one type may be converted to a pointer
to a function of another type and back again; the result shall
compare equal to the original pointer...

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #31

P: n/a
In <cu*************@zero-based.org> Martin Dickopp <ex****************@zero-based.org> writes:
Lew Pitcher <lp******@sympatico.ca> writes:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
printf("main() at %p\n",(void *)&main);

return EXIT_SUCCESS;
}


Is the cast to `void *' valid? I cannot find anything in the standard
which allows a pointer to a function to be converted to type `void *'.


It is syntactically valid, but devoid of any semantics, therefore it is
a case of undefined behaviour due to lack of specification.

One can replace unconditionally invoking undefined behaviour by
conditionally invoking undefined behaviour this way:

unsigned long address = (unsigned long)main;
printf("main() at %lx\n", address);

This invokes undefined behaviour *only* if the address of main cannot
be represented as an unsinged long:

6 Any pointer type may be converted to an integer type. Except as
previously specified, the result is implementation-defined. If the
result cannot be represented in the integer type, the behavior
is undefined. The result need not be in the range of values of
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
any integer type.
^^^^^^^^^^^^^^^^^

C99 users may want to use unsigned long long for this purpose, to increase
their chances of avoiding undefined behaviour. However, the language
doesn't guarantee the existence of a solution to this problem (the AS/400
programmers know why ;-)

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #32

P: n/a
In <cu*************@zero-based.org> Martin Dickopp <ex****************@zero-based.org> writes:
Lew Pitcher <lp******@sympatico.ca> writes:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
printf("main() at %p\n",(void *)&main);

return EXIT_SUCCESS;
}


Is the cast to `void *' valid? I cannot find anything in the standard
which allows a pointer to a function to be converted to type `void *'.


It is syntactically valid, but devoid of any semantics, therefore it is
a case of undefined behaviour due to lack of specification.

One can replace unconditionally invoking undefined behaviour by
conditionally invoking undefined behaviour this way:

unsigned long address = (unsigned long)main;
printf("main() at %lx\n", address);

This invokes undefined behaviour *only* if the address of main cannot
be represented as an unsinged long:

6 Any pointer type may be converted to an integer type. Except as
previously specified, the result is implementation-defined. If the
result cannot be represented in the integer type, the behavior
is undefined. The result need not be in the range of values of
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
any integer type.
^^^^^^^^^^^^^^^^^

C99 users may want to use unsigned long long for this purpose, to increase
their chances of avoiding undefined behaviour. However, the language
doesn't guarantee the existence of a solution to this problem (the AS/400
programmers know why ;-)

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #33

P: n/a
In <40****************@news.individual.net> rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
Martin Dickopp <ex****************@zero-based.org> wrote:
Lew Pitcher <lp******@sympatico.ca> writes:
> #include <stdio.h>
> #include <stdlib.h>
>
> int main(void)
> {
> printf("main() at %p\n",(void *)&main);
>
> return EXIT_SUCCESS;
> }
Is the cast to `void *' valid?


No. Mind you, there is no better way to print the address of a function,
either.


There is, even if you can't figure it out...
Where this works, it works; where it doesn't, nothing else is likely to.


How do you know?

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #34

P: n/a
In <40****************@news.individual.net> rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
Martin Dickopp <ex****************@zero-based.org> wrote:
Lew Pitcher <lp******@sympatico.ca> writes:
> #include <stdio.h>
> #include <stdlib.h>
>
> int main(void)
> {
> printf("main() at %p\n",(void *)&main);
>
> return EXIT_SUCCESS;
> }
Is the cast to `void *' valid?


No. Mind you, there is no better way to print the address of a function,
either.


There is, even if you can't figure it out...
Where this works, it works; where it doesn't, nothing else is likely to.


How do you know?

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #35

P: n/a
pete <pf*****@mindspring.com> writes:
Lew Pitcher wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

pete wrote:
| Martin Dickopp wrote:
|
|>Lew Pitcher <lp******@sympatico.ca> writes:
|>
|>
|>>#include <stdio.h>
|>>#include <stdlib.h>
|>>
|>>int main(void)
|>>{
|>> printf("main() at %p\n",(void *)&main);
|>>
|>> return EXIT_SUCCESS;
|>>}
|>
|>Is the cast to `void *' valid?
|
|
| No.
|
| In N869, it's one of the common extensions.
|
| J.5.7 Function pointer casts
| [#2] A pointer to a function may be cast to a pointer to an
| object or to void, allowing a function to be inspected or
| modified (for example, by a debugger) (6.5.4).
|
| ... which makes it more obviously not part of standard C.

In 9989-1999 (admittedly, just the draft C99 standard, and not the
/actual standard itself), the printf() function documentation in
7.19.6.3 refers the reader to the fprintf() documentation for a
description of it's input. The fprintf() documentation in 7.19.6.1 says
of the %p format

~ p The argument shall be a pointer to void. The value of the pointer is
~ converted to a sequence of printing characters, in an
~ implementation-defined manner.

So, to satisfy the %p format character, the argument to
fprintf()/printf() /must/ be a "pointer to void". Since main is a
"pointer to function returning int", and not a "pointer to void", I
interpreted the documentation as requiring a cast to void pointer.


I interpret it as meaning that printing the address of a function
isn't something that you are guaranteed to be able to do.


So do I. You certainly cannot do it with the `%p' specifier. 6.3.2.3#1
makes it quite clear that only pointers to incomplete or object type can
be converted to `void *'.

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #36

P: n/a
pete <pf*****@mindspring.com> writes:
Lew Pitcher wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

pete wrote:
| Martin Dickopp wrote:
|
|>Lew Pitcher <lp******@sympatico.ca> writes:
|>
|>
|>>#include <stdio.h>
|>>#include <stdlib.h>
|>>
|>>int main(void)
|>>{
|>> printf("main() at %p\n",(void *)&main);
|>>
|>> return EXIT_SUCCESS;
|>>}
|>
|>Is the cast to `void *' valid?
|
|
| No.
|
| In N869, it's one of the common extensions.
|
| J.5.7 Function pointer casts
| [#2] A pointer to a function may be cast to a pointer to an
| object or to void, allowing a function to be inspected or
| modified (for example, by a debugger) (6.5.4).
|
| ... which makes it more obviously not part of standard C.

In 9989-1999 (admittedly, just the draft C99 standard, and not the
/actual standard itself), the printf() function documentation in
7.19.6.3 refers the reader to the fprintf() documentation for a
description of it's input. The fprintf() documentation in 7.19.6.1 says
of the %p format

~ p The argument shall be a pointer to void. The value of the pointer is
~ converted to a sequence of printing characters, in an
~ implementation-defined manner.

So, to satisfy the %p format character, the argument to
fprintf()/printf() /must/ be a "pointer to void". Since main is a
"pointer to function returning int", and not a "pointer to void", I
interpreted the documentation as requiring a cast to void pointer.


I interpret it as meaning that printing the address of a function
isn't something that you are guaranteed to be able to do.


So do I. You certainly cannot do it with the `%p' specifier. 6.3.2.3#1
makes it quite clear that only pointers to incomplete or object type can
be converted to `void *'.

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #37

P: n/a
Richard Bos wrote:
Martin Dickopp <ex****************@zero-based.org> wrote:
Lew Pitcher <lp******@sympatico.ca> writes:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
printf("main() at %p\n",(void *)&main);

return EXIT_SUCCESS;
}


Is the cast to `void *' valid?


No. Mind you, there is no better way to print the address of a function,
either. Where this works, it works; where it doesn't, nothing else is
likely to.


Yes there is a better way.
The code below will still print the binary representation of the
address of the function where %p won't. Even if
sizeof(int(*)()) is bigger than sizeof(void*).

The trick is that even when you might not convert function ptr
to void*, nobody said you cannot convert the (&fptr)
to the (void*) :-), see below :

/* dump address of the function no matter whether it can be
* converted to void* or not */
#include <stdio.h>
#include <stdlib.h>

typedef int (*fptr_t)();
void dump_hex( FILE* out, void* p, int len)
{
unsigned char *pb = p;
int i;
for(i=0; i < len; i++)
printf("%02X", 0xFF & (unsigned int)pb[i] );
}

void dump_function_addr(const char* fname, fptr_t fptr) {
printf("function %s() is at [", fname);
dump_hex( stdout, (void*)&fptr, sizeof(fptr) );

/* nb: you might not convert &main to void*, but */
/* nobody said we cannot convert '&fptr' to void* :-) */

printf("]\n");
}

int main(void)
{
dump_function_addr("main", main );

return EXIT_SUCCESS;
}
--
Yakov
Nov 14 '05 #38

P: n/a
Richard Bos wrote:
Martin Dickopp <ex****************@zero-based.org> wrote:
Lew Pitcher <lp******@sympatico.ca> writes:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
printf("main() at %p\n",(void *)&main);

return EXIT_SUCCESS;
}


Is the cast to `void *' valid?


No. Mind you, there is no better way to print the address of a function,
either. Where this works, it works; where it doesn't, nothing else is
likely to.


Yes there is a better way.
The code below will still print the binary representation of the
address of the function where %p won't. Even if
sizeof(int(*)()) is bigger than sizeof(void*).

The trick is that even when you might not convert function ptr
to void*, nobody said you cannot convert the (&fptr)
to the (void*) :-), see below :

/* dump address of the function no matter whether it can be
* converted to void* or not */
#include <stdio.h>
#include <stdlib.h>

typedef int (*fptr_t)();
void dump_hex( FILE* out, void* p, int len)
{
unsigned char *pb = p;
int i;
for(i=0; i < len; i++)
printf("%02X", 0xFF & (unsigned int)pb[i] );
}

void dump_function_addr(const char* fname, fptr_t fptr) {
printf("function %s() is at [", fname);
dump_hex( stdout, (void*)&fptr, sizeof(fptr) );

/* nb: you might not convert &main to void*, but */
/* nobody said we cannot convert '&fptr' to void* :-) */

printf("]\n");
}

int main(void)
{
dump_function_addr("main", main );

return EXIT_SUCCESS;
}
--
Yakov
Nov 14 '05 #39

P: n/a
Lew Pitcher wrote:
pete wrote:
| Martin Dickopp wrote:
|>Lew Pitcher <lp******@sympatico.ca> writes:
|>
|>> #include <stdio.h>
|>> #include <stdlib.h>
|>>
|>> int main(void)
|>> {
|>> printf("main() at %p\n",(void *)&main);
|>>
|>> return EXIT_SUCCESS;
|>> }
|>
|> Is the cast to `void *' valid?
|
| No.
|
| In N869, it's one of the common extensions.
|
| J.5.7 Function pointer casts
| [#2] A pointer to a function may be cast to a pointer to
| an object or to void, allowing a function to be inspected
| or modified (for example, by a debugger) (6.5.4).
|
| ... which makes it more obviously not part of standard C.

In 9989-1999 (admittedly, just the draft C99 standard, and not
the /actual standard itself), the printf() function documentation
in 7.19.6.3 refers the reader to the fprintf() documentation for
a description of it's input. The fprintf() documentation in
7.19.6.1 says of the %p format

~ p The argument shall be a pointer to void. The value of the
~ pointer is converted to a sequence of printing characters, in
~ an implementation-defined manner.

So, to satisfy the %p format character, the argument to
fprintf()/printf() /must/ be a "pointer to void". Since main is a
"pointer to function returning int", and not a "pointer to void", I
interpreted the documentation as requiring a cast to void pointer.


A better interpretation is that you may not be able to pass the
address of a function to printf. What if you are executing on a
system that dynamically loads and unloads functions, for example.
That address might be a tape volume name and offset, and require
operator intervention to resolve. The data just does not fit into
a void*.

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

P: n/a
Lew Pitcher wrote:
pete wrote:
| Martin Dickopp wrote:
|>Lew Pitcher <lp******@sympatico.ca> writes:
|>
|>> #include <stdio.h>
|>> #include <stdlib.h>
|>>
|>> int main(void)
|>> {
|>> printf("main() at %p\n",(void *)&main);
|>>
|>> return EXIT_SUCCESS;
|>> }
|>
|> Is the cast to `void *' valid?
|
| No.
|
| In N869, it's one of the common extensions.
|
| J.5.7 Function pointer casts
| [#2] A pointer to a function may be cast to a pointer to
| an object or to void, allowing a function to be inspected
| or modified (for example, by a debugger) (6.5.4).
|
| ... which makes it more obviously not part of standard C.

In 9989-1999 (admittedly, just the draft C99 standard, and not
the /actual standard itself), the printf() function documentation
in 7.19.6.3 refers the reader to the fprintf() documentation for
a description of it's input. The fprintf() documentation in
7.19.6.1 says of the %p format

~ p The argument shall be a pointer to void. The value of the
~ pointer is converted to a sequence of printing characters, in
~ an implementation-defined manner.

So, to satisfy the %p format character, the argument to
fprintf()/printf() /must/ be a "pointer to void". Since main is a
"pointer to function returning int", and not a "pointer to void", I
interpreted the documentation as requiring a cast to void pointer.


A better interpretation is that you may not be able to pass the
address of a function to printf. What if you are executing on a
system that dynamically loads and unloads functions, for example.
That address might be a tape volume name and offset, and require
operator intervention to resolve. The data just does not fit into
a void*.

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

P: n/a

On Wed, 7 Apr 2004, Leor Zolman wrote:

Curious -- I've never considered how implicit conversion rules ought to
play out in the arena of variadic functions... on one hand, pointers to
/anything/ implicitly convert to pointer-to-void, but on the other hand
there's no declaration for the receiving pointer-to-void.

Or, does the implicit conversion apply when the pointer value is extracted
and cast to void * in the receiving function?


I don't understand what you mean. Pointer-to-foo and pointer-to-void
can be implicitly "inter-converted" like this:

foo *pf;
void *pv;

pf = pv; pv = pf;

Likewise, 'pf' passed to a function prototyped as expecting a void
pointer will be implicitly converted. And vice versa.
Variadic functions are by definition not prototyped as expecting
anything in particular in the "..." part. So when you have

printf("foo", pf);

the value of 'pf' is passed to 'printf' as a pointer to foo, no
matter what the function actually expects. Likewise, in

printf("foo", pv);

'pv' is passed as a pointer to void.
Does that clear up your doubts?

HTH,
-Arthur

Nov 14 '05 #42

P: n/a

On Wed, 7 Apr 2004, Leor Zolman wrote:

Curious -- I've never considered how implicit conversion rules ought to
play out in the arena of variadic functions... on one hand, pointers to
/anything/ implicitly convert to pointer-to-void, but on the other hand
there's no declaration for the receiving pointer-to-void.

Or, does the implicit conversion apply when the pointer value is extracted
and cast to void * in the receiving function?


I don't understand what you mean. Pointer-to-foo and pointer-to-void
can be implicitly "inter-converted" like this:

foo *pf;
void *pv;

pf = pv; pv = pf;

Likewise, 'pf' passed to a function prototyped as expecting a void
pointer will be implicitly converted. And vice versa.
Variadic functions are by definition not prototyped as expecting
anything in particular in the "..." part. So when you have

printf("foo", pf);

the value of 'pf' is passed to 'printf' as a pointer to foo, no
matter what the function actually expects. Likewise, in

printf("foo", pv);

'pv' is passed as a pointer to void.
Does that clear up your doubts?

HTH,
-Arthur

Nov 14 '05 #43

P: n/a
> Undefined behaviour. The standard doesn't define conversions between
function pointers and incomplete or object pointer types. And there is no
guarantee that the type pointer to void is wide enough to be able to
represent the result of such a conversion.

6.3.2.3 Pointers

1 A pointer to void may be converted to or from a pointer to any
incomplete or object type...
^^^^^^^^^^^^^^^^^^^^^^^^^

7 A pointer to an object or incomplete type may be converted to
a pointer to a different object or incomplete type...

8 A pointer to a function of one type may be converted to a pointer
to a function of another type and back again; the result shall
compare equal to the original pointer...

Dan


Can a pointer to a function be converted to an integer type such as
size_t such that one could use printf("0x%x\n", (size_t)main); ?

Hmmm, now that I think of it, is it legal (according to the standard)
to convert between pointer and integer types at all?
Nov 14 '05 #44

P: n/a
> Undefined behaviour. The standard doesn't define conversions between
function pointers and incomplete or object pointer types. And there is no
guarantee that the type pointer to void is wide enough to be able to
represent the result of such a conversion.

6.3.2.3 Pointers

1 A pointer to void may be converted to or from a pointer to any
incomplete or object type...
^^^^^^^^^^^^^^^^^^^^^^^^^

7 A pointer to an object or incomplete type may be converted to
a pointer to a different object or incomplete type...

8 A pointer to a function of one type may be converted to a pointer
to a function of another type and back again; the result shall
compare equal to the original pointer...

Dan


Can a pointer to a function be converted to an integer type such as
size_t such that one could use printf("0x%x\n", (size_t)main); ?

Hmmm, now that I think of it, is it legal (according to the standard)
to convert between pointer and integer types at all?
Nov 14 '05 #45

P: n/a
On Wed, 7 Apr 2004 16:04:10 -0400 (EDT), "Arthur J. O'Dwyer"
<aj*@nospam.andrew.cmu.edu> wrote:

On Wed, 7 Apr 2004, Leor Zolman wrote:

Curious -- I've never considered how implicit conversion rules ought to
play out in the arena of variadic functions... on one hand, pointers to
/anything/ implicitly convert to pointer-to-void, but on the other hand
there's no declaration for the receiving pointer-to-void.

Or, does the implicit conversion apply when the pointer value is extracted
and cast to void * in the receiving function?
I don't understand what you mean. Pointer-to-foo and pointer-to-void
can be implicitly "inter-converted" like this:

foo *pf;
void *pv;

pf = pv; pv = pf;

Yes, of course.
Likewise, 'pf' passed to a function prototyped as expecting a void
pointer will be implicitly converted. And vice versa.
No questions there.
Variadic functions are by definition not prototyped as expecting
anything in particular in the "..." part. So when you have

printf("foo", pf);

the value of 'pf' is passed to 'printf' as a pointer to foo, no
matter what the function actually expects.
And therein lies my question. If pf has type pointer-to-foo, but is printed
using a %p format conversion, that represents a foo* -> void* conversion
without the compiler's "knowledge"... when the internals of printf extract
that argument, it will at some point be "converted" into a void *, but
without any knowledge of what it was "before". So is such an implicit
conversion officially permitted? I've been writing code that does that
forever, and it makes me wonder...

Lew pointed out 7.19.6.1, where it says "the argument [to %p] shall be a
pointer to void. Pete above points out how (explicit) conversion of a
pointer-to-function into a pointer-to-void is a "common extension" (so it
is definitely bad karma to omit the cast with a pointer-to-function)...but
what is the Standard's take on performing no cast whatsoever on a
pointer-to-something-/else/ (not a function, and not void)? IOW, is:
int i, *pi = &i;
printf("%p\n", pi);
conformant?
Likewise, in

printf("foo", pv);

'pv' is passed as a pointer to void.
This is the case that seems well-defined to me, in the case of a %p
conversion.
Does that clear up your doubts?
Does that clear up my question? :-)

I'm quite a newbie at Standard-reading, my implementation experience
limited to a very crude subset of pre-C89 C. So please view my questions as
/questions/, rather than any deliberate attempt to suggest a problem with
the Standard. If I do happen to stumble across any problems (and I guess I
may have come close on one or two occasions, even if they weren't
original), that's purely by accident.
-leor

HTH,
-Arthur


--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Nov 14 '05 #46

P: n/a
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

El Wed, 07 Apr 2004 10:07:15 +0200, Martin Dickopp escribió:

Is the cast to `void *' valid? I cannot find anything in the standard
which allows a pointer to a function to be converted to type `void *'.


Hi, I'm new to this group, just a couple of days reading. I can see you
are constantly referring to the "Standard" and I've seen in the FAQ that
you must pay for it ($18 electronic document).

All of you have payed for it? shouldn't a "standard" be free?

Thanks in advance and sorry for my english
- --
Alberto Giménez, SimManiac en el IRC
http://www.almorranasozial.es.vg
GNU/Linux Debian Woody 3.0 GnuPG ID: 0x3BAABDE1
Linux registered user #290801
WinError 01E: Timing error - Please wait. And wait. And wait. And wait.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQFAdHAp0keCtzuqveERAuOuAJ0cl6hlfaq+ikGVVKTthj/DUgaJVwCaAiRb
4mdlpHHPze7fArdyUEuEe5U=
=uj/E
-----END PGP SIGNATURE-----
Nov 14 '05 #47

P: n/a
On Wed, 7 Apr 2004 23:18:33 +0200, Alberto Giménez <al****@teleline.es>
wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

El Wed, 07 Apr 2004 10:07:15 +0200, Martin Dickopp escribió:

Is the cast to `void *' valid? I cannot find anything in the standard
which allows a pointer to a function to be converted to type `void *'.
Hi, I'm new to this group, just a couple of days reading. I can see you
are constantly referring to the "Standard" and I've seen in the FAQ that
you must pay for it ($18 electronic document).

All of you have payed for it? shouldn't a "standard" be free?


I tried using the free version of the "Draft" Standard that's floating
around, and which I guess is legitimately downloadable (although I couldn't
find it last time I looked) for free. But there are enough differences that
I soon (happily) forked over the $18 for my electronic copy of the Real
McCoy.

Compared to what the committee members had to pay in order to cover their
own expenses just to be on the Standard committee, we're getting a bargain
;-)
-leor

Thanks in advance and sorry for my english


--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Nov 14 '05 #48

P: n/a

On Wed, 7 Apr 2004, Leor Zolman wrote:

Arthur O'Dwyer <aj*@nospam.andrew.cmu.edu> wrote:
Variadic functions are by definition not prototyped as expecting
anything in particular in the "..." part. So when you have

printf("foo", pf);

the value of 'pf' is passed to 'printf' as a pointer to foo, no
matter what the function actually expects.
And therein lies my question. If pf has type pointer-to-foo, but is printed
using a %p format conversion, that represents a foo* -> void* conversion
without the compiler's "knowledge"... when the internals of printf extract
that argument, it will at some point be "converted" into a void *, but
without any knowledge of what it was "before". So is such an implicit
conversion officially permitted? I've been writing code that does that
forever, and it makes me wonder...


If you pass a value of type T to a variadic function, and that function
is expecting a value of type U instead, then you have undefined behavior,
unless <some legalese involving cv-qualification>. It's not terribly
unintuitive, is it?
[I think N869 section 7.15.1.1 is wrong when it uses the word
"compatible" to describe what I think is really "having the same
alignment and size restrictions" or something like that. Unless
it was the Committee's intent to have all implementations pass
pointers into variadic functions *as void pointers*, and have an
implicit conversion take place inside 'va_arg'. Experts, please?]
All the exceptions I'm aware of are covered by N869 section 6.2.5.27,
which allows things like

struct foo p;
my_vfunc("actually retrieves a struct bar", &p);
unsigned char *p = <something>;
printf("%p", p);

Since 'unsigned char *' and 'void *' are guaranteed to have the same
representation (at least, according to my interpretation of the Standard;
I know some people think *all* character types are similar to 'void *',
and others think that only *at least one* character type is similar
to 'void *'), this is conforming code.
But it's so easy to add the cast every time and make sure, that it's
just not worth fiddling around with special cases. :)
Lew pointed out 7.19.6.1, where it says "the argument [to %p] shall be a
pointer to void. Pete above points out how (explicit) conversion of a
pointer-to-function into a pointer-to-void is a "common extension" (so it
is definitely bad karma to omit the cast with a pointer-to-function)...but
what is the Standard's take on performing no cast whatsoever on a
pointer-to-something-/else/ (not a function, and not void)? IOW, is:
int i, *pi = &i;
printf("%p\n", pi);
conform[ing]?


No. See above; 'int *' and 'void *' do not necessarily have the
same representation or alignment requirements.

-Arthur

Nov 14 '05 #49

P: n/a

On Wed, 7 Apr 2004, Alberto [iso-8859-1] Giménez wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
It would be nice if you could figure out some way to balance your
authentication interests against the readability of your message.
PGP signatures in the text of your message are ugly. (But attachments
are just evil.) Please consider turning off your PGP signature when
posting to Usenet.
El Wed, 07 Apr 2004 10:07:15 +0200, Martin Dickopp escribió:

Is the cast to `void *' valid? I cannot find anything in the standard
which allows a pointer to a function to be converted to type `void *'.
Hi, I'm new to this group, just a couple of days reading. I can see you
are constantly referring to the "Standard" and I've seen in the FAQ that
you must pay for it ($18 electronic document).

All of you have payed for it? shouldn't a "standard" be free?


That's what I think. ;-) But it costs a lot of money to fly
international experts out to ISO committee meetings to discuss the
state of the C language and suchlike, and it costs a lot of money
to print copies of the standard, and maintain web servers, and pay
salaries to ISO people, and convene meetings to deal with errata
and corrigenda. So I suppose ISO (and member organizations) have
a good reason to charge for copies of the Standard.

If you don't want to buy a copy -- I haven't, and I think I'm
not alone -- you can find electronic versions of N869, the last
public draft of the C99 standard, online somewhere. Google for
"N869".
- --


That is not a proper sig delimiter, as far as I know. The standard
signature delimiter on Usenet is two hyphens followed by a single space
and a newline, like this:

--
Arthur
Nov 14 '05 #50

89 Replies

This discussion thread is closed

Replies have been disabled for this discussion.