Reputation: 285
Recently I stumbled upon some C code where the return type of a function definition was in itself a struct definition. For example, this:
#include <stdio.h>
struct f {
int a[25];
const char* ch;
}
function(int h)
{
printf("Passed: %d\n", h);
}
int main(int argc, char* argv[]) {
printf("array at: %p ptr : %p\n", function(4).a, function(5).ch);
int *ptr = function(6).a;
for(int i = 0; i < 25; i++)
{
ptr[i] = i;
printf("%d\n", ptr[i]);
}
puts("No segfaults.");
return 0;
}
You can test this yourself here.
My question is why would something like this be allowed? What benefits does it actually have over defining a struct
normally? You can't init the variables, unless, I guess, you create a struct
inside a function, change its data and then return
it. Which is pretty standard-fare, but the thing is, under clang 7.0.0
you don't even need to return
anything! I thought non void
functions having no return
statements was a compiler error (with the only exception being main
), but clang
lets you off the hook with a warning.
And also we can be sure that each function call results in an object created, as the code I gave doesn't segfault. Although I'm not sure why it doesn't as the struct
is being allocated on the stack and whenever it would go out of scope (which is right when function
ends) it would get deallocated and the address would become invalid. In my code I can write to a location which my program no longer owns and for some reason it doesn't segfault, but I don't exclude the possibility of it being UB.
Upvotes: 2
Views: 145
Reputation: 15576
Because it's syntatically and semantically valid and prohibiting it would increase complexity in the compiler. It makes no sense to prohibit something that the benefits of leaving could exceed the costs of keeping.
Upvotes: 3
Reputation: 26066
My question is why would something like this be allowed?
There are many things allowed in the C grammar that may not be particularly good style.
under clang 7.0.0 you don't even need to return anything! I thought non void functions having no return statements was a compiler error (with the only exception being main), but clang lets you off the hook with a warning.
It is not an error nor undefined behavior to flow out of a function with non-void
return type without a return
as long as the caller does not use the value (6.9.1p12 of the C standard).
But it is very bad style to do because then callers have to be aware of the conditions where they can or not use the return value (plus the return value is commonly used for error codes in C which the caller needs to check anyway) so all compilers implement a warning.
unless, I guess, you create a struct inside a function, change its data and then return it.
Well, that is the point: you can declare a struct
in-place to return several values from a function.
Although I'm not sure why it doesn't as the struct is being allocated on the stack and whenever it would go out of scope (which is right when function ends) it would get deallocated and the address would become invalid.
You are returning by value, there is nothing wrong with that. If what you say were true, even returning an int
would be a problem.
Upvotes: 5