469,898 Members | 1,586 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,898 developers. It's quick & easy.

A value returned to a function without a `return' statement, why?

I ever missed a `return' statement when write a function `int
HighDigit(Num)' to get the highest digit of an integer.

But even if the `return' statement is ignored the function still can
obtain an `correct' return value when the argument `Num' is larger than
or equal to the Macro `NUM_SYS'.

If the argument is less than the Macro, the function without a `return'
get an undefined value. I've made a test on Ms Windows 2000 and VC 6.
Thank you in advance for explaining why.

And would you please comment on this algorithm? Thank you.


i.e.
Num HighDigit(Num)
======================
123 | 1
321 | 3
2 | 2
10 | 1
______________________

The code I write is:
//highdigit.h

#ifndef _HIGH_DIGIT_H_
#define _HIGH_DIGIT_H_

#define NUM_SYS 10 //number system, decimal assumed as default

int HighDigit(int Num);

#endif //_HIGH_DIGIT_H_
//highdigit.c

#include "highdigit.h"

int HighDigit(int Num){
while (Num >= NUM_SYS){
Num /= NUM_SYS;
}

//return Num; //This statement be missed by me at first.
}

Nov 14 '05 #1
6 2080
On 13 Mar 2005 21:32:52 -0800, "lovecreatesbeauty"
<lo***************@gmail.com> wrote in comp.lang.c:
I ever missed a `return' statement when write a function `int
HighDigit(Num)' to get the highest digit of an integer.
It is actually legal in C to omit a return statement from a function
with a return type other than void. Rather foolish, but legal.
But even if the `return' statement is ignored the function still can
obtain an `correct' return value when the argument `Num' is larger than
or equal to the Macro `NUM_SYS'.
Now here the C standard does have something to say. If you miss a
return statement in a function that has a non-void return type, and if
the calling code uses the return value in any way, then the behavior
is undefined.
If the argument is less than the Macro, the function without a `return'
get an undefined value. I've made a test on Ms Windows 2000 and VC 6.
Actually the result is always undefined, a term with a precisely
defined meaning in the C language. It is just in some cases the value
is what you expect it to be, and in other cases it is not.
Thank you in advance for explaining why.
When you produce undefined behavior, the C language no longer
specifies what will happen. One possible result of undefined behavior
is that, in some cases, the program "works" the way you think it
should.
And would you please comment on this algorithm? Thank you.


i.e.
Num HighDigit(Num)
======================
123 | 1
321 | 3
2 | 2
10 | 1
______________________

The code I write is:
//highdigit.h

#ifndef _HIGH_DIGIT_H_
#define _HIGH_DIGIT_H_
This is something you should not do. All identifiers beginning with
two underscores or an underscore followed by an uppercase letter are
reserved for the compiler, and not to be used in your code.
#define NUM_SYS 10 //number system, decimal assumed as default
Either your function always works with base 10, in which case you
don't need the definition in the header but only in the source code
file with the function body. And it is not a default, it is the only
value. Or you want it to work on various bases, in which case the
base should be a function parameter as in functions like strtol() in
the standard library.
int HighDigit(int Num);
You could make this:

int HighDigit(int Num, int base);
#endif //_HIGH_DIGIT_H_
//highdigit.c

#include "highdigit.h"

int HighDigit(int Num){
while (Num >= NUM_SYS){
Num /= NUM_SYS;
}

//return Num; //This statement be missed by me at first.
}


....and likewise:

int HighDight(int Num, int base)
{
assert(base > 0);
while (Num >= base)
{
Num /= base;
}
return Num;
}

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #2
Jack, thank you. Could please give some suggestion on the usage of
`assert()'.

I think, an runtime value makes assert() failed in debug version can
also (always) make it failed in release version, but in the release
version (NDEBUG defined) the `assert()' means null, so it can't catch
runtime error in release version.

Nov 14 '05 #3
"Jack Klein" <ja*******@spamcop.net> wrote in message
news:qo********************************@4ax.com...
On 13 Mar 2005 21:32:52 -0800, "lovecreatesbeauty"
<lo***************@gmail.com> wrote in comp.lang.c:
Thank you in advance for explaining why.


When you produce undefined behavior, the C language no longer
specifies what will happen. One possible result of undefined behavior
is that, in some cases, the program "works" the way you think it
should.


As to why the UB leads to it "working" in his case (as the OP asked), it may
be because the compiler happened to use the same register for "Num" that is
also the return value register. Of course, recompiling with a different
compiler, version, or optimization level may cause a different register to
be used and complete garbage to be returned. UB at its best.

S

--
Stephen Sprunk "Stupid people surround themselves with smart
CCIE #3723 people. Smart people surround themselves with
K5SSS smart people who disagree with them." --Aaron Sorkin

Nov 14 '05 #4
On 14 Mar 2005 04:13:24 -0800, "lovecreatesbeauty"
<lo***************@gmail.com> wrote in comp.lang.c:
Jack, thank you. Could please give some suggestion on the usage of
`assert()'.

I think, an runtime value makes assert() failed in debug version can
also (always) make it failed in release version, but in the release
version (NDEBUG defined) the `assert()' means null, so it can't catch
runtime error in release version.


C doesn't define "debug version" and "release version". If you want
the assert() macro to work, make sure that NDEBUG is not defined. If
you can't figure out how to modify your IDE's settings, ask in one of
Microsoft's support groups in the news:microsoft.public.* family on
their server msnews.microsoft.com.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #5
"lovecreatesbeauty" <lo***************@gmail.com> writes:
original question

//highdigit.h

#ifndef HIGH_DIGIT_H
#define HIGH_DIGIT_H

#define NUM_SYS 10 //

int HighDigit(int num);

#endif //HIGH_DIGIT_H


//highdigit.c

#include "highdigit.h"

int HighDigit(int num){
while (num >= NUM_SYS){
num /= NUM_SYS;
}

//return num; //omitted.
}

I test it on Linux & GCC again, and get the same problem as on Windows
& VC6.

If the argument `num' is larger than or equal to the Macro, the loop
body is executed and the result is right as if the `return num'
provided implicitly. But if the argument is less than the Macro, the
loop body is not executed. The result is undefinded.


The result is *always* undefined. The undefined result may, in some
cases, happen to be what you expect it to be. You should never depend
on this; the behavior can vary depending on anything, including the
phase of the moon or the importance of the customers watching your
demo.

--
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.
Nov 14 '05 #6
On 15 Mar 2005 04:10:20 -0800, "lovecreatesbeauty"
<lo***************@gmail.com> wrote:
I test it on Linux & GCC again, and get the same problem as on Windows
& VC6.


It is working by accident. The compiler has (apparently) chosen to use
the same register for the calculation as it uses to return a value. This
is a pretty good strategy, and a common optimization. Change the code to
increment the value of a global variable and you'll likely get different
results.

I strongly suggest you turn up the warning level on your compiler - it
should be telling you about the error in your function.

--
#include <standard.disclaimer>
_
Kevin D Quitt USA 91387-4454 96.37% of all statistics are made up
Per the FCA, this address may not be added to any commercial mail list
Nov 14 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

8 posts views Thread by DaKoadMunky | last post: by
reply views Thread by lovecreatesbeauty | last post: by
5 posts views Thread by Dmitriy Lapshin [C# / .NET MVP] | last post: by
20 posts views Thread by lovecreatesbeauty | last post: by
9 posts views Thread by noor.fatma | last post: by
21 posts views Thread by Steven T. Hatton | last post: by
9 posts views Thread by stevewy | last post: by
7 posts views Thread by Terry Olsen | last post: by
1 post views Thread by Waqarahmed | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.