Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.70
Fasterbru
5 / 5 / 2
Регистрация: 18.11.2014
Сообщений: 81
#1

Как создать глобальную константу для всего проекта? - C++

20.11.2014, 22:43. Просмотров 1397. Ответов 24
Метки нет (Все метки)

как создать?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.11.2014, 22:43     Как создать глобальную константу для всего проекта?
Посмотрите здесь:

C++ Как обьявить глобальную переменную в функции?
C++ Где хранить глобальную переменную для всех представлений?
C++ Как и где описать глобальную переменную?
C++ Как обьявить глобальную переменную
C++ Как правильно объявить константы для всего проекта, который состоит из нескольких файлов
Как глобальную переменную засунуть в структуру? C++
Как создать глобальную переменную? C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
true_bugmaker
28 / 5 / 1
Регистрация: 18.11.2014
Сообщений: 68
20.11.2014, 23:38     Как создать глобальную константу для всего проекта? #2
globalconst.hpp:
C++
1
extern const int globalconst;
globalconst.cpp:
C++
1
const int globalconst = 777;
Потом инклудить globalconst.hpp где нужно. При желании можно поместить её в namespace или в статический класс.
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3614 / 1889 / 501
Регистрация: 18.10.2014
Сообщений: 3,451
20.11.2014, 23:45     Как создать глобальную константу для всего проекта? #3
Цитата Сообщение от Fasterbru Посмотреть сообщение
как создать?
Это зависит от того, что имеется в виду под "глобальностью" и "константностью". Какого типа константа? Насколько "тяжел" этот тип?

Для скалярных типов в С++ в заголовочном файле просто пишется

C++
1
2
const int MY_GLOBAL_CONSTANT = 42;
const char *const MY_GLOBAL_STRING = "Hello";
и все. Вопрос закрыт.

Но если вы где-то в программе будете брать адрес этой константы '&MY_GLOBAL_CONSTANT', то в разных модулях этот адрес будет разным. Это вас волнует? Если волнует, то делать следует так показал true_bugmaker. Но в этом случае константа не будет константой времени компиляции в тех модулях, в которых видно только ее объявление.

Если тип вашей константы не скалярен ("тяжелый тип"), то опять же лучше поступить как показал true_bugmaker.
true_bugmaker
28 / 5 / 1
Регистрация: 18.11.2014
Сообщений: 68
21.11.2014, 00:17     Как создать глобальную константу для всего проекта? #4
Но если вы где-то в программе будете брать адрес этой константы '&MY_GLOBAL_CONSTANT', то в разных модулях этот адрес будет разным.
Если объявлять эту константу каждую в своём модуле, и вдруг придётся её менять, будет худо. Если константу объявить в общем заголовочном файле, линковщик грязно выругается на обилие одинаковых глобальных имён.
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3614 / 1889 / 501
Регистрация: 18.10.2014
Сообщений: 3,451
21.11.2014, 00:29     Как создать глобальную константу для всего проекта? #5
Цитата Сообщение от true_bugmaker Посмотреть сообщение
Если объявлять эту константу каждую в своём модуле, и вдруг придётся её менять, будет худо.
В языке C++ (в отличие от С) явно инициализированные 'const' объекты целочисленных типов образуют Integral Constant Expressions. Это настолько ценное свойство целочисленных 'const' объектов, что пожертвовать им мы не можем и ради него будем объявлять такие константы именно так, как я показал.

Разумеется, надо следить за глобальностью констант и ограничивать ее до минимальной необходимости. Т.е. не совать в действительно глобальные заголовки то, что там не нужно.

Цитата Сообщение от true_bugmaker Посмотреть сообщение
Если константу объявить в общем заголовочном файле, линковщик грязно выругается на обилие одинаковых глобальных имён.
Неправда. В языке С++ (в отличие от С) 'const' объекты имеют внутреннее связывание по умолчанию. Никакой ругани от линковщика не будет. Более того, современный компилятор вообще не создаст такого объекта в памяти, если константа нигде не используется как lvalue.
true_bugmaker
28 / 5 / 1
Регистрация: 18.11.2014
Сообщений: 68
21.11.2014, 00:48     Как создать глобальную константу для всего проекта? #6
http://en.wikipedia.org/wiki/One_Definition_Rule
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3614 / 1889 / 501
Регистрация: 18.10.2014
Сообщений: 3,451
21.11.2014, 01:02     Как создать глобальную константу для всего проекта? #7
Цитата Сообщение от true_bugmaker Посмотреть сообщение
http://en.wikipedia.org/wiki/One_Definition_Rule
Учитесь понимать терминологию. ODR по ссылке относится только к сущностям с external linkage. Объекты, объявленные с internal linkage, образуют разные, независимые объекты в разных единицах трансляции. Поэтому множественное определение 'const' объекта в С++ в разных единицах трансляции не является нарушением ODR. Это просто определения разных, независимых объектов, а не множественное определение одного и тот же объекта.

Точно так же как определение 'static int i = 5;' в разных единицах трансляции не является нарушением ODR, определение 'const int j = 42;' в разных единицах трансляции не является нарушением ODR. В языке С++ для переменной в namespace scope 'const' эквивалентно 'static const'.

7.1.1 Storage class specifiers

6 A name declared in a namespace scope without a storage-class-specifier has external linkage unless it has internal linkage because of a previous declaration and provided it is not declared const. Objects declared const and not explicitly declared extern have internal linkage.
true_bugmaker
28 / 5 / 1
Регистрация: 18.11.2014
Сообщений: 68
21.11.2014, 01:15     Как создать глобальную константу для всего проекта? #8
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
ODR по ссылке относится только к сущностям с external linkage. Объекты, объявленные с internal linkage, образуют разные, независимые объекты в разных единицах трансляции. Поэтому множественное определение 'const' объекта в С++ в разных единицах трансляции не является нарушением ODR.
ТС нигде не указывал таких тонкостей своего проекта.
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3614 / 1889 / 501
Регистрация: 18.10.2014
Сообщений: 3,451
21.11.2014, 01:58     Как создать глобальную константу для всего проекта? #9
Цитата Сообщение от true_bugmaker Посмотреть сообщение
ТС нигде не указывал таких тонкостей своего проекта.
Я не вижу, какое отношение это может иметь к каким-то "тонкостям проекта". Это фундамент языков С и С++, который всегда присутствует во всех "проектах" без исключения.

Спецификация 'const' объектов целочисленных типов языка С++ специально разработана так, чтобы 'const int N = 42;' при правильном использовании мог выступать в качестве константы времени компиляции, т.е. в качестве замены для '#define N 42' из языка С. '#define' считается слишком грубым инструментом, так как не поддерживает типизации и не подчиняется областям видимости.

В языке С++ (в отличии от С) разрешается использовать 'const' объекты целочисленных типов, например, для задания меток case, ширин битовых полей, размеров любых массивов, инициализаторов enum констант и т.п. Но чтобы 'const' объекты можно было использовать в такой роли глобально в проекте, их инициализаторы должны быть видны во всем проекте. Т.е. поступать придется именно так, как показано в моем примере и платить за это перекомпиляцией всего проекта при изменении значения константы.

А если вам не нужно, чтобы ваша глобальная константа была константой времени компиляции, а была просто "неизменяемой переменной" (как это было в С), то можно пойти по вашему пути через 'extern const' в заголовочном файле.
true_bugmaker
28 / 5 / 1
Регистрация: 18.11.2014
Сообщений: 68
21.11.2014, 02:14     Как создать глобальную константу для всего проекта? #10
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Я не вижу, какое отношение это может иметь к каким-то "тонкостям проекта". Это фундамент языков С и С++, который всегда присутствует во всех "проектах" без исключения.
То есть ТС не гарантированно не огребёт проблем нарушая ODR направо и налево?
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3614 / 1889 / 501
Регистрация: 18.10.2014
Сообщений: 3,451
21.11.2014, 03:23     Как создать глобальную константу для всего проекта? #11
Цитата Сообщение от true_bugmaker Посмотреть сообщение
проблем нарушая ODR направо и налево
Я не имею прямого доступа к проекту ТС и поэтому не знаю, что он там нарушает или не нарушает.

Вы, видимо, чего то не поняли. Мое объяснение выше не является каким-то трюком уровня специфического линкера. Концепции linkage (external linkage и internal linkage) - это языковые концепции, взятые непосредственно из спецификации языка. В спецификации языка нигде не сказано, что определение констант c internal linkage в заголовочном файле в С++ является нарушением ODR. Нет, не является и никогда не являлось.

Ни в языке С, ни в языке С++ невозможно нарушить ODR путем определения объектов c internal linkage в разных единицах трансляции. Это, вообще то, азы объектной модели С и С++. Меня удивляет, что приходится тратить столько времени на объяснение такой элементарщины человеку, который в состоянии найти статью про ODR в Википедии.

Зрителям: как думаете - тролль?
Croessmah
Модератор
Эксперт CЭксперт С++
12878 / 7264 / 810
Регистрация: 27.09.2012
Сообщений: 17,950
Записей в блоге: 2
Завершенные тесты: 1
21.11.2014, 04:22     Как создать глобальную константу для всего проекта? #12
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Зрителям: как думаете - тролль?
врядли. Многие с удивлением узнают о раздельной компиляции, а тут про линковку...
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3614 / 1889 / 501
Регистрация: 18.10.2014
Сообщений: 3,451
21.11.2014, 04:45     Как создать глобальную константу для всего проекта? #13
Цитата Сообщение от Croessmah Посмотреть сообщение
Многие с удивлением узнают о раздельной компиляции, а тут про линковку...
Да, но человек знает аббревиатуру ODR и приводит цитаты из стандарта (в другом треде, пусть и не до конца их понимая). В такой ситуации странно видеть, что человек не знает того элементарного факта, что, например, объявление 'static int i = 5;' или 'const int j = 10;' в заголовочном файле не приводит к нарушению ODR и никогда нарушением ODR не являлось.
Croessmah
Модератор
Эксперт CЭксперт С++
12878 / 7264 / 810
Регистрация: 27.09.2012
Сообщений: 17,950
Записей в блоге: 2
Завершенные тесты: 1
21.11.2014, 04:56     Как создать глобальную константу для всего проекта? #14
TheCalligrapher, всё-таки я считаю, что знать и понимать это разные понятия.
gromo
370 / 269 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
21.11.2014, 06:10     Как создать глобальную константу для всего проекта? #15
TheCalligrapher, вообще подход true_bugmaker более предпочтителен, так как константы обычно заводят для того, чтобы можно было быстренько поменять их значение и проверить работу программы. И если константа будет определена в заголовочном файле, то придется перекомпилировать все модули, куда включается этот заголовочный файл. А если завести себе отдельный файл config.cpp с константами, то перекомпилять надо будет только его ну и заново слинковать естественно.
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3614 / 1889 / 501
Регистрация: 18.10.2014
Сообщений: 3,451
21.11.2014, 07:15     Как создать глобальную константу для всего проекта? #16
Цитата Сообщение от gromo Посмотреть сообщение
И если константа будет определена в заголовочном файле, то придется перекомпилировать все модули, куда включается этот заголовочный файл. А если завести себе отдельный файл config.cpp с константами,
Как уже было сказано мной выше, каждый подход имеет свои преимущества и недостатки. Если выбранный способ задания константы не подходит для ваших целей, то не важно быстро компилируется проект или нет.

Ещё раз: константа, объявленная по методу 'extern const' НЕ является константой вообще. Это "неизменяемая переменная", а не константа. Она не может использоваться там, где язык С++ требует константу. Она не может использоваться для задания размера массивного типа, она не может использоваться в метках case, она не может использоваться как параметр шаблона, и т.д. и т.п. В дополнение к этому, 'extern const' значение не может напрямую участововать в оптимизациях времени компиляции. Другими словами в огромном количестве (или даже в подавляющем большинстве) языковых случаев такая ложная "константа" совершенно бесполезна.

Если же вы работаете над какими-то гигантскими проектами, в которых настоящие константы не нужны, то конечно, для сокращения времени компиляции вам возможно лучше пользоваться подходом с 'extern const'. Но это какие-то очень специфические проекты. В большинстве реальных С++ проектов нужны настоящие константы, т.е. константы времени компиляции. Такие константы можно получить только одним способом - определением прямо в заголовочном файле.

Поэтому рассуждать на тему того, какой способ "предпочтительнее", в большинстве случаев просто не приходится. Если вам нужна настоящая константа в терминологии языка С++, т.е. константа времени компиляции, то никакого выбора у вас нет - константа определяется именно так, как показал я. А то, что ваш проект будет долго перекомпилирваться - это неизбежные реалии языков С и С++.

=============

В языке С, например, 'const' объекты вообще никогда не являются константами, где их не объявляй. Поэтому в языке С огромное количество именованных констант объявляется через '#define'. '#define' и 'enum' - это фактически единственные спосбы получить именованную константу времени компиляции в С.
gromo
370 / 269 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
21.11.2014, 19:33     Как создать глобальную константу для всего проекта? #17
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Она не может использоваться для задания размера массивного типа
Как оказалось, может. А в остальных случаях - согласен.
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3614 / 1889 / 501
Регистрация: 18.10.2014
Сообщений: 3,451
21.11.2014, 19:55     Как создать глобальную константу для всего проекта? #18
Цитата Сообщение от gromo Посмотреть сообщение
Как оказалось, может
Нет, не оказалось. В С++ - не может. Я специально сослался именно на массивный тип, чтобы исключить из рассмотрения выражения типа 'new int[n]'. Размеры в массив-типах в С++ - только константы времени компиляции.
gromo
370 / 269 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
21.11.2014, 20:27     Как создать глобальную константу для всего проекта? #19
TheCalligrapher,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// config.h
#include <cstddef>
extern const std::size_t c_size;
 
// config.cpp
#include "config.h"
const std::size_t c_size = 5u;
 
// main.cpp
#include "config.h"
int main()
{
    int iAr[c_size];
    return 0;
}
Bash
1
g++ -std=c++14 -Wpedantic -Wextra # Без GNUтых расширений к языку
ЧЯДНТ?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.11.2014, 20:46     Как создать глобальную константу для всего проекта?
Еще ссылки по теме:

Как лучше всего создать форму в С++ C++
Как создать release проекта в MS Visual Studio? C++
C++ Как проще всего создать множество?
C++ Как создать 2 проекта в одном solution в Visual Studio?
C++ Как правильно создать глобальную переменную?

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3614 / 1889 / 501
Регистрация: 18.10.2014
Сообщений: 3,451
21.11.2014, 20:46     Как создать глобальную константу для всего проекта? #20
Цитата Сообщение от gromo Посмотреть сообщение
ЧЯДНТ?
Вполне может быть, что вы правы. Я почему-то полагал, что run-time sized arrays были выкинуты из C++14 в последний момент. Но сейчас что-то навскидку не могу найти этому подтверждения...

Похоже они таки вошли. Однако их функциональность существенно урезана по сравнению с С VLA: "T is called the array element type; this type shall not be a reference type, the (possibly cv-qualified) type void, a function type, an array of unknown or runtime bound, or an abstract class type."
Yandex
Объявления
21.11.2014, 20:46     Как создать глобальную константу для всего проекта?
Ответ Создать тему
Опции темы

Текущее время: 04:07. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru