C ++: прямое объявление const с внутренней связью - PullRequest
4 голосов
/ 17 февраля 2020

Я хочу переслать объявление константной переменной без , присваивающей ей внешнюю связь. Однако мне кажется, что это невозможно, потому что ключевое слово extern одновременно означает «это имеет внешнюю связь» и «это объявление переменной, а не определение», и я не могу получить одно без другого:

//// 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

Правильно ли мое понимание? Есть ли обходные пути?

1 Ответ

0 голосов
/ 17 февраля 2020

Прежде всего, предварительное объявление определяется только для типов. Вы можете набрать

class X;

и затем использовать, например, X *.

То, чего вы пытаетесь достичь, это объявить символ перед фактическим использованием. Единственный способ, которым я знаю, сделать это через ключевое слово extern.

Но если вы хотите сделать внутреннюю связь символов, анонимное пространство имен может помочь

namespace {
extern const char table[256]; // symbol declaration. Internal linkage.
}

char foo() {
    // use table
}
namespace {
const char table[256] = {...}; // symbol definition. Internal linkage.
}

Здесь это тест, который вы можете сделать

$ 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
$
...