Strange Behaviour of this function

G

g.ankush1

#include <stdio.h>


/* 1st example

int a()
{
return 1;

}

b()
{

}


int main()
{

int x;
a();
x=b();

printf("%d",x);

}

*/


// 2nd example


int a()
{
return 1;

}

b()
{
a();
}

int main()
{

int x;
x=b();
printf("%d",x);
}


Please see the first example and the second example. I don't know why
is there a difference of output. I tried it running in vc ++ 6.0

Thanks in advance

Regards
Ankush
 
?

=?ISO-8859-1?Q?=22Nils_O=2E_Sel=E5sdal=22?=

#include <stdio.h>


/* 1st example

int a()
{
return 1;

}

b()
{

}


int main()
{

int x;
a();
x=b();

printf("%d",x);

}

*/


// 2nd example


int a()
{
return 1;

}

b()
{
a();
}

int main()
{

int x;
x=b();
printf("%d",x);
}


Please see the first example and the second example. I don't know why
is there a difference of output. I tried it running in vc ++ 6.0

Your code exhibits undefined behavior.
You 'b' function is declared without a return type, which means it
defaults to int. Yet you don't return an int from it -- you should,
note that main also is declared to return an int, so return an int
from main too.
 
K

Keith Thompson

#include <stdio.h>


/* 1st example

int a()
{
return 1;

}

b()
{

}

You didn't specify a return type for the function b. In C89/C90, it
defaults to int. In C99, the "implicit int" feature has been removed.
It's always better to specify the type explicitly.

You don't return a value from the function. You need to.
int main()
{

int x;
a();
x=b();

Here you use the value returned by b(), but there's no return
statement in b. This could assign any arbitrary value to x.
printf("%d",x);

}

*/


// 2nd example


int a()
{
return 1;

}

b()
{
a();
}

Same thing as the first example.
int main()
{

int x;
x=b();

And again, you assign some garbage value to x.
printf("%d",x);
}


Please see the first example and the second example. I don't know why
is there a difference of output. I tried it running in vc ++ 6.0

You get garbage in both cases. It happens to be different garbage.
Don't worry about why it's different, just fix the program.
 
P

Peter Nilsson

[whitespace modified...]
You didn't specify a return type for the function b. In C89/C90, it
defaults to int. In C99, the "implicit int" feature has been removed.
It's always better to specify the type explicitly.

You don't return a value from the function. You need to.

You need to if you want to use the return value. If there is no
return value, and the caller doesn't expect one, then there isn't
actually a requirement to return one in either C90 or C99.
[C99's dumping of implicit int notwithstanding. The story is
different in C++.]
Here you use the value returned by b(), but there's no return
statement in b. This could assign any arbitrary value to x.

No. It's not a question of what arbitrary value gets returned.
Merely attempting to make such a call is undefined behaviour
in itself.

Even if b() had a return type of unsigned char, UB would still
be invoked.
 
K

Keith Thompson

Peter Nilsson said:
[whitespace modified...]
You didn't specify a return type for the function b. In C89/C90, it
defaults to int. In C99, the "implicit int" feature has been removed.
It's always better to specify the type explicitly.

You don't return a value from the function. You need to.

You need to if you want to use the return value. If there is no
return value, and the caller doesn't expect one, then there isn't
actually a requirement to return one in either C90 or C99.
[C99's dumping of implicit int notwithstanding. The story is
different in C++.]

He needs to return a value whether the standard requires it or not.
Or at least he should.
No. It's not a question of what arbitrary value gets returned.
Merely attempting to make such a call is undefined behaviour
in itself.

Even if b() had a return type of unsigned char, UB would still
be invoked.

And one possible consequence of UB is assigning some arbitrary value
to x.
 
K

Kenny McCormack

Keith Thompson said:
He needs to return a value whether the standard requires it or not.

I don't think one is allowed to say that here. In any context.
You, of all people, would know that.
 
P

Peter Nilsson

Keith said:
And one possible consequence of UB is assigning some arbitrary value
to x.

One possible consequence, yes. However, your original statement can be
read to imply that an arbitrary value is the _only_ possible
consequence.
More specifically, you imply that on an implementation where int has
no trap representations, an unspecified value _will_ be returned.

Consider...

This *could* assign any arbitrary value to x.
This could assign *any* arbitrary value to x.

The latter form was how I initially read your statement. In context,
the
emphasis can subtly change the interpretation of 'could' to mean
'will'.

If you believe your original statement cannot possibly be
misinterpreted,
then I regret to say that (like many clc readers no doubt) my first
language was not English. [Of course, I did study it at school here in
Australia. ... Damn neary passed too... ;-]
 
A

Andrew Poelstra

#include <stdio.h>
/* 1st example */

#if 0
int a(void) { return 1; }
int b(void) {}

int main(void)
{
int x;
a();
x = b();
printf("%d", x);
return 0;
}
#endif

/* 2nd example */

int a(void) { return 1; }
int b(void) { a(); }

int main()
{
int x;
x = b();
printf("%d", x);
return 0;
}


Please see the first example and the second example. I don't know why
is there a difference of output. I tried it running in vc ++ 6.0

Don't use tabs on Usenet. Don't use // comments on Usenet. Don't use
excess newlines on Usenet. Don't compress your expressions horizontally;
spaces are not evil. Don't use /*...*/ comments to eliminate code; use
#if 0...#endif comments. Don't rely on implicit int. Explicitly state
the arguments of functions as void, unless you have a reason not to.
main() returns int. main() returns int. main() returns int. Return
something from main().

I've fixed all of the above for you.


Look carefully at your functions above, and tell me what b() returns.
 
K

Keith Thompson

Peter Nilsson said:
One possible consequence, yes. However, your original statement can be
read to imply that an arbitrary value is the _only_ possible
consequence.
More specifically, you imply that on an implementation where int has
no trap representations, an unspecified value _will_ be returned.
[...]

You're right, attempting to use the result invokes undefined behavior.
C99 6.9.1p12 says:

If the } that terminates a function is reached, and the value of
the function call is used by the caller, the behavior is
undefined.

And yes, my statement could be read either way. Frankly, I didn't
stop to think about whether it invokes undefined behavior or not. I
was responding to a poster who, by the looks of his code, probably
doesn't know what "undefined behavior" is, and the distinction between
undefined behavior and an unspecified value didn't seem important at
the time. The conclusion is the same either way: Don't Do That.

I suppose I could have been more precise.
 
K

Keith Thompson

Andrew Poelstra said:
#include <stdio.h>
/* 1st example */ [snip]
/* 2nd example */ [snip]

Please see the first example and the second example. I don't know why
is there a difference of output. I tried it running in vc ++ 6.0

Don't use tabs on Usenet. Don't use // comments on Usenet. Don't use
excess newlines on Usenet. Don't compress your expressions horizontally;
spaces are not evil. Don't use /*...*/ comments to eliminate code; use
#if 0...#endif comments. Don't rely on implicit int. Explicitly state
the arguments of functions as void, unless you have a reason not to.
main() returns int. main() returns int. main() returns int. Return
something from main().

I've fixed all of the above for you.

Andrew, as a matter of etiquette, if you're going to modify posted
code, please don't do it in-place. Your followup made it appear as if
the OP has written the modified code. It would have been much clearer
to post your modified version of his code *as new text*, without the
"> " prefix.

(We've had cases here of people *deliberately* altering quoted text
without saying they've done so -- which I'm certain was not your
intent.)
 
A

Andrew Poelstra

Andrew, as a matter of etiquette, if you're going to modify posted
code, please don't do it in-place. Your followup made it appear as if
the OP has written the modified code. It would have been much clearer
to post your modified version of his code *as new text*, without the
"> " prefix.

(We've had cases here of people *deliberately* altering quoted text
without saying they've done so -- which I'm certain was not your
intent.)

In this case I made some actual changes to his code.

However, if I was only adding spacing or replacing tabs, would that be
okay?
 
K

Keith Thompson

Andrew Poelstra said:
In this case I made some actual changes to his code.

However, if I was only adding spacing or replacing tabs, would that be
okay?

I don't think there's necessarily any consensus on where the line
should be drawn, so all I can offer is my own opinion.

Expanding tabs is ok. Changing the visible layout, IMHO, is not; if
the code is badly formatted, don't pretend that the OP actually wrote
something that's well formatted. (I'd say changing indentation levels
is *probably* ok if you clearly state you've done it; adding or
removing braces is not.)

If some posted piece of code is so ugly you can't stand it, feel free
to fix it *in your own original text*. If you want to post just your
corrected version without quoting the original, that's ok, as long as
you say what you're doing.

In English text, reformatting paragraphs is ok as long as it doesn't
change the meaning or the wording (I often do so when the original
text as very long and/or ragged lines ). Correcting misspellings or
punctuation errors is not; it's too easy to guess wrong about what was
meant. I usually ignore spelling, grammar, and punctuation errors
unless they make it difficult to read the text; in that case, I might
post corrected text, but not as a quotation.

The meaning of a "> " prefix is "this is a direct quotation from the
previous article". Don't use it if that's not what you mean.

Again, this is all my opinion.
 
C

CBFalconer

Keith said:
I don't think there's necessarily any consensus on where the line
should be drawn, so all I can offer is my own opinion.

Expanding tabs is ok. Changing the visible layout, IMHO, is not;
if the code is badly formatted, don't pretend that the OP actually
wrote something that's well formatted. (I'd say changing
indentation levels is *probably* ok if you clearly state you've
done it; adding or removing braces is not.)

If some posted piece of code is so ugly you can't stand it, feel
free to fix it *in your own original text*. If you want to post
just your corrected version without quoting the original, that's
ok, as long as you say what you're doing.

In English text, reformatting paragraphs is ok as long as it
doesn't change the meaning or the wording (I often do so when the
original text as very long and/or ragged lines ). Correcting
misspellings or punctuation errors is not; it's too easy to guess
wrong about what was meant. I usually ignore spelling, grammar,
and punctuation errors unless they make it difficult to read the
text; in that case, I might post corrected text, but not as a
quotation.

The meaning of a "> " prefix is "this is a direct quotation from
the previous article". Don't use it if that's not what you mean.

That pretty well agrees with my own practice. I also occasionally
add a blank line between paragraphs, or elide silly blank lines in
source code. The idea is to make the whole article easily readable
by the end viewer. I can't stand those evilly line wrapped
postings, which take up far too much unnecessary room.
 
D

Dik T. Winter

That should not be done.

In my opinion that is okay.

Not needed in my opinion. The discussion is about a C program (in
this forum), so layout changes do not change the program.

Why is there a difference? Both for code lay-out and for English text,
I would think that making changes that do not change the meaning can be
done. Why would it be allowed for English text but not for code?

I do not think so. The prefix means that the block after the prefixes
(on multiple lines) is what the original writer wrote, but possibly
reformatted. And it does not matter whether the original was C code
or English text, as long as the quote does mean exactly the same as
the original. Darn, I even modify quoted-printable text coded from
ISO-8859-1 to the plain ISO-8859-1 text.
> That pretty well agrees with my own practice. I also occasionally
> add a blank line between paragraphs, or elide silly blank lines in
> source code. The idea is to make the whole article easily readable
> by the end viewer. I can't stand those evilly line wrapped
> postings, which take up far too much unnecessary room.

For that reason I also frequently re-format nested quotes (using the
quotation symbols originally used). And I do that with code *and* text.
In my opinion, in any place the quotation marks function as white space
(together with the preceding new line). And any form of white space
can be replaced by any other form of white space.
 
K

Keith Thompson

Dik T. Winter said:
Keith Thompson wrote: [...]
Expanding tabs is ok. Changing the visible layout, IMHO, is not;
if the code is badly formatted, don't pretend that the OP actually
wrote something that's well formatted. (I'd say changing
indentation levels is *probably* ok if you clearly state you've
done it; adding or removing braces is not.)

Not needed in my opinion. The discussion is about a C program (in
this forum), so layout changes do not change the program.

Layout changes don't change the program as far as the compiler is
concerned, but they do change it as far as the reader is concerned.

There have been religious wars about where braces should go. If I
write this:

if (something) {
func(42);
x = y * z + 17;
}

and a followup says:
> if (something)
> {
> func(42);
> x = y * z + 17;
> }

or even:
> if(something){func(42);x=y*z+17;}

then I'm going to be seriously annoyed; that's *not* what I wrote,
even if it means the same thing.
Why is there a difference? Both for code lay-out and for English text,
I would think that making changes that do not change the meaning can be
done. Why would it be allowed for English text but not for code?

In most English text, the layout really is insignificant. Except in
poetry, we rarely use line breaks to express meaning, and reformatting
a paragraph to make it more legible is ok. (And if someone posted,
say, a haiku or a limerick, assuming it's topical, reformatting it
would be rude.)

In C source code, however, the layout can be a significant portion of
the effort that went into writing it.

And if someone posts a *poorly* formatted C program, I might quote it
exactly and then post my own properly formatted version. Showing the
properly formatted version as if it were what the OP wrote would be
misleading IMHO, and would not make the point as well.

[...]
For that reason I also frequently re-format nested quotes (using the
quotation symbols originally used). And I do that with code *and* text.
In my opinion, in any place the quotation marks function as white space
(together with the preceding new line). And any form of white space
can be replaced by any other form of white space.

I agree with you on English text; I disagee when it comes to source
code.
 
R

raghu

#include <stdio.h>


/* 1st example

int a()
{
return 1;

}

b()
{

}


int main()
{

int x;
a();
x=b();

printf("%d",x);

}

*/


// 2nd example


int a()
{
return 1;

}

b()
{
a();
}

int main()
{

int x;
x=b();
printf("%d",x);
}


Please see the first example and the second example. I don't know why
is there a difference of output. I tried it running in vc ++ 6.0

Thanks in advance

Regards
Ankush
hai,
the return value of previous function will be assigned to present
function if it doesnot return nothing and not declared void. try it
out:

b(){}
int main()
{
int x;
printf("C lang%d\n",b());
x = b();
printf("%d",x);
}
the return value of printf will be asigned to x
bye
with smile
Raghu
 
R

Richard Heathfield

raghu said:

b(){}
int main()
{
int x;
printf("C lang%d\n",b());
x = b();
printf("%d",x);
}
the return value of printf will be asigned to x

The behaviour of this program is undefined for at least two reasons, one of
which is that b() does not return a value. See if you can spot the other
for yourself.
 
M

mark_bluemel

raghu said:
the return value of previous function will be assigned to present
function if it doesnot return nothing and not declared void.

Where is this behaviour specified?

It may _appear_ to work this way in some implementations dependent on
how the subroutine calling mechanism for the target architecture works
(which is nothing to do with the C language), but there's no guarantee
of this behaviour.

Please don't let one set of observations make you think that you can
specify what undefined behaviour will do everywhere...
 
K

Keith Thompson

raghu said:
the return value of previous function will be assigned to present
function if it doesnot return nothing and not declared void. try it
out:

b(){}
int main()
{
int x;
printf("C lang%d\n",b());
x = b();
printf("%d",x);
}
the return value of printf will be asigned to x

Sorry, but that's nonsense. It might happen to behave that way in
some implementations, sometimes, but the behavior is undefined.
 
R

raghu

Keith said:
Sorry, but that's nonsense. It might happen to behave that way in
some implementations, sometimes, but the behavior is undefined.

But it happened in gcc compiler. I modified the code for number of
times and concluded in that manner.
 

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

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top