Почему const подразумевает внутреннюю связь в C ++, а в C - нет?

83

См. Тему. О чем они думали?

ОБНОВЛЕНИЕ: изменено со «статического» на «внутреннее связывание», чтобы избежать путаницы.

Чтобы привести пример ... Помещение в файл следующего:

const int var_a = 1;
int var_b = 1;

... и компиляция g++ -c test.cppтолько с экспортом var_b.

Йохан Котлински
источник

Ответы:

113

Я верю ты имеешь в виду

Почему const подразумевает внутреннюю компоновку в C ++

Верно, что если вы объявляете объект const в области пространства имен, он имеет внутреннюю связь.

Приложение C ( C ++ 11, C.1.2 ) дает обоснование

Изменение: имя области действия файла, которое явно объявлено как const, а не явно объявлено как extern, имеет внутреннюю связь, тогда как в C оно будет иметь внешнюю связь.

Обоснование: поскольку объекты const могут использоваться как значения времени компиляции в C ++, эта функция побуждает программистов предоставлять явные значения инициализатора для каждой константы. Эта функция позволяет пользователю помещать константные объекты в файлы заголовков, которые включены во многие единицы компиляции.

Йоханнес Шауб - litb
источник
Кажется, что неконстантные глобальные объекты также могут быть инициализированы, но почему стандарт не дает им внутренней связи?
Йонг Ли
13

Как сказано в литб, constобъекты в C ++ имеют внутреннюю связь. Это потому, что они предназначены для использования следующим образом:

// a.cpp
const int BUFSIZE = 100;
char abuf[BUFSIZE];

// b.cpp
const int BUFSIZE = 256
int bbuf[BUFSIZE];
RobertS поддерживает Монику Челлио
источник
6

Const и static являются ортогональными понятиями как в C, так и в C ++.

В constКлючевое слово указывает компилятору , чтобы запретить переменную появляться как Lvalue любого выражения - по существу , делает его только для чтения.

В языке C staticключевое слово имеет несколько применений в зависимости от того, к чему оно применяется. При применении к переменной функции он указывает, что переменная не хранится в локальной области видимости функции, но доступна при ее вызовах. При применении к глобальной переменной или функции он становится доступным только для определенного файла - другими словами, он доступен только внутри модуля компиляции (если не объявлен extern).

В C ++ staticключевое слово можно использовать в определении класса, чтобы переменная или функции были общими для всех экземпляров класса, а не были локальными для каждого экземпляра. Кроме того, функция статического класса в C ++ может обращаться только к статическим переменным этого класса (или классов, к которым у нее есть доступ). Теперь в C ++ constчленам предоставляется внутренняя связь с модулем компиляции, если они явно не объявлены extern- это может быть то, о чем вы говорите. Это позволяет совместно использовать константы времени компиляции в модуле с помощью файлов заголовков. Однако имейте в виду, что члены на самом деле не статичны - скорее, константа компилируется в каждое место, где на нее ссылаются.

Л.Бушкин
источник
6

В C и C ++ термин статический имеет несколько значений (он может управлять связыванием и хранением). Вам нужно будет прочитать D&E Страуструпа, чтобы оценить его обоснование, но когда вы объявляете переменную константной в области пространства имен, она автоматически имеет внутреннюю связь - тогда как в C вы должны объявить его статическим, чтобы заставить его иметь внутреннюю связь.

Конечно, в C ++ использование static для управления связыванием устарело, анонимные пространства имен можно использовать для имитации внутренней связи в C ++.

Переменные const в C ++ должны были заменить константы препроцессора - и поскольку константы препроцессора видны только в файлах, которые их определяют, аналогично, const автоматически делает переменную видимой только в файле, который ее определяет.

Фейсал Вали
источник
4

Эти концепции ортогональны и не должны рассматриваться как одно и то же.

Постоянство - это свойство доступа: оно говорит только о том, должна ли ваша переменная быть доступной только для чтения (константная) или для записи-чтения (неконстантная).

Статичность - это свойство времени жизни (и технически локализация памяти): оно сообщает, будет ли переменная глобальной в области видимости класса (когда находится в классе) или единицы перевода (при использовании с глобальной переменной, определенной в cpp) .

Клаим
источник
-2

Это не так, и наиболее очевидным примером является то, что если у вас есть переменная-член const (которая, конечно, инициализируется конструктором), она не используется всеми объектами этого класса, но индивидуальна для каждого.

class A {
public:
  A(int newx) : x(newx);
private
  int x;
}

litb дает лучший ответ выше.

Алекс Браун
источник
Разве он не всегда? (litb)
RastaJedi
-5

Это не так. Пишем следующее:

const int i = 0;

не делает iстатическим (ни в C, ни в C ++).

Мартин Кот
источник