Platon Makovsky
Platon Makovsky

Reputation: 285

What's the deal with being allowed to define a struct in the return type of a function definition? (C)

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

Answers (2)

S.S. Anne
S.S. Anne

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

Acorn
Acorn

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

Related Questions