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

Regarding the sizeof a function

P: n/a
Hi,

I have written a program

void main()
{
printf("%d %d\n", sizeof main, sizeof(main()));
}

in this program the output is 1 and 4,

as i understood from the books, function name represents the address
of the function. i thought sizeof main should give 4 , and i don't
know why sizeof(main()) is giving 4, Can some one please explain what
the former one does and what the later one do?. Why is this behavior?

Appreciate your help in this regard.

Thanks,
Vikas.

Jun 15 '07 #1
Share this Question
Share on Google+
17 Replies


P: n/a
In article <11**********************@a26g2000pre.googlegroups .com>,
venkat <ve**********@gmail.comwrote:
printf("%d %d\n", sizeof main, sizeof(main()));
There are several other errors in your program, but

(a) Functions are not converted to function pointers when
used as the operand of sizeof. It's illegal to apply
sizeof to a function.

(b) It's illegal to apply sizeof to void, since it's an
incomplete type.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Jun 15 '07 #2

P: n/a
On Jun 15, 4:29 pm, rich...@cogsci.ed.ac.uk (Richard Tobin) wrote:
In article <1181906769.365502.273...@a26g2000pre.googlegroups .com>,

venkat <venkatavi...@gmail.comwrote:
printf("%d %d\n", sizeof main, sizeof(main()));

There are several other errors in your program, but

(a) Functions are not converted to function pointers when
used as the operand of sizeof. It's illegal to apply
sizeof to a function.

(b) It's illegal to apply sizeof to void, since it's an
incomplete type.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Hi Richard,

Thanks for replying, i haven't observed that much, i want to avoid the
return that is why i put void in the program , the program is give
below

main()
{
printf("%d %d\n", sizeof main, sizeof(main()));

return;

}

Jun 15 '07 #3

P: n/a
venkat said:

<snip>
Thanks for replying, i haven't observed that much, i want to avoid the
return that is why i put void in the program ,
But by doing so, you are no longer writing in C.
the program is give below

main()
{
printf("%d %d\n", sizeof main, sizeof(main()));
Undefined behaviour because you call a variadic function without a valid
prototype in scope. Solution: #include <stdio.h>

Undefined behaviour because you're passing size_t to printf when it's
expecting int. You do this twice. Solution: add casts to int. (A rare
correct use of a cast.)

Constraint violation requiring a diagnostic message because you're
trying to apply sizeof to an expression having function type. Solution:
don't apply sizeof to an expression having function type.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jun 15 '07 #4

P: n/a
venkat wrote:
>
.... snip ...
>
Thanks for replying, i haven't observed that much, i want to avoid
the return that is why i put void in the program , the program is
give below

main()
{
printf("%d %d\n", sizeof main, sizeof(main()));
return;
}
main returns an int. Say and do so. #include <stdio.h>. A call
to a variadic function without a prototype is an error, and
behaviour is undefined. sizeof can't be applied to functions.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jun 15 '07 #5

P: n/a
On Fri, 15 Jun 2007 11:26:09 -0000, venkat <ve**********@gmail.com>
wrote:
>Hi,

I have written a program

void main()
{
printf("%d %d\n", sizeof main, sizeof(main()));
}

in this program the output is 1 and 4,

as i understood from the books, function name represents the address
of the function. i thought sizeof main should give 4 , and i don't
know why sizeof(main()) is giving 4, Can some one please explain what
the former one does and what the later one do?. Why is this behavior?

Appreciate your help in this regard.
Your understanding is incorrect at several points.

When an unadorned function name (one without the argument
list) is evaluated, the result is a value of type pointer to function.

The operand of the sizeof operator is not evaluated. The
compiler merely determines the type.

The sizeof operator may not be applied to a function or to an
incomplete type.

Now look at your code.

main should return int.

You have no prototype for printf. Calling a variadic function
this way invokes undefined behavior.

Your second argument applies sizeof to a function. This
invokes undefined behavior.

Your format string promises that the third argument is of type
int. Your actual argument is of type size_t. More undefined
behavior.

In your code, the type of main() is void. void is an
incomplete type. More undefined behavior.

Since your code invokes undefined behavior, there is no way to explain
why it produced this output. There is no guarantee that it would
produce the same behavior if you reran it.

Your third argument
Remove del for email
Jun 15 '07 #6

P: n/a
venkat <ve**********@gmail.comwrites:
I have written a program

void main()
{
printf("%d %d\n", sizeof main, sizeof(main()));
}

in this program the output is 1 and 4,

as i understood from the books, function name represents the address
of the function. i thought sizeof main should give 4 , and i don't
know why sizeof(main()) is giving 4, Can some one please explain what
the former one does and what the later one do?. Why is this behavior?
The correct declaration is "int main(void)"; your compiler might
happen to allow "void main()", but it's non-standard and non-portable.
Writing non-standard code for the sake of avoiding a return statement
isn't worth it; just add a "return 0;" at the end. (The "return 0;"
might not be necessary, but it can't hurt.)

Since you call printf(), you need to add "#include <stdio.h>". This
is another of those things that's mandatory, but your compiler might
not be friendly enough to warn you about it.

It's illegal (a constraint violation, requiring a diagnostic) to apply
sizeof to a function name. It's also illegal to apply sizeof to an
expression of type void (you declared main() to return void, so the
expression main() is of type void). Your compiler may be allowing
these applications of sizeof as a non-portable extension. (gcc has
such an extension, but the output you're seeing is inconsistent with
the way gcc does this.)

printf's "%d" format expects an int argument; sizeof yields a value of
type size_t. If the rest of the program weren't incorrect, you could
avoid that problem by casting the arguments to type int.

Here's a corrected version of your program:

#include <stdio.h>
int main(void)
{
printf("%d %d\n", (int)sizeof &main, (int)sizeof main());
return 0;
}

This will print two numbers, the size in bytes of a function pointer
and the size in bytes of an int. I get "4 4" on one system, "8 4" on
another; there are other possibilities.

Here's an exercise for you. Read your compiler's documentation and
find out how to enable warning messages. Using your program as you
posted it, errors and all, figure out how to make your compiler warn
you about *all* the errors I've pointed out. It might not be able to
warn about the mismatch in the printf format, but it should be able to
diagnose the other problems. Once you've found the right set of
options, develop the habit of using them whenever you use the
compiler, and correct any problems it warns you about. And remember
that fixing your code so it doesn't produce any warnings is the only
*beginning* of writing correct code.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 15 '07 #7

P: n/a
Barry Schwarz <sc******@doezl.netwrites:
[...]
When an unadorned function name (one without the argument
list) is evaluated, the result is a value of type pointer to function.
[...]

*Unless* it's the operand of unary "&" or "sizeof" operator. &func
yields the address of the function; sizeof func, as you mention later,
is a constraint violation.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 15 '07 #8

P: n/a
Keith Thompson said:
Barry Schwarz <sc******@doezl.netwrites:
[...]
>When an unadorned function name (one without the argument
list) is evaluated, the result is a value of type pointer to
function.
[...]

*Unless* it's the operand of unary "&" or "sizeof" operator.
Read it again, Keith. Neither & nor sizeof evaluate their operands.
Barry was dealing with the evaluation case first, as a sort of "that's
what the OP thought was happening", to lead into his "but this is what
is actually happening" paragraph, which you snipped, but which dealt
with the sizeof issue perfectly well: "The operand of the sizeof
operator is not evaluated. The compiler merely determines the type."

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jun 15 '07 #9

P: n/a
Richard Heathfield <rj*@see.sig.invalidwrites:
Keith Thompson said:
>Barry Schwarz <sc******@doezl.netwrites:
[...]
>>When an unadorned function name (one without the argument
list) is evaluated, the result is a value of type pointer to
function.
[...]

*Unless* it's the operand of unary "&" or "sizeof" operator.

Read it again, Keith. Neither & nor sizeof evaluate their operands.
Barry was dealing with the evaluation case first, as a sort of "that's
what the OP thought was happening", to lead into his "but this is what
is actually happening" paragraph, which you snipped, but which dealt
with the sizeof issue perfectly well: "The operand of the sizeof
operator is not evaluated. The compiler merely determines the type."
Ok, fair enough.

IMHO the rule as stated in the standard is simpler to understand:
whenever an expression of function type appears (most commonly a
function name), it's converted to a pointer unless it's the operand of
a unary "&" or "sizeof"; for "&", the address is computed, and for
"sizeof", a constraint is violated.

There may be infinitely many ways to express this correctly.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 15 '07 #10

P: n/a
Richard Heathfield wrote:
Keith Thompson said:
>Barry Schwarz <sc******@doezl.netwrites:
[...]
>>When an unadorned function name (one without the argument
list) is evaluated, the result is a value of type pointer to
function.
[...]

*Unless* it's the operand of unary "&" or "sizeof" operator.

Read it again, Keith. Neither & nor sizeof evaluate their operands.
Evaluation of the unary & operator does cause evaluation of its operand, and
the conversion from function to pointer-to-function normally is part even
of expressions that are not evaluated. sizeof(main()) cannot be accepted if
the conversion from int(void) to int(*)(void) gets omitted just because the
expression is not evaluated.
Jun 15 '07 #11

P: n/a
Harald van =?UTF-8?B?RMSzaw==?= wrote:
Evaluation of the unary & operator
does cause evaluation of its operand,
No it doesn't.
There's no undefined behavior in the code below
even though the value of (A) is indeterminate.

/* BEGIN new.c */

int main(void)
{
int A;
int *B = &A;

return 0;
}

/* END new.c */
--
pete
Jun 15 '07 #12

P: n/a
pete wrote:
Harald van =?UTF-8?B?RMSzaw==?= wrote:
>Evaluation of the unary & operator
does cause evaluation of its operand,

No it doesn't.
Yes, it does.
There's no undefined behavior in the code below
even though the value of (A) is indeterminate.

/* BEGIN new.c */

int main(void)
{
int A;
int *B = &A;

return 0;
}

/* END new.c */
That's because the lvalue-to-value conversion is not performed. You're just
evaluating something different now: you're evaluating the lvalue A, rather
than the value stored at lvalue A.

The distinction matters: given
struct S { int member; };
struct S *f();

evaluation of &(f()->member) must result in a call to f.
Jun 15 '07 #13

P: n/a
Harald van Dijk <tr*****@gmail.comwrites:
Richard Heathfield wrote:
>Keith Thompson said:
>>Barry Schwarz <sc******@doezl.netwrites:
[...]
When an unadorned function name (one without the argument
list) is evaluated, the result is a value of type pointer to
function.
[...]

*Unless* it's the operand of unary "&" or "sizeof" operator.

Read it again, Keith. Neither & nor sizeof evaluate their operands.

Evaluation of the unary & operator does cause evaluation of its operand, and
the conversion from function to pointer-to-function normally is part even
of expressions that are not evaluated.
Actually, the operand of unary "&" is evaluated *as an lvalue*. For
example, &array[func()] will call func.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 15 '07 #14

P: n/a
Keith Thompson wrote:
Harald van Dijk <tr*****@gmail.comwrites:
>Richard Heathfield wrote:
>>Keith Thompson said:
Barry Schwarz <sc******@doezl.netwrites:
[...]
When an unadorned function name (one without the argument
list) is evaluated, the result is a value of type pointer to
function.
[...]

*Unless* it's the operand of unary "&" or "sizeof" operator.

Read it again, Keith. Neither & nor sizeof evaluate their operands.

Evaluation of the unary & operator does cause evaluation of its operand,
and the conversion from function to pointer-to-function normally is part
even of expressions that are not evaluated.

Actually, the operand of unary "&" is evaluated *as an lvalue*. For
example, &array[func()] will call func.
I'm not sure that's the best example. &array[func()] is equivalent to
&*(array+func()), and for the special case of an unary & operator with an
unary * operator as its operand, neither operator is evaluated.
Jun 15 '07 #15

P: n/a
In article <46***********@mindspring.com>,
pete <pf*****@mindspring.comwrote:
>Evaluation of the unary & operator
does cause evaluation of its operand,
>No it doesn't.
I don't have the standard handy so I can't check its definition of
"evaluate", but there's certainly a sense in which the operand of & is
evaluated, and it's much the same sense in which the left hand side of
an assignment is evaluated. If you have

&(a[3*x]->b)
or
a[3*x]->b = 1

then in both cases all of the "evaluation" of a[3*x]->b is done except
the last step, in order to determine the location referred to.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Jun 15 '07 #16

P: n/a

"Richard Heathfield" <rj*@see.sig.invalidwrote in message
news:x8*********************@bt.com...
venkat said:

<snip>
>Thanks for replying, i haven't observed that much, i want to avoid the
return that is why i put void in the program ,

But by doing so, you are no longer writing in C.
>the program is give below

main()
{
printf("%d %d\n", sizeof main, sizeof(main()));

Undefined behaviour because you call a variadic function without a valid
prototype in scope. Solution: #include <stdio.h>

Undefined behaviour because you're passing size_t to printf when it's
expecting int. You do this twice. Solution: add casts to int. (A rare
correct use of a cast.)
any reason why you dont advice to use %u? or even %zu for c99
Jun 16 '07 #17

P: n/a
Serve Laurijssen said:
"Richard Heathfield" wrote...
>venkat said:
<snip>
>> printf("%d %d\n", sizeof main, sizeof(main()));
<snip>
>>
Undefined behaviour because you're passing size_t to printf when it's
expecting int. You do this twice. Solution: add casts to int. (A rare
correct use of a cast.)

any reason why you dont advice to use %u? or even %zu for c99
Yes.

Normally I would advise %lu for C90, and %zu for C99, but I got the
impression that that would be TMI for this particular OP at this stage
in his education.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jun 16 '07 #18

This discussion thread is closed

Replies have been disabled for this discussion.