Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ struct declared in function visible in main

Tags:

c++

c++14

why does this code work? with c++14

// Example program
#include <iostream>
#include <string>
using namespace std;


auto fun()
{
    struct a
    {
        int num = 10;
        a()
        {

            cout << "a made\n";
        }
        ~a()
        {
            cout << "a destroyed\n";
        }
    };
    static a a_obj;
    return a_obj;
}


int main()
{
    auto x = fun();
    cout << x.num << endl;

}

how is the type a visible in main? if i change auto x= to a x= it obviously doesn't compile, but how does main know about the type a?

The static declaration is there since I was trying to test for something else but then I stumbled upon this behavior.

Running it here: https://wandbox.org/permlink/rEZipLVpcZt7zm4j

like image 914
PYA Avatar asked Aug 17 '17 14:08

PYA


People also ask

Can we declare struct inside function in C?

Yes, the standard allows this, and yes, the name you create this way is only visible inside the function (i.e., it has local scope, just like when you define int i; , i has local scope). or, if you're really only going to use it once, struct { /* ...

Can struct be declared inside function?

The function is declared inside the struct definition, in order to make the relationship between the structure and the function explicit.

How do you pass a structure to a function in C?

To pass a structure to a function we have to properly declare the function parameter list. In the following example we are creating a student structure. struct student { char firstname[64]; char lastname[64]; char id[64]; int score; };

Can a function return a structure variable?

This can be done using call by reference as well as call by value method. How to return a structure from the functions? To return a structure from a function the return type should be a structure only.


2 Answers

This is all surprising until you realize this: name visibility doesn't hide the type. It just hides the name of the type. Once you understand this it all makes sense.

I can show you this without auto, with just plain old templates:

auto fun()
{
    struct Hidden { int a; };

    return Hidden{24};
}

template <class T> auto fun2(T param)
{
    cout << param.a << endl; // OK
} 

auto test()
{
    fun2(fun()); // OK
}

If you look closely you will see this is the same situation as yours:

you have a struct Hidden which is local to fun. Then you use an object of type Hidden inside test: you call fun which returns a Hidden obj and then you pass this object to the fun2 which in turn has no problem at all to use the object Hidden in all it's glory.

as @Barry suggested the same thing happens when you return an instance of a private type from a class. So we have this behavior since C++03. You can try it yourself.

like image 55
bolov Avatar answered Sep 18 '22 14:09

bolov


C++14 is made to be more and more tolerant with auto. Your question is not clear, because you're not stating what the problem is.

Now let's tackle your question differently: Why does it not work with a x = ...?

The reason is that the struct definition is not in the scope of the main. Now this would work:

// Example program
#include <iostream>
#include <string>
using namespace std;

struct a
{
    int num = 10;
};

auto fun()
{
    static a a_obj;
    return a_obj;
}


int main()
{
    a x = fun();
    cout << x.num << endl;

}

Now here it doesn't matter whether you use a or auto, because a is visible for main(). Now auto is a different story. The compiler asks: Do I have enough information to deduce (unambiguously) what the type of x is? And the answer is yes, becasue there's no alternative to a.

like image 45
The Quantum Physicist Avatar answered Sep 18 '22 14:09

The Quantum Physicist