Implicit int return value of C function - c

I've googled and just can't seem to find the answer to this simple question.
Working on a legacy code base (ported to Linux recently, and slowly updating to a new compiler) and I see a lot of
int myfunction(...)
{
// no return...
}
I know the implicit return TYPE of a function is int, but what is the implicit return VALUE when no return is specified. I've tested and gotten 0, but that's only with gcc. Is this compiler specific or is it standard defined to 0?
EDIT: 12/2017
Adjusted accepted answer based upon it referencing a more recent version of the standard.

From the '89 standard as quoted in the new testament:
Flowing off the end of a function is equivalent to a return with no expression. In either case, the return value is undefined.
That standard usually expresses the on-the-ground behavior of pre-existing implementations.

Such a thing is possible, but only under the assumption that the return value of the function is never used. The C11 standard says in para 6.9.1:
If the } that terminates a function is reached, and the value of the
function call is used by the caller, the behavior is undefined.
(AFAIR previous version of the standard had similar wording)
So it would be a good idea to transform all the functions of that sort that you have to void functions, so no user of such a function could be tempted to use the return value.

The return statement is never mandatory at the end of a function, even if the function return type is not void. No diagnostic is required and it is not undefined behavior.
Example (defined behavior):
int foo(void)
{
}
int main()
{
foo();
}
But reading the return value of foo is undefined behavior:
int bla = foo(); // undefined behavior
From the C Standard:
(C99, 6.9.1 on p.12) "If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined."
The main function is an exception to this rule as if the } is reached in main it is equivalent as if there was a return 0; statement.
(C99 draft, 5.1.2.2.3 on p.13) ...reaching the } that terminates the main function returns a value of 0.

That's simply undefined behaviour; if you don't populate the return area (which for example is generally eax/rax on x86 family processors), it'll have the value last set up through some side-effect in your function.
See Is a return statement mandatory for C++ functions that do not return void? which is basically a duplicate of this question (except that it's tagged as C++).

If the return statements consistently do not return a value, the function is best converted to, and declared as, returning void:
void myfunction(...)
{
...
return;
...
}
If there are some some return expr; and some return; statements in the function, then you need to decide which is the better behaviour, and make them consistent — either always return a value and leave the type as int or never return a value and change the type to void.
Note that you'll need to declare functions modified to return void (in a header, unless they are — or should be — static and hidden in a single source file) since the default return type (assumed return type) of int is no longer valid.

It may always be zero in that function, but on most architectures (certainly x86) the return statement moves the contents of a specific register to a specific place on the stack which the caller will retrieve and use as its return function.
The return statement will place the variable passed to it in that location so that it'll be a different value. My experience with not placing a specific return statement is that its fairly random what gets returned and you can't rely on it being the same thing.

I'm certain that it is undefined behaviour for a function whose return type is not void to omit a return statement. In C99 there is an exception for main, where if the return statement is omitted, it is assumed to return 0 implicitly, but this doesn't apply to any other function.
It may work on a specific platform/compiler combination but you should never rely on such specifics. Using any kind of undefined behaviour in your code makes it unportable. It is common to see undefined behaviour in legacy code though.

Related

Recursuve calls in c working even though its not returned to its parent call in stack [duplicate]

I've googled and just can't seem to find the answer to this simple question.
Working on a legacy code base (ported to Linux recently, and slowly updating to a new compiler) and I see a lot of
int myfunction(...)
{
// no return...
}
I know the implicit return TYPE of a function is int, but what is the implicit return VALUE when no return is specified. I've tested and gotten 0, but that's only with gcc. Is this compiler specific or is it standard defined to 0?
EDIT: 12/2017
Adjusted accepted answer based upon it referencing a more recent version of the standard.
From the '89 standard as quoted in the new testament:
Flowing off the end of a function is equivalent to a return with no expression. In either case, the return value is undefined.
That standard usually expresses the on-the-ground behavior of pre-existing implementations.
Such a thing is possible, but only under the assumption that the return value of the function is never used. The C11 standard says in para 6.9.1:
If the } that terminates a function is reached, and the value of the
function call is used by the caller, the behavior is undefined.
(AFAIR previous version of the standard had similar wording)
So it would be a good idea to transform all the functions of that sort that you have to void functions, so no user of such a function could be tempted to use the return value.
The return statement is never mandatory at the end of a function, even if the function return type is not void. No diagnostic is required and it is not undefined behavior.
Example (defined behavior):
int foo(void)
{
}
int main()
{
foo();
}
But reading the return value of foo is undefined behavior:
int bla = foo(); // undefined behavior
From the C Standard:
(C99, 6.9.1 on p.12) "If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined."
The main function is an exception to this rule as if the } is reached in main it is equivalent as if there was a return 0; statement.
(C99 draft, 5.1.2.2.3 on p.13) ...reaching the } that terminates the main function returns a value of 0.
That's simply undefined behaviour; if you don't populate the return area (which for example is generally eax/rax on x86 family processors), it'll have the value last set up through some side-effect in your function.
See Is a return statement mandatory for C++ functions that do not return void? which is basically a duplicate of this question (except that it's tagged as C++).
If the return statements consistently do not return a value, the function is best converted to, and declared as, returning void:
void myfunction(...)
{
...
return;
...
}
If there are some some return expr; and some return; statements in the function, then you need to decide which is the better behaviour, and make them consistent — either always return a value and leave the type as int or never return a value and change the type to void.
Note that you'll need to declare functions modified to return void (in a header, unless they are — or should be — static and hidden in a single source file) since the default return type (assumed return type) of int is no longer valid.
It may always be zero in that function, but on most architectures (certainly x86) the return statement moves the contents of a specific register to a specific place on the stack which the caller will retrieve and use as its return function.
The return statement will place the variable passed to it in that location so that it'll be a different value. My experience with not placing a specific return statement is that its fairly random what gets returned and you can't rely on it being the same thing.
I'm certain that it is undefined behaviour for a function whose return type is not void to omit a return statement. In C99 there is an exception for main, where if the return statement is omitted, it is assumed to return 0 implicitly, but this doesn't apply to any other function.
It may work on a specific platform/compiler combination but you should never rely on such specifics. Using any kind of undefined behaviour in your code makes it unportable. It is common to see undefined behaviour in legacy code though.

Can the return type of a function be altered outside of it's scope to return no value? [duplicate]

This question already has answers here:
return nothing from non-void function in C
(8 answers)
Closed 12 months ago.
The ANSI C PROGRAMMING book (basics of functions section) states 'Control also returns to the caller with no value when the execution "falls off the end" of the function by reaching the closing right brace. It is not illegal, but probably a sign of trouble, if a function returns a value from one place and no value from another.'
How can a function once created with a return value, return no value in another place? Is it in a circumstance when I use a conditional statement inside the function to return a value and no value if the condition fails?
The ANSI C PROGRAMMING book…
The ANSI C standard is defunct, and books about it should not be used except when working with ancient software that used it. The International Organization for Standardization (ISO) and International Electrotechnical Commission (IEC) currently publish a C standard.
Can the return type of a function be altered outside of it's scope to return no value?
There is no change in the type of a function. Its type is, for example, “function returning int” (and having whatever parameters). Whether it actually returns a value or not is a matter of behavior at execution time, not of type.
… Control also returns to the caller with no value when the execution "falls off the end" of the function by reaching the closing right brace. It is not illegal, but probably a sign of trouble, if a function returns a value from one place and no value from another.'
Yes, this is allowed. C 2018 6.9.1 12 says:
Unless otherwise specified, if the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.
Thus a function may complete by letting control flow to the closing }, and this is defined by the C standard as long as the caller does not use the value.
This permits, for example, functions that do or do not return a value depending on circumstances, such as:
enum Command { Set, Get };
int GetOrSetValue(enum Command Command, int NewValue)
{
static int SavedValue;
switch (Command)
{
case Set:
SavedValue = NewValue;
break;
case Get:
return SavedValue;
}
}
#include <stdio.h>
int main(void)
{
// Set saved value without using function return value.
GetOrSetValue(Set, 4);
// Use function return value ot get saved value.
printf("%d\n", GetOrSetValue(Get, 0));
}
Nonetheless, this aspect of C is rarely used and exists largely to accommodate old software. Good programming practice avoids it in new code, and compiling warnings about reaching the end of a non-void function assist with that.

Do we always have to assign the return value of a function in C? [duplicate]

This question already has answers here:
Do unsigned functions has to return something??
(2 answers)
Closed 1 year ago.
I was writing a code to swap the elements of 2 arrays, my colleague wrote the function as a pointer to integer return value and in main he didn't receive the returning pointer, yet the code worked perfectly, why is this possible?, I will try to include some code below:
int * Swap (int a_size,int *a,int b_size,int *b){
int i;
int temp;
for(i=0;i<b_size;i++){
temp=a[i];
a[i]=b[i];
b[i]=temp;
}
}
I guess there are sort of two questions here:
If a function is declared to return a value (or not), how wrong is it to not return a value (or to return a value)?
If a function returns a value (or not), how wrong is it for the caller not to use the value (or to use the value)?
Let's examine these in turn.
First, if a function is declared to return a value (or not), how wrong is it to not return a value (or to return a value)?
There are four cases:
function declared to return value, function does return value: this is obviously good and proper.
function declared to return void, function does not return value: this is obviously good and proper.
function declared to return void, function does return value: this is obviously an error, and the compiler will emit an error message and halt compilation.
function declared to return value, function does not return value: this is probably an error, but for historical reasons, the compiler might not complain. Good compilers will at least issue a warning here. It sounds like your compiler didn't. You might want to think about getting a better compiler, or changing compilation options so it issues more warnings. (It's also possible for this situation not to be an error, as described in Eric Postpischil's answer, and this helps explains why the situation is not, in fact, illegal. There may also be subtle differences between the case where the function "falls off the end" and hits the terminating } without ever having a return statement, versus the case where it has an explicit return; statement without a value.)
That might answer your question, but if not, let's move on to my second question: if a function returns a value (or not), how wrong is it for the caller not to use the value (or to use the value)?
Again, there are four cases:
function declared to return value, caller uses return value: this is obviously good and proper.
function declared to return void, caller does not use return value: this is obviously good and proper.
function declared to return void, caller does use return value: this is obviously an error, and the compiler will emit an error message and halt compilation.
function declared to return value, caller does not use return value: this is the interesting case. It might be a problem, or it might not be a problem. Let's expand on this further:
For a function like sqrt, whose sole function is to compute and return a value, it would obviously be very strange to not use the return value. For example, if you write
sqrt(100);
alone on a line, you're asking to compute the square root of 100, and then throwing away the return value. This is not an error, but a good compiler will probably warn about it, because it's probably not what you want.
There are other functions that return a value, that you might not care about. For example, it's not well known that the venerable printf function returns a value: the number of characters printed. But printf is not a function whose sole function is to compute and return a value; printf also does something interesting off to the side: it prints stuff. So if you call
printf("Hello, world!\n");
but if you throw away the return value, that's fine, almost no one would object to that. (Theoretically there's a chance that printf might fail, due to some kind of an i/o error, and return -1 to try to tell you this, but most programs don't care about this, and in the grand scheme of things that's not a problem.)
Finally, there are programs that return a value, that you might not think you care about, but that you probably should care about. Consider this fragment:
int i;
printf("enter an integer:\n");
scanf("%d", &i);
printf("you typed %d\n, i);
Here, the problem is that if the user types something like "no, I won't", scanf will be unable to read an integer as requested by %d, and it will return 0 to say that it performed no conversion, but the program won't notice, and since i is an uninitialized value, it's hard to see what the program might print.
If we think about this carefully, we see that there might be sort of a "hidden" attribute of functions, namely: "How okay is it for the caller to ignore the return value?" printf is a function that returns int, but it's usually (in all but the most paranoid programs) okay to ignore the return value. But scanf is a function that returns int where, as we've just seen, it's not a good idea to ignore the return value (although lots of programmers do). And sqrt is a function returning double, where it's almost certainly an error not to use the return value. So if a compiler decides to help you out by warning you when you forget to use a function's return value, how does it avoid spamming you with warnings every time you call printf? And the answer is that such a compiler has to invent a special way to implement that property -- a property not defined by the C language, which is why I called it "hidden" -- that specifies whether or not the warning is appropriate.
Also -- and this gets down to the meat of your question as asked -- there's a higher-order question that sort of combines the two top-level questions I've been exploring: If a function is declared as returning a value, but does not return a value, what happens if the caller does/doesn't try to use the returned value?
And the answer is that if a function is declared as returning a value, but it doesn't actually return a value, but the caller doesn't try to use the return value, that's fine -- although this might seem like kind of a dicey situation! And on the other hand, if the caller does try to use the value that wasn't returned, that's obviously a bad situation. As far as the C Standard is concerned, it falls into the dreaded category of undefined behavior, and there's a pretty good reason for this: deciding whether it's actually a problem is a hard, almost impossible problem. If a function is declared as returning a value, and if it sometimes doesn't return a value, and if the caller sometimes doesn't try to use the returned non-value, deciding whether it's actually a problem would theoretically requiring (a) examining the code for both the function and its caller and (b) deciding under which circumstances the function does or doesn't return a value. Both of these subproblems are basically impossible to solve. C supports separate compilation, so in the general case a compiler won;t be able to inspect both the function and its caller at once. And solving subproblem (b) is basically the halting problem. So it's up to you, the programmer, to keep things straight in this case: the compiler can't be required to issue an error if you try to use the value that wasn't returned by a function declared as if it returned one.
In the end, though, the Swap() function you posted could probably an example of the "don't care" case. It's defined as returning int *, but it doesn't actually return a value, but the caller doesn't try to use it, so it's okay. But this is potentially quite confusing and error-prone, so I would suggest that it would be much better to either (a) have it actually return a value or (b) redeclare it as returning void.
The C standard does not require a function declared with a non-void return type to return a value. It is not, by itself, undefined behavior for such a function not to return a value.
It is undefined behavior if the caller attempts to use the value of a function that did not return a value. C 2018 6.9.1 12 says:
Unless otherwise specified, if the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.
(It is “otherwise specified” for main: In a hosted environment, if the return type of main is int and it reaches the } that terminates its body, it returns zero, per C 2018 5.1.2.2.3 1.)
In most cases, it is good practice for a function declared with a non-void return type to return a value, and compilers may warn if they do not. However, there are situations in which a function may be intentionally designed not to return a value in all cases. For example:
typedef enum { Get, Set } CommandType;
int DoCommand(CommandType Command, int Value)
{
switch (Command)
{
command Get:
return SavedValue;
command Set:
SavedValue = Value;
break;
}
}
This is a very simplified abstracted example—with simple situations, we might want to separate this routine into two routines, one to set and one to get. But in more complicated software, it might make sense to wrap these and other “commands” that operate on various objects (not shown) into a single command-and-control routine which sometimes returns a value and sometimes does not.
In order to write correct C programs, one should always indicate the correct return type of the function. In case a function does not return any value, a "special" return type void is used.
Example function that returns an int:
int add(int a, int b) {
return a + b;
}
Example function that returns nothing:
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
You can ignore the return value of a function if you don't need it:
void test(void) {
int x = add(3, 5); // correct, we're using the return value of add()
add(1, 2); // also correct, we're just ignoring the return value of add()
(void) add(1, 2); // more correct, this is just like previous line, but we're making it obvious to the reader that we are explicitly ignoring the return value, and it is not a mistake
}
EDIT: in order to make my answer more useful, I will add some examples of what SHOULD NOT be done in C.
Example 1:
// WRONG, because we defined neg() to return an int, but we're not returning it
// NOTE: this is wrong even if we ignore the return value of neg()
int neg(int* a) {
*a = -(*a);
}
// POSSIBLE CORRECT ALTERNATIVE
void neg(int* a) {
*a = -(*a);
}
// ANOTHER POSSIBLE CORRECT ALTERNATIVE
int neg(int* a) {
*a = -(*a);
return *a;
}
Example 2:
// WRONG, because we defined foo() to return nothing, but we're actually returning an int
void foo(int a) {
return a;
}
// CORRECT ALTERNATIVE
int foo(int a) {
return a;
}
Example 3:
// CORRECT
void foo(int a, int b) {
if (a == 0) {
return; // we're returning early from the function (and we're returning nothing, of course, since function is void)
}
printf("%d %d\n", a, b);
return; // this is really not needed and it is implicit in void functions: when they reach the end, they return nothing
}
// WRONG
int bar(int a, int b) {
if (a == 0) {
return; // WRONG, we must return an int
}
int x = foo(1, 2); // WRONG: foo() returns nothing (i.e.: void), and we cannot therefore use the return value of foo()
// WRONG: reached end of function, but we never returned an int
}
Example 4:
void test(void) {
printf("Hello, I'm ignoring your return value.\n"); // CORRECT, printf() is a standard function that returns the number of characters written (returned as an int), and if we don't need this information, we can just ignore the returning value
malloc(500); // WRONG, malloc() is a standard function defined to return a pointer, and it is one of many functions that we should never ignore the return value of
// The difference between printf() and malloc() must be learned from the docs: there we can find out that printf()'s return value can be safely ignored, while malloc()'s cannot
}
EDIT 2: in my answer the words CORRECT and WRONG are not always used to say "it is correct/wrong according to the ISO C standard", but sometimes (as in the example of malloc() vs printf()) they mean "it is correct/wrong according to good programming practices"
Yes. Always do a clean return from any non-void function.
Otherwise the consequences are
confused colleagues
confused future you
more risks at code changes

function returns the value of a pointer without "return" statement [duplicate]

Please explain why sometimes return statement is not needed?
Function has a return type, but return statement missing. Meanwhile, program compiles and works fine.
Please help me understand this better
char* handleInput() {
fgets(buffer, 1024, stdin);
// return buffer; <---- COMMENTED RETURN
}
void main() {
char* ptr = handleInput();
int flag = atoi(ptr);
if (flag < 0) break;
printf("You entered: %s\n", ptr);
}
Basically what gets returned is dumb luck. You get what happens to be in the CPU register when it comes back. If, for example, the returned value would be in AX, and the char* happens to be in AX, you lucked out. I believe this is an undefined behavior; i.e. the C language specifications don't tell what you should so, so it is left to the compiler. I'm surprised a modern compiler wouldn't at least throw a warning at you.
C99 6.9.1/12 "Function definitions" 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.
C90 6.6.6.4 "The return statement"standard says something with simialr effect:
If a return statement without an expression is executed, and the value of the function call is used by the caller, the behavior is undefined. Reaching the } that terminates a function is equivalent to a return statement without an expression.
So returning from a function without returning something from the function is permitted - but the caller of the function isn't allowed to use the 'result' of the function call. That's undefined behavior, and like other answers have mentioned you can get 'expected' results with undefined behavior, but that's only by chance.
I believe the rationale for this is that pre-standard C defaulted to a return type of int for functions if the function wasn't explicitly declared (or if the declaration omitted the return type), and that continued to be supported when C was standardized. Many of those functions were designed to be called only for side-effects they produced, and no return value was expected or provided.
A couple side notes:
gcc will warn about this if the -Wall option is used. MSVC warns about it by default.
you should be getting a compiler error about the if (flag < 0) break; line since the break isn't in a loop or switch.
main() should return int not void (-Wall will warn about that as well). Of course, you should also return some value explicitly...
Not using 'return' in a function declared to return a value is bad practice to say the least. Most compilers should generate a warning.

Do unsigned functions has to return something??

Hey I'm working on an exercise where I have to program an unsigned function in C, and I have a question, do I have to return something because of the type of the function?? Or is it optional??
In normal use, any function declared to return a value ought to return a value. This is largely a matter of good programming practice. Failing to return a value is often a sign of an error. However, this is not required by the C standard, and there are two exceptions.
C 2018 6.9.1 12 allows a function to terminate by reaching the end of its code without returning a value, provided the caller does not use the value of the function:
Unless otherwise specified, if the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.
One case where a function might return a value in some situations and not in others is where it is designed to perform various different actions upon command. For example:
unsigned DoSomething(int command, int parameters[])
{
switch (command)
{
case GetSomething:
…
return Something;
case RememberSomething;
Something = parameters[0];
…
break;
}
}
Such designs may be error-prone and ought to be considered carefully. Since the function is declared to return a value, a programmer might expect it to do so and inadvertently assign the value of the function to another object in a situation where no value is returned, resulting in undefined behavior.
Additionally, a function may not return at all, and there is a function specifier for explicitly telling the compiler this is so, _Noreturn, as specified in 6.7.4. This behavior is typically used only in abnormal situations. For example, the standard functions abort and exit terminate the program, so they do not return. Of course, they are declared with void, so they never return anything. However, you might have a function that calls exit in some circumstances and returns an integer in others.
It is a good idea to have all your non-void functions return something, but if you exit a function without return statment (i.e. with the } character) and try to access its result, the behavior is undefined.
If you explore different compilers on Godbolt, with the following code as the C source:
int n()
{
int a = 1234;
}
You will notice that some compilers issue a warning on this behavior depending on their warning levels.
The value you get if you try to use the result function as an int, for example, in printf("%d\n", n()); is undefined: there is no guarantee about what value you will get or if your program will crash, or do something else entirely.
That said, depending on the architecture you're compiling for, you may get a local value from your function as the return value. For example, on the x86 architecture, just about every calling convention specifies that the return value is whatever is in the register eax when the function returns. So, if the generated code for the function n above stores the local variable a in eax, the "return value" (quote-unquote) will be 1234.
This is not something you should ever rely on, though.

Resources