I want to forward declare a const variable without giving it external linkage. It seems to me, however, that this is impossible because the extern
keyword simultaneously means "this has external linkage" and "this is a variable declaration, not a definition", and I can't get one without the other:
//// main.cpp: ////
extern const char table[256]; // forward declaration. External linkage.
// const char table[256]; // Error: table requires an initializer
// static const char table[256]; // Same error
// foo uses table so I need it forward declared:
char foo()
{
// uses table
}
const char table[256] = {...}; // Actual definition
Is my understanding correct? Are there any workarounds?
First of all, a forward declaration is defined only for types. You can type
class X;
and then use X *
for example.
What you are trying to achieve here, is declare symbol before actual usage.
The only way I know to do this is via extern
keyword.
But if want to make symbol linkage internal, anonymous namespace can help
namespace {
extern const char table[256]; // symbol declaration. Internal linkage.
}
char foo() {
// use table
}
namespace {
const char table[256] = {...}; // symbol definition. Internal linkage.
}
Here is a test you can do
$ cat test.cc
extern const char moo[4];
char foo() { return moo[2]; }
const char moo[4] = {0};
$ g++ -c test.cc -o test.o -O3 && g++ test.o -shared -o test.so && nm -gD test.so | grep moo
00000000000005ad R moo
$
$ cat test.cc
namespace {
extern const char moo[4];
}
char foo() { return moo[2]; }
namespace {
const char moo[4] = {0};
}
$ g++ -c test.cc -o test.o -O3 && g++ test.o -shared -o test.so && nm -gD test.so | grep moo
$