1

When I define an enum class inside a function, it has a value from the available options. However, when I define it within a class, it has value of none of the options. So what is the initial value of g.f? what will return true when compared? ((g.f==??)==true) ?

#include <iostream>

enum class Fruit
{
    apple,
    orange
};

class Garden
{
public:
    Fruit f;
};

void print_enum(Fruit f)
{
    switch(f)
    {
        case Fruit::apple:
            std::cout<<"apple\n";
            break;
        case Fruit::orange:
            std::cout<<"orange\n";
            break;
        default:
            std::cout<<"other\n";
            break;
    }   
}

int main()
{
    Garden g;
    Fruit f;

    print_enum(f); // apple
    print_enum(g.f); // other

    return 0;
}
7
  • 6
    Undefined behaviour. There is no reliable initial value here, and printing it can cause other problems too. You have to assign a value. Commented Jul 22, 2017 at 6:22
  • @deviantfan, I know it is an undefined behavior. But why it is neither apple nor orange? Commented Jul 22, 2017 at 6:23
  • 5
    Because it's UB? Do you expect UB making sense? Commented Jul 22, 2017 at 6:23
  • 1
    Uninitialized local variables (like both g and f) have an indeterminate value. Commented Jul 22, 2017 at 6:25
  • 2
    Regarding all the talk about undefined behavior, you might want to read a bit more about it. Commented Jul 22, 2017 at 6:27

2 Answers 2

1

Always initialize your variables, C++ doesn't intialize them with a "default" value in several occasions.

In both cases you have written here you are at the mercy of your compiler and OS, but likely you'll end up with garbage in your enum variable (that's what you experiment in your latter case). If you want to see what that garbage is, execute this:

std::cout << (int)g.f << std::endl;
Sign up to request clarification or add additional context in comments.

2 Comments

it is -1875479328
There it is, it's what one commonly calls garbage but it's actually the value of whatever was using that memory before your variable was using that space. Just remember to initialize your variables to 0, null, apple or whatever makes sense in each case.
1

The standard stipulates that accessing the value of an uninitialised variable of automatic storage duration gives undefined behaviour.

The consequence is that any operation which relies on accessing the value gives undefined behaviour. Accessing the value of a variable is necessary to;

  • Compare it with another value. For example, a == b gives undefined behaviour if either a or b is uninitialised. Even the comparison a == a gives undefined behaviour if a is uninitialised.
  • Assign the value to another variable. For example, a = b gives undefined behaviour if b is uninitialised.
  • Pass it to a function by value. For a function f(), the call f(a) will give undefined behaviour if a is uninitialised.
  • Output the value. For example, std::cout << a gives undefined behaviour if a is uninitialised.

Because of this, there is no point in requiring an uninitialised variable to have a particular value. Accessing the value gives undefined behaviour, so testing if it is equal (or not equal, or greater than, or ....) to any value gives undefined behaviour.

This is often summarised by describing the value of an uninitialised variable as indeterminate. If it is not possible to access a value without introducing undefined behaviour, it is not possible to reliably determine what the value is.

Of course, there is then the question of why the standard deems that accessing the value of an uninitialised variable gives undefined behaviour. Leaving the value uninitialised allows the compiler to allocate memory for the variable (e.g. from stack) but not bother initialising it - the data in that memory can be whatever happens to be there. Initialising a variable to any specified value can be an expensive operation (e.g. an array of two million elements is a variable, albeit a big one, and initialising it may be computationally expensive). It is also often an unnecessary operation, since the first thing a lot of code does to an initialised variable is (wait for it ....) to assign a value to it i.e. to initialise it.

An operation that is (potentially) both unnecessary and computationally wasteful tends to be unpopular with both programmers and compiler vendors. Making the behaviour undefined does away with all of that .... albeit by requiring programmers to be careful to initialise their variables before any operation that accesses their values.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.