Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.57/76: Рейтинг темы: голосов - 76, средняя оценка - 4.57
5 / 5 / 4
Регистрация: 18.11.2014
Сообщений: 81

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

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

Студворк — интернет-сервис помощи студентам
как создать?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
20.11.2014, 22:43
Ответы с готовыми решениями:

Как создать константу для нескольких файлов проекта
Создал константу, если писать в несколько заголовочных файлов а потом инклюдить в один вызывается ошибка

Как создать глобальную константу для объекта
Может я просто терминологию где-то неверно использую - заранее не кидайтесь пустыми бутылками))) Есть 5 процедур, работающих с 3...

Как объявить глобальную переменную для всего проекта?
Как объявить переменную для всего проекта, а не для одной формы или блока? То, что в VB делается в модуле.

24
28 / 5 / 1
Регистрация: 18.11.2014
Сообщений: 68
20.11.2014, 23:38
globalconst.hpp:
C++
1
extern const int globalconst;
globalconst.cpp:
C++
1
const int globalconst = 777;
Потом инклудить globalconst.hpp где нужно. При желании можно поместить её в namespace или в статический класс.
2
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
20.11.2014, 23:45
Цитата Сообщение от Fasterbru Посмотреть сообщение
как создать?
Это зависит от того, что имеется в виду под "глобальностью" и "константностью". Какого типа константа? Насколько "тяжел" этот тип?

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

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

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

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

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

Цитата Сообщение от true_bugmaker Посмотреть сообщение
Если константу объявить в общем заголовочном файле, линковщик грязно выругается на обилие одинаковых глобальных имён.
Неправда. В языке С++ (в отличие от С) 'const' объекты имеют внутреннее связывание по умолчанию. Никакой ругани от линковщика не будет. Более того, современный компилятор вообще не создаст такого объекта в памяти, если константа нигде не используется как lvalue.
0
28 / 5 / 1
Регистрация: 18.11.2014
Сообщений: 68
21.11.2014, 00:48
http://en.wikipedia.org/wiki/One_Definition_Rule
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
21.11.2014, 01:02
Цитата Сообщение от 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.
0
28 / 5 / 1
Регистрация: 18.11.2014
Сообщений: 68
21.11.2014, 01:15
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
ODR по ссылке относится только к сущностям с external linkage. Объекты, объявленные с internal linkage, образуют разные, независимые объекты в разных единицах трансляции. Поэтому множественное определение 'const' объекта в С++ в разных единицах трансляции не является нарушением ODR.
ТС нигде не указывал таких тонкостей своего проекта.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
21.11.2014, 01:58
Цитата Сообщение от true_bugmaker Посмотреть сообщение
ТС нигде не указывал таких тонкостей своего проекта.
Я не вижу, какое отношение это может иметь к каким-то "тонкостям проекта". Это фундамент языков С и С++, который всегда присутствует во всех "проектах" без исключения.

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

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

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

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

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

Зрителям: как думаете - тролль?
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
21.11.2014, 04:22
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Зрителям: как думаете - тролль?
врядли. Многие с удивлением узнают о раздельной компиляции, а тут про линковку...
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
21.11.2014, 04:45
Цитата Сообщение от Croessmah Посмотреть сообщение
Многие с удивлением узнают о раздельной компиляции, а тут про линковку...
Да, но человек знает аббревиатуру ODR и приводит цитаты из стандарта (в другом треде, пусть и не до конца их понимая). В такой ситуации странно видеть, что человек не знает того элементарного факта, что, например, объявление 'static int i = 5;' или 'const int j = 10;' в заголовочном файле не приводит к нарушению ODR и никогда нарушением ODR не являлось.
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
21.11.2014, 04:56
TheCalligrapher, всё-таки я считаю, что знать и понимать это разные понятия.
0
 Аватар для gromo
383 / 281 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
21.11.2014, 06:10
TheCalligrapher, вообще подход true_bugmaker более предпочтителен, так как константы обычно заводят для того, чтобы можно было быстренько поменять их значение и проверить работу программы. И если константа будет определена в заголовочном файле, то придется перекомпилировать все модули, куда включается этот заголовочный файл. А если завести себе отдельный файл config.cpp с константами, то перекомпилять надо будет только его ну и заново слинковать естественно.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
21.11.2014, 07:15
Цитата Сообщение от gromo Посмотреть сообщение
И если константа будет определена в заголовочном файле, то придется перекомпилировать все модули, куда включается этот заголовочный файл. А если завести себе отдельный файл config.cpp с константами,
Как уже было сказано мной выше, каждый подход имеет свои преимущества и недостатки. Если выбранный способ задания константы не подходит для ваших целей, то не важно быстро компилируется проект или нет.

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

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

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

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

В языке С, например, 'const' объекты вообще никогда не являются константами, где их не объявляй. Поэтому в языке С огромное количество именованных констант объявляется через '#define'. '#define' и 'enum' - это фактически единственные спосбы получить именованную константу времени компиляции в С.
1
 Аватар для gromo
383 / 281 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
21.11.2014, 19:33
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Она не может использоваться для задания размера массивного типа
Как оказалось, может. А в остальных случаях - согласен.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
21.11.2014, 19:55
Цитата Сообщение от gromo Посмотреть сообщение
Как оказалось, может
Нет, не оказалось. В С++ - не может. Я специально сослался именно на массивный тип, чтобы исключить из рассмотрения выражения типа 'new int[n]'. Размеры в массив-типах в С++ - только константы времени компиляции.
0
 Аватар для gromo
383 / 281 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
21.11.2014, 20:27
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тых расширений к языку
ЧЯДНТ?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
21.11.2014, 20:46
Цитата Сообщение от 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."
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
21.11.2014, 20:46
Помогаю со студенческими работами здесь

Как объявить глобальную константу?
Пример из хелпа не работает: ' Declare Public constant. Public Const MyString = 'HELP'

Как qt создать глобальную переменную для двух классов?
Как qt создать глобальную переменную для двух классов, которой не будет в mainwindow.cpp?

Как создать глобальную переменную для доступа из других файлов?
TStringList* SL = new TStringList; Как создать не в функции, а как глобальную переменную для доступа из других файлов?

Как сделать указатель глобальным для всего проекта?
При компиляции выдает следующее Checking project dependencies... Compiling Project1.cbproj (Debug, Win32) bcc32 command line for...

Как объявить переменную для доступа на уровне всего проекта
Имеется программа, в которой вычисляются массивы: ReDim A#(i), B#(i) Как мне сделать так, чтоб к ним я мог обращаться из другой формы? ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru