Подтвердить что ты не робот

Почему множественное определение глобальной переменной const разрешено в С++, а не в C?

Множественное определение глобальной переменной не допускается на C или С++ из-за правила One Definition. Однако в С++ глобальная переменная const может быть определена в нескольких единицах компиляции без ошибок. Это не то же самое, что в C.

Почему С++ разрешает это, пока C не работает? Почему использование и поведение глобального константа отличаются от неконстантного глобального таким образом в С++ по сравнению с C? Что происходит под обложками с С++ и C относительно const?

Например, это разрешено в С++, но неправильно в C:

// Foo.cpp
const int Foo = 99;

// Main.cpp
const int Foo = 99;
int main()
{
    cout << Foo << endl;
    return 0;
}

И это хорошо с C, но неправильно с С++:

// Foo.cpp
const int Foo = 99;

// Main.cpp
extern const int Foo;
int main()
{
    cout << Foo << endl;
    return 0;
}
4b9b3361

Ответ 1

// Foo.cpp
const int Foo = 99;

// Main.cpp
const int Foo = 99;

const переменная в пространстве имен имеет внутреннюю связь. Таким образом, они в основном две разные переменные. Нет переопределения.

Из комментария @David, 3.5/3 [basic.link]:

Имя, имеющее область пространства имен (3.3.5) имеет внутреннюю связь, если это имя из
- объект, ссылка, функция или функциональный шаблон, который явно объявлено статическим или,
- объект или ссылка явно объявлена const и не объявлено явно извне или ранее объявлен внешняя связь; или
- член данных анонимного союза.


Во втором случае вы должны делать это (правильный путь):

//Foo.h
extern const int Foo; //use extern here to make it have external linkage!

// Foo.cpp
#include "Foo.h"
const int Foo = 99; //actual definition goes here

// Main.cpp
#include "Foo.h"
int main()
{
   cout << Foo << endl;
}

Ответ 2

Я думаю, что вы просите об обосновании, а не о конкретном правиле языка, которое позволяет это.

Обоснование этого состоит в том, что он облегчает использование переменных const. Он дает типизированную замену для одного общего использования #define.

Вместо #define MAX_COUNT 211 вы можете использовать const int max_count = 211; точно так же, например. общий заголовочный файл, не беспокоясь о том, где поставить одно определение.

Вы не можете юридически изменить значение объекта const, чтобы не было видимой разницы между наличием одного объекта и нескольких объектов с тем же значением.

Как вы можете поместить определение объекта const в заголовочный файл, для компилятора тривиально использовать значение непосредственно на этапе компиляции, при этом такие оптимизации не должны быть отложены до фиксации времени ссылки.

Ответ 3

В основном, в С++ константные, нелокальные переменные являются подлинными константными выражениями или constexpr. Это позволяет много вещей, таких как TMP.

const int five = 5;
int main() {
    int x[five];
    std::array<int, five> arr;
}

В C это просто переменная, которая не может быть изменена. То есть

const int five = 5;
int main() {
    int x[five]; // Technically, this is a variable length array
}

Достаточно эквивалентно

int five = 5;
int main() {
    int x[five];
}

Фактически, С++ продвигает некоторые виды переменной const в новую категорию, constexpr, тогда как в C это не существует, и они являются просто переменными, которые не подлежат модификации.

Ответ 5

Почему английские люди заклинают ЦВЕТ, тогда как американские люди заклинают его ЦВЕТ?

Это два разных языка из одной базы, но они не имеют одинаковых правил.

C и С++ - то же самое. Если бы они не были разными, их оба называли бы одним и тем же.

Ответ 6

Мое обходное объявление объявляло это как:

static classfoo foo;

он работал в моей ситуации.