Kitswas
Kitswas

Reputation: 1197

extern enum in header file

In my project, I have a header file containing the following lines.

extern enum class options {alpha, beta, gamma, theta};
extern options P1, P2;

Compilation gives me

error: a storage class can only be specified for objects and functions

Why?
How can I rectify this?

Compiler: GCC 9.2.0

Upvotes: 3

Views: 2038

Answers (2)

Wyck
Wyck

Reputation: 11720

There's no storage associated with an enum class definition. So it doesn't make sense for it to be marked as extern.

A variable whose type is an enum class, on the other hand, can certainly be extern because there's storage associated with a variable to hold the value of that variable. The location of this storage is something that the linker must ultimately work out.

It makes sense to know of the existence of a variable without being responsible for designating storage for it at link time. This is how you get global variables. For example:

main.cpp

int foo = 5; // declaration and definition together.

other.cpp

extern int foo; // declaration only, (external definition still required elsewhere)
// but you can now use `foo` in this file. e.g.:
int examineFoo() {
  return foo;
}

This is also useful if you want to provide a declaration of a global variable in a header file. For example:

main.cpp

#include "foo.h"
int foo = 5;

foo.h

extern int foo;

other.cpp

#include "foo.h"
int examineFoo() {
  return foo;
}

It's okay to encounter both the extern declaration and the definition in the same file. e.g.:

extern int foo;
int foo = 5;

To fix your problem

To fix exactly the example you provided, you can remove extern from the enum class definition, where it does not make sense to have it.

enum class options {alpha, beta, gamma, theta};
extern options P1, P2;

Remember that some non-extern definition of those variables P1 and P2 will be required in another module in order for your program to link if you make use of them.

For you, you probably want the class to be defined in a header, along with an extern declaration of any global variables (yuck) you want in your program.

options.h

enum class options {alpha, beta, gamma, theta};
extern options P1, P2;

options.cpp

#include "options.h"
options P1 = options::alpha, P2 = options::beta;

In options.cpp you include options.h to get the definition of the enum class. It also came with an extern definition of the global variables P1 and P2, which wasn't strictly necessary as they are going to be defined in this file anyway, but it's not illegal to do it.

other.cpp

#include "options.h"
options examineOptionP1() {
   return P1;
}

other.cpp is aware of the class definition for options and is aware of extern declarations of P1 and P2.

Upvotes: 1

dbush
dbush

Reputation: 223689

extern is applied to variables to specify that they have external linkage. What you have is not a variable but an enum definition, therefore extern cannot be applied to it.

What you can do is apply extern to variables at file scope of the enum type.

For example, your header file would have:

enum options {alpha, beta, gamma, theta};

extern options myoption;

And in one source file you would have:

options myoption;

Upvotes: 2

Related Questions