Reputation: 1953
I am able to compile this with gcc using the -Wextra -g
flags and I get no errors. Why does the compiler not catch that I don't return anything from a non-void function? Also, I've run this on a 32-bit and a 64-bit machine. It ran perfectly fine on the 32-bit, and even printed 'Apple stem length 10. Apple color r'. But it seg faults on the 64-bit machine. What is gcc doing here that gives me such unpredictable behavior and why is it not giving me any errors at compile time?
#include <stdlib.h>
#include <stdio.h>
struct apple
{
int stem_length;
char color;
};
struct apple* alloc_apple(const int stem_length, const char color)
{
struct apple* new_apple = (struct apple*)malloc(sizeof(struct apple));
new_apple->stem_length = stem_length;
new_apple->color = color;
}
int main(int argc, char* argv[])
{
struct apple* some_apple = alloc_apple(10, 'r');
printf("Apple stem length %d. Apple color %c\n", some_apple->stem_length,
some_apple->color);
free(some_apple);
return 0;
}
Upvotes: 0
Views: 142
Reputation: 320777
Errors? What errors?
"Not returning anything from a non-void function" has never been considered a formal "error" (i.e. a constraint violation) in C. (BTW, it is not an "error" in C++ either). It is just how the language is defined. Some compilers might issue a warning, but in general case they are not allowed to treat this as a constraint violation.
As a side note, the difference between C and C++ in that regard is that in C++ forgetting to return something is always undefined behavior. In C the behavior is undefined only if you attempt to use the function's result in the calling code. Otherwise, if the returned value is ignored by the caller, C sees it as perfectly normal legal code.
Upvotes: 0
Reputation: 94475
You are using -Wextra
, but this is wrong option.
Gcc (and most unix compilers) uses -Wall
option to enable most warnings, including the one you want to see, the -Wreturn-type
: http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
-Wall
This enables all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning), even in conjunction with macros. -Wall turns on the following warning flags:
... list of
-Wreturn-type
and 30 more-W...
flags
And your -Wextra
only enables several additional warnings which are not turned on by -Wall
.
-Wextra
This enables some extra warning flags that are not enabled by -Wall. ... list of 12 rare
-W...
options
Example:
$ gcc t.c -Wextra
# No output
$ gcc t.c -Wall
t.c: In function ‘alloc_apple’:
t.c:15:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
So, just use "-Wall
" to get most warnings, -Wall -Wextra
to get more. And sometimes you can also use set -Wall -Wextra -std=c99 -pedantic -pedantic-errors
to be sure that your program is very close to C99 standard (but system headers have non-standard code and this is not caught).
Also use clang
, it has better warnings and better warnings set by default:
$ clang t.c
t.c:15:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
1 warning generated.
Upvotes: 3
Reputation: 36534
alloc_apple
fails to return new_apple;
at the end. This may work by coincidence if new_apple
happens to be left lying around in the register the return value is expected in when the function returns (on i386 this is usually EAX
), but allowing control to reach the end of a non-void
returning function produces undefined behavior (which may include anything from accidentally working as expected to causing demons to fly out of your nose).
I am fairly certain that if you compile with gcc -Wall
(enable all warnings) it would point out the issue; return-type
is the specific warning.
The function wouldn't even work for compilers that use the ancient convention of returning the value of the last expression evaluated if no return
is present, since the last expression evaluates to the value of color
.
Upvotes: 4
Reputation: 121881
The issue is that you're failing to return a value from a function.
This is undefined behavior. It just "seems to work" on 32-bit, and it crashes on 64-bit. If you're curious why it's failing, the first step is to get a stack trace.
As to "why didn't GCC tell me?"
It can:
http://gcc.gnu.org/onlinedocs/gcc-3.4.3/gcc/Warning-Options.html
-Wreturn-type
Warn whenever a function is defined with a return-type that defaults to int. Also warn about any return statement with no return-value in a function whose return-type is not void.
For C++, a function without return type always produces a diagnostic message, even when -Wno-return-type is specified. The only exceptions are main and functions defined in system headers.
Personally, I almost always use these switches during development:
gcc -g -pedantic -Wall ...
Upvotes: -1