questions

A

aarklon

1) I have seen programs like this:-
#include<stdlib.h>
#include<stdio.h>

void f(j)
{ printf("\n j = %d",j); }

void fun(i){ void (*p)(int); p = f; p(100 + i); (p)(100 + i); }

int main(void)
{

void (*ptr)(int);
ptr = fun;

(*ptr)(222);
ptr(333);

puts("\nEND OF THE PROGRAM");
return(EXIT_SUCCESS);
}


does this mean that if we are defining a function without
explicitly specifying the type of the parameter,
will it default to int (signed or unsigned)???

2) how this program works..???

#include<stdlib.h>
#include<stdio.h>

char fun()
{
static i = 3;
int main = 10;

return
printf("%d\n",i-- > 0 ?i && fun():main);
}

int main(void)
{
fun();
puts("");
return(EXIT_SUCCESS);
}

o/p is given as :- 0 1 1

is ternary operator a sequence point...????
for the first time when the function is called
how will be i && fun() evaluated....???

assuming ternary operator is not sequence point

i && fun() will evaluate to 3 && fun()
is n't it then what value will fun() evaluate to...????

3) is there any concept of default return value for a function
returning int...???

suppose i am having a fn such as this

int myfun()
{


}

and i am calling it in main as
#include<stdio.h> main(){printf("%d",myfun())}

what value will it print by default...???


4) why the following program prints o/p correctly as far as my
understanding
goes this program returns address of local variable is n't
it...???
int* f()
{
int a = 12;
return &a;
}

int* fun()
{
int *b = f();

return b;
}

int main(void)
{

printf("\nfun = %d",*(fun()));

puts("");
return(EXIT_SUCCESS);
}
 
M

Mark Bluemel

1) I have seen programs like this:-
#include<stdlib.h>
#include<stdio.h>

void f(j)
{ printf("\n j = %d",j); }

void fun(i){ void (*p)(int); p = f; p(100 + i); (p)(100 + i); } [snip]
does this mean that if we are defining a function without
explicitly specifying the type of the parameter,
will it default to int (signed or unsigned)???

Yes - int, which is signed unless explicitly made unsigned.

This is for compatibility/consistency with pre-ansi code, I think.
2) how this program works..???

#include<stdlib.h>
#include<stdio.h>

char fun()
{
static i = 3;
int main = 10;

return
printf("%d\n",i-- > 0 ?i && fun():main);

This looks suspiciously like UB to me.
}

int main(void)
{
fun();
puts("");
return(EXIT_SUCCESS);
}

o/p is given as :- 0 1 1

is ternary operator a sequence point...????
for the first time when the function is called
how will be i && fun() evaluated....???
assuming ternary operator is not sequence point

i && fun() will evaluate to 3 && fun()
is n't it then what value will fun() evaluate to...????

My expectation is that fun() will always evaluate to a char with a value
of 2 (the number of characters output by printf).
3) is there any concept of default return value for a function
returning int...???
No

suppose i am having a fn such as this

int myfun() { }

A decent compiler, with appropriate options, should warn you about this.

(gcc with "-ansi -Wall -pedantic" said
"xxx.c: In function `fred':
xxx.c:10: warning: control reaches end of non-void function")
and i am calling it in main as
#include<stdio.h> main(){printf("%d",myfun())}

what value will it print by default...???

Any garbage that happens to be handy
4) why the following program prints o/p correctly as far as my
understanding
goes this program returns address of local variable is n't
it...???
int* f()
{
int a = 12;

initialize an auto int variable to 12.
return &a;

return the address of the variable
}

int* fun()

This function simply passes the address on
{
int *b = f();

return b;
}

int main(void)
{

printf("\nfun = %d",*(fun()));

This tries to access the data currently held in that address. Depending
on all sorts of factors, that could still be 12, or it may not. In your
case it was.
 
J

James Kuyper

1) I have seen programs like this:-
#include<stdlib.h>
#include<stdio.h>

void f(j)
{ printf("\n j = %d",j); }

void fun(i){ void (*p)(int); p = f; p(100 + i); (p)(100 + i); }

int main(void)
{

void (*ptr)(int);
ptr = fun;

(*ptr)(222);
ptr(333);

puts("\nEND OF THE PROGRAM");
return(EXIT_SUCCESS);
}


does this mean that if we are defining a function without
explicitly specifying the type of the parameter,
will it default to int (signed or unsigned)???

Having unspecified types default to 'int' (which is signed) was allowed
in older versions of the C language. Starting with C99, it's no longer
allowed.
2) how this program works..???

#include<stdlib.h>
#include<stdio.h>

char fun()
{
static i = 3;
int main = 10;

return
printf("%d\n",i-- > 0 ?i && fun():main);
}

int main(void)
{
fun();
puts("");
return(EXIT_SUCCESS);
}

o/p is given as :- 0 1 1

is ternary operator a sequence point...????

Yes, there is a sequence point after evaluation of the left operand
(6.5.15p4).
for the first time when the function is called
how will be i && fun() evaluated....???

The first time i is called, the side effects of the i-- expression will
have been completed before the && expression is evaluated. Therefore,
the value of 'i' will be 2. Since 'i' is non-zero, the right operand of
the && expression must be evaluated, resulting in a recursive call to fun().

In the second call to fun(), i starts out with a value of 2, so the &&
expression is evaluated. By that time, i is reduced to 1. Since Since
1!=0, a third call to fun() occurs.

In the third call to fun(), i starts out with a value of 1, so the &&
expression is evaluated. By that time, i has been reduced to 0. Since
it's left operand compares equal to 0, && doesn't need to evaluate it's
right operand, and the ?: expression has a a value of 0. This gets
printed out. printf() returns the number of characters printed, or a
negative value indicating failure; either way, it's value is non-zero.

Control returns to the second call to fun(). Since the value returned by
fun is non-zero, the value of the && expression is 1. This value gets
printed out, and the non-zero value returned by printf() is returned by fun.

Control returns to the first call to fun(). Since the value returned by
the second call to fun is non-zero, the value of the && expression is 1.
3) is there any concept of default return value for a function
returning int...???

No. It's a constraint violation to return from a function declared as
returning a value, unless you explicitly return a value.
4) why the following program prints o/p correctly as far as my
understanding
goes this program returns address of local variable is n't
it...???
int* f()
{
int a = 12;
return &a;
}

int* fun()
{
int *b = f();

return b;
}

int main(void)
{

printf("\nfun = %d",*(fun()));

puts("");
return(EXIT_SUCCESS);
}

The behavior of that program is undefined. That means that the C
standard imposes no restrictions on it's behavior. In particular, the C
standard doesn't prohibit that function from producing what you consider
"correct" output. By the way, what output do you consider "correct"? As
far as the C standard is concerned, any behavior whatsoever is equally
correct.
 
C

Christopher Benson-Manica

[comp.lang.c] James Kuyper said:
No. It's a constraint violation to return from a function declared as
returning a value, unless you explicitly return a value.

For the curious (including me), the constraint in question is
contained in 6.8.6.4p1 of n869. However, I would qualify that
statement as "It's a constraint violation to _explicitly_ return from
a function ...", given that the case of reaching the } terminating a
function is dealt with separately by 6.9.1p12.
 
J

Jack Klein

1) I have seen programs like this:-
#include<stdlib.h>
#include<stdio.h>

void f(j)
{ printf("\n j = %d",j); }

void fun(i){ void (*p)(int); p = f; p(100 + i); (p)(100 + i); } [snip]
does this mean that if we are defining a function without
explicitly specifying the type of the parameter,
will it default to int (signed or unsigned)???

Yes - int, which is signed unless explicitly made unsigned.

Only prior to 1999. Newer versions of the C standard, 1999 and later,
have made this code a constraint violation.

--
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
 
B

Barry Schwarz

1) I have seen programs like this:-
#include<stdlib.h>
#include<stdio.h>

void f(j)
{ printf("\n j = %d",j); }

void fun(i){ void (*p)(int); p = f; p(100 + i); (p)(100 + i); }

int main(void)
{

void (*ptr)(int);
ptr = fun;

(*ptr)(222);
ptr(333);

puts("\nEND OF THE PROGRAM");
return(EXIT_SUCCESS);
}


does this mean that if we are defining a function without
explicitly specifying the type of the parameter,
will it default to int (signed or unsigned)???

C99 deleted the "implicit int" feature. If you are compiling under
the old standard, the typeless arguments will be int (which is
signed).
2) how this program works..???

#include<stdlib.h>
#include<stdio.h>

char fun()
{
static i = 3;
int main = 10;

return
printf("%d\n",i-- > 0 ?i && fun():main);
}

int main(void)
{
fun();
puts("");
return(EXIT_SUCCESS);
}

o/p is given as :- 0 1 1

is ternary operator a sequence point...????

There is a sequence point after the first operand is evaluated (at the
?) but not after whichever other argument is evaluated.
for the first time when the function is called
how will be i && fun() evaluated....???

assuming ternary operator is not sequence point

Then you are not talking about C any more. If there is no sequence
point here, your program need not start in main. And then fun will
never get called.
i && fun() will evaluate to 3 && fun()
is n't it then what value will fun() evaluate to...????

Yes. And if fun returns 0, the expression will evaluate to 0. If fun
returns any other value, the expression will evaluate to 1.
3) is there any concept of default return value for a function
returning int...???

Only for main and only in C99.
suppose i am having a fn such as this

int myfun()
{


}

and i am calling it in main as
#include<stdio.h> main(){printf("%d",myfun())}

what value will it print by default...???

Since you invoke undefined behavior, it could print your telephone
number or your grandmother's birthdate. On a well-designed system
(tm), your program would terminate in error when it tried to return
from myfunc without returning a value and the printf would never
execute.
4) why the following program prints o/p correctly as far as my
understanding

Since you invoke undefined behavior, there is no such thing as correct
output. Or perhaps it should be phrased that any output is correct.
One of the worst kinds of UB is to appear to work as expected.
goes this program returns address of local variable is n't
it...???
int* f()
{
int a = 12;
return &a;

At the time the return statement executes, a still exists so &a is not
a problem (yet).
}

int* fun()
{
int *b = f();

Once f returns, a has ceased to exist. By definition, the address of
a becomes indeterminate. Attempting to assign this indeterminate
value to b invokes undefined behavior.
return b;
}

int main(void)
{

printf("\nfun = %d",*(fun()));

puts("");
return(EXIT_SUCCESS);
}


Remove del for email
 
A

Amandil

Only for main and only in C99.


Since you invoke undefined behavior, it could print your telephone
number or your grandmother's birthdate. On a well-designed system
(tm), your program would terminate in error when it tried to return
from myfunc without returning a value and the printf would never
execute.

I don't see why any system should have the program terminate in error.
On most systems (I believe) an int return value is returned in a
register, not on the stack. I think something (somewhere, perhaps K&R)
limited the size of a return value to the size of a register. Since
there is some value in the register, although that value is garbage
(as far as we are concerned) it exists, and therefore should not
generate an error.
Since you invoke undefined behavior, there is no such thing as correct
output. Or perhaps it should be phrased that any output is correct.
One of the worst kinds of UB is to appear to work as expected.


At the time the return statement executes, a still exists so &a is not
a problem (yet).



Once f returns, a has ceased to exist. By definition, the address of
a becomes indeterminate. Attempting to assign this indeterminate
value to b invokes undefined behavior.

As a practical explanation of why it 'seems' to work properly, a is
stored as a local variable of f(), usually on the stack. As the stack
has not yet been deallocated yet, *(fun()) doesn't cause a fault, and
as the stack has not yet been reused, the value (in stack space) is
still the same. If you would have saved the address and called another
function before the printf() call, the value likely would be
different.

-- Martie (Gandalf fell into the abyss; but he's all white now)
 
S

santosh

Amandil said:
I don't see why any system should have the program terminate in error.
On most systems (I believe) an int return value is returned in a
register, not on the stack. I think something (somewhere, perhaps K&R)
limited the size of a return value to the size of a register.

No. Composite objects like structures can be returned, and they most
certainly won't likely fit in a machine register.
Since
there is some value in the register, although that value is garbage
(as far as we are concerned) it exists, and therefore should not
generate an error.

Not if the machine implements trap representations. The compiler could
initialise unused objects with a trap value whose access could trigger
an exception.

<snip>
 
F

Flash Gordon

Amandil wrote, On 23/11/07 04:43:
I don't see why any system should have the program terminate in error.

When undefined behaviour is invoked there does not have to be a reason.
On most systems (I believe) an int return value is returned in a
register, not on the stack.

Most is not all. Once you know all current implementations (not
practical) you then have to find out about all future implementations
before you can make general statements about undefined behaviour on any
system.
I think something (somewhere, perhaps K&R)
limited the size of a return value to the size of a register.

So tell me how you can fit a 16 bit int in to an 8 bit register. Yes,
there are still C implementations for 8 bit processors.
Since
there is some value in the register, although that value is garbage
(as far as we are concerned) it exists, and therefore should not
generate an error.

<snip>

Perhaps someone will develop a processor with a "valid" bit on registers
where you get a SIGSEGV if you read from a register that does not have
the valid bit set. The program could clear the valid bit on the "return
value" register since according to the rules of C you are not permitted
to use the value if it was not returned. In fact, this would be a
sensible thing to implement on a debugging implementation even if the HW
did not support it.

Another reason that you might get strange effects is that an optimiser
could make assumptions that are not true, assumptions it is allowed to
make because the C standard says that it is up to the programmer to
ensure that they are true.
 
N

Nick Keighley

I'd hope it wouldn't even compile

I don't see why any system should have the program terminate in error.

because it's undefined behaviour?

On most systems (I believe) an int return value is returned in a
register, not on the stack.


typedef struct
{
int x [110000];
} Biggun;


Biggun get_one()
{
Biggun b;
return b;
}

admittedly the only time I saw this it was an accident.
I believe we only had a 4k stack at the time...

I think something (somewhere, perhaps K&R)
limited the size of a return value to the size of a register.

you are mistaken.

Since
there is some value in the register, although that value is garbage
(as far as we are concerned) it exists, and therefore should not
generate an error.

people mentioned trap values. I have actually used a platform
that used 1's complement and initialied everything to -0.
Reading -0 invoked a hardware trap. (Admittedly this wasn't
a C implementaion).



<snip>

--
Nick Keighley

"High Integrity Software: The SPARK Approach to Safety and Security"
Customers interested in this title may also be interested in:
"Windows XP Home"
(Amazon)
 
A

aarklon

As a practical explanation of why it 'seems' to work properly, a is
stored as a local variable of f(), usually on the stack. As the stack
has not yet been deallocated yet, *(fun()) doesn't cause a fault, and
as the stack has not yet been reused, the value (in stack space) is
still the same. If you would have saved the address and called another
function before the printf() call, the value likely would be
different.

-- Martie (Gandalf fell into the abyss; but he's all white now)

okay i verified what you have said.
you are correct.thanks for making this subtle matter clear
 
J

J. J. Farrell

Amandil said:
I don't see why any system should have the program terminate in error.

Because it invokes undefined behaviour. Anything can happen. An
excellent implementation would spot and report this at compile time, a
slightly less excellent implementation could spot it at run time. Many
won't spot it at all and you'll be left with random behaviour.
On most systems (I believe) an int return value is returned in a
register, not on the stack.

What about the rest of the systems?
I think something (somewhere, perhaps K&R)
limited the size of a return value to the size of a register.

You think incorrectly.
Since
there is some value in the register, although that value is garbage
(as far as we are concerned) it exists, and therefore should not
generate an error.

Probably true on systems which happen to work that way. What about all
the other systems?
 
B

Barry Schwarz

I don't see why any system should have the program terminate in error.

So that someone who sees "an expected result" doesn't fall into the
trap of thinking his code is correct. Since this particular type of
undefined behavior is detectable by the compiler, there is no reason
the generated code should leave any doubt in the user's mind.
On most systems (I believe) an int return value is returned in a
register, not on the stack. I think something (somewhere, perhaps K&R)
limited the size of a return value to the size of a register. Since

I guess you have never returned a large struct from a function.
there is some value in the register, although that value is garbage
(as far as we are concerned) it exists, and therefore should not
generate an error.

So you recommend letting the code continue to run with some residual
value. No thank you. I prefer my system to help me as much as
possible debug coding errors. This doesn't even involve a performance
degradation the way subscript range checks would.

snip


Remove del for email
 
D

David Thompson

[comp.lang.c] James Kuyper said:
No. It's a constraint violation to return from a function declared as
returning a value, unless you explicitly return a value.

For the curious (including me), the constraint in question is
contained in 6.8.6.4p1 of n869. However, I would qualify that
statement as "It's a constraint violation to _explicitly_ return from
a function ...", given that the case of reaching the } terminating a
function is dealt with separately by 6.9.1p12.

And, since James (and others) pointed out correctly that implicit-int
was legal before C99, I'd add that this constraint is also new in C99;
before that 'return;' in a nonvoid function was allowed, but using the
indeterminate result was UB. (The other constraint, that you can't use
'return expr;' in a void function, was in C89 and unchanged in C99.)

- formerly david.thompson1 || achar(64) || worldnet.att.net
 

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,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top