Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.73/15: Рейтинг темы: голосов - 15, средняя оценка - 4.73
383 / 281 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
1

Будут ли все константы гарантированно инициализированы к моменту обращения к ним из разных единиц трансляции

10.08.2014, 00:10. Показов 2800. Ответов 38
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Безопасно ли такое использование:
C++
1
2
3
4
5
6
7
8
9
10
11
// config.cpp
const int ival = 6;
const SomeNonTrivialClass obj(...);
 
// config.h
extern const int ival;
extern const SomeNonTrivialClass obj;
 
// some_source_file.cpp
#include "config.h"
void func() { std::cout << obj << ival;   }
То есть мне нужны просто константы, не статические, собранные в одном файле и которые можно использовать по всей программе. Можно ли не городить Singleton для каждой константы?

Не по теме:

Знаю вопрос тупой, но я запутался что-то :cry:



Забыл главное: будут ли все константы гарантированно инициализированы к моменту обращения к ним из разных единиц трансляции?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.08.2014, 00:10
Ответы с готовыми решениями:

Подождать пока все контролы на форме не будут инициализированы
Проблема следующая: Есть к примеру 2 TextBox К одному из них прикручено событие &quot;Textchanged&quot;. ...

Как создавать файлы, которые будут подгружаться по мере обращения к ним?
У меня приложение занимает 120 kb, при том что программа в целом будет весить не более 800 kb, и...

Какие шрифты гарантированно будут у пользователя(CSS:font-family)
Вопрос к опытным разработчикам: какие шрифты безопаснее всего писать в этом атрибуте CSS? Не хочу...

Как будут инициализированы переменные в теле функции и вне тела функции?
Здравствуйте. Подскажите, пожалуйста, как будут инициализированы переменные в теле функции и вне...

38
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,285
10.08.2014, 02:02 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от gromo Посмотреть сообщение
Это понятно, но не в таких же жЫрных аспектах?
В 2.95.х были еще более жирные аспекты.

Добавлено через 6 минут
Цитата Сообщение от gromo Посмотреть сообщение
Был
Да уж. Ну значит я за 12 лет не встретил примеров нестандартного кода на gcc 2 и 3, которые бы его потребовали. А GCC 2 огромное количество нестандартного кода пропускает. Приходилось портировать программы написанные на 2.95 на более новые версии, ни с чем не сравнимые ощущения. Из серии "как это вообще могло работать".

Добавлено через 10 минут
Цитата Сообщение от DrOffset Посмотреть сообщение
Это понятно, но не в таких же жЫрных аспектах?
Вот например, из того, что вспомнил про 2.95.
Можно было определять параметры по-умолчанию у функций и в определении и в объявлении.
Если у шаблонного класса был добавлен этот же шаблон в друзья (чтобы разные инстанции были друг другу друзьями), то этот код при инстанцировании выдавал internal compiler error. Вообще на ICE там частенько приходилось смотреть. Вот так.
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
10.08.2014, 14:17 22
сколько демагогии, вместо придерживания простых правил: целочисленные константы значения которых известны на момент компиляции оформляем в enum, все прочее в функцию возвращающую const T& на static переменную определенную внутри функции

Добавлено через 1 минуту
Цитата Сообщение от DrOffset Посмотреть сообщение
В пределах одной единицы трансляции порядок определен, если не собираешься использовать их из других глобальных объектов, то все будет хорошо.
скажи это тому кто будет работать с этим кодом через год месяц
0
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,285
10.08.2014, 19:48 23
Цитата Сообщение от Jupiter Посмотреть сообщение
сколько демагогии
Хочется заметить что демагогия, в основном, не касалась первоначальной темы.
Предложенные тобой простые правила тоже не панацея. От перекрестных ссылок, если кто-то захочет, это не спасет: сохранит он себе не копию, а ссылку в другом глобальном объекте, а потом статический объект-владелец уничтожится и получим висячую ссылку. У enum тоже есть свои недостатки (в С++03) - это фиксированный тип значений. А вот мы совсем недавно налетали на такое: один и тот же enum с разными значениями в разных файлах. В одном куске программы одно поведение, в другом - совсем иное, на стыке - хаос и анархия.
Это я к тому, что правила хоть и хорошие (я с ними почти согласен), но субъективные. И ежели кто захочет нагадить, то у него получится, будь уверен.

Цитата Сообщение от Jupiter Посмотреть сообщение
скажи это тому кто будет работать с этим кодом через год месяц
Или я что-то пропустил, или в данной теме не было вопросов о сопровождаемости кода. Был исключительно технический вопрос. Я подразумеваю, что у автора своя голова на плечах и он знает что делает. Переубеждать всех, кто по моему мнению собирается делать что-то некорректное или опасное (в любых смыслах) я лично не собираюсь, и вряд ли хватит сил это делать, если соберусь. Так что тебе тоже не советую. В общем, если какие вопросы по поводу правильности такого подхода, то это к автору, а не ко мне.
0
383 / 281 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
10.08.2014, 22:00  [ТС] 24
Цитата Сообщение от Jupiter Посмотреть сообщение
целочисленные константы значения которых известны на момент компиляции оформляем в enum, все прочее в функцию возвращающую const T& на static переменную определенную внутри функции
я как раз хотел избежать этого:
Цитата Сообщение от gromo Посмотреть сообщение
Можно ли не городить Singleton для каждой константы?
я понимаю, что это не до конца singleton, но я хотел избежать этой дополнительной писанины с локальными статическими константами, обертыванием их в функцию и т.д.
0
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
11.08.2014, 21:56 25
Цитата Сообщение от gromo Посмотреть сообщение
Забыл главное: будут ли все константы гарантированно инициализированы к моменту обращения к ним из разных единиц трансляции?
Да. Все константы и глобальные переменные инициализируются до вызова main(). Причем статическая инициализация (точнее - даже загрузка)
C++
1
int ival= 6;
предшествует динамической
C++
1
const SomeNonTrivialClass obj(...);
При инициализации obj можно использовать ival независимо от того, в каких модулях они описаны.
Последовательность динамической инициализации глобальных переменных, насколько я помню, не определина. Если у вас есть глобальнае obj1 и obj2, то при инициализации одного использовать другой не стоит.
Или я не понял, и вы имели в виду что-то другое?
0
383 / 281 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
11.08.2014, 23:06  [ТС] 26
Цитата Сообщение от gng Посмотреть сообщение
Последовательность динамической инициализации глобальных переменных, насколько я помню, не определина.
Выходит последовательность статической инициализации глобальных переменных также не определена, только она гарантированно происходит до динамической инициализации глобальных объектов?
0
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,285
11.08.2014, 23:37 27
Цитата Сообщение от gromo Посмотреть сообщение
Выходит последовательность статической инициализации глобальных переменных также не определена, только она гарантированно происходит до динамической инициализации глобальных объектов?
А зачем тебе нужна это последовательность? Она ничего не дает.
А вот динамическая инициализация вполне определена:
Dynamic initialization of a non-local variable with static storage duration is either ordered or
unordered. Definitions of explicitly specialized class template static data members have ordered initializa-
tion. Other class template static data members (i.e., implicitly or explicitly instantiated specializations) have
unordered initialization. Other non-local variables with static storage duration have ordered initialization.
Variables with ordered initialization defined within a single translation unit shall be initialized in the order
of their definitions in the translation unit.
2
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
11.08.2014, 23:42 28
Цитата Сообщение от gromo Посмотреть сообщение
Выходит последовательность статической инициализации глобальных переменных также не определена, только она гарантированно происходит до динамической инициализации глобальных объектов?
Я не эксперт в стандартах, но писать в глобальной секции одного си модуля
int a= 5;
а в глобальной секции другого
int b= a;
я бы не решился. Хотя, возможно, b в этом случае будет инициализирована динамически, или даже умный компаноновщик сможет отследить порядок статической инициализации и все будет OK.
0
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,285
11.08.2014, 23:44 29
Цитата Сообщение от gng Посмотреть сообщение
писать в глобальной секции одного си модуля
То, что в разных модулях порядок инициализации не определен было сказано еще в начале темы. Он, как я понял, спрашивает про один модуль.
0
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
11.08.2014, 23:46 30
PS. В рамках одного модуля, конечно, инициализация упорядочена.
0
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,285
12.08.2014, 00:10 31
Цитата Сообщение от gng Посмотреть сообщение
Хотя, возможно, b в этом случае будет инициализирована динамически
Кстати не возможно, а точно так.
3.6.2/2
Together, zero-initialization and constant initialization are called static initialization;
В то время как constant initialization это:
— if each full-expression (including implicit conversions) that appears in the initializer of a reference with
static or thread storage duration is a constant expression (5.19) and the reference is bound to an lvalue
designating an object with static storage duration or to a temporary (see 12.2);
— if an object with static or thread storage duration is initialized by a constructor call, if the constructor is
a constexpr constructor, if all constructor arguments are constant expressions (including conversions),
and if, after function invocation substitution (7.1.5), every constructor call and full-expression in
the mem-initializers and in the brace-or-equal-initializer s for non-static data members is a constant
expression;
— if an object with static or thread storage duration is not initialized by a constructor call and if every
full-expression that appears in its initializer is a constant expression.
Так, что то, что не решился бы - это правильно. Глобальные переменные вообще нужно минимизировать (а то и полностью искоренять). Но тем не менее код был бы корректный.

Добавлено через 6 минут
Это плохо еще и тем, что в один прекрасный момент кто-нибудь заменит 5 на вызов функции и получим UB.
0
383 / 281 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
12.08.2014, 01:12  [ТС] 32
DrOffset, gng, что-то краски все сгущаются и сгущаются
Правильно ли я понял:
Статическая инициализация - это когда объект инициализируется на этапе компиляции. Сюда можно отнести встроенные типы, POD типы, и классы с constexpr конструкторами.
Динамическая инициализация - это когда объект инициализируется и обретает константность во время выполнения. Сюда относим все нетривиальные классы.
Вот эта фраза:
Цитата Сообщение от gng Посмотреть сообщение
При инициализации obj можно использовать ival независимо от того, в каких модулях они описаны.
То есть, нетривиальный объект obj можно инициализировать, используя ival, независимо в каких модулях трансляции они находятся?
0
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,285
12.08.2014, 01:33 33
Цитата Сообщение от gromo Посмотреть сообщение
Сюда можно отнести встроенные типы, POD типы, и классы с constexpr конструкторами.
Константные выражения или constexpr. POD или не POD напрямую не имеет значения.
Цитата Сообщение от gromo Посмотреть сообщение
Динамическая инициализация - это когда объект инициализируется и обретает константность во время выполнения
Константность самого объекта, опять же, необязательна.
Цитата Сообщение от gromo Посмотреть сообщение
То есть, нетривиальный объект obj можно инициализировать, используя ival, независимо в каких модулях трансляции они находятся?
Можно. Это вытекает из того, что вся статическая инициализация прошита в бинарник и когда модуль загружается в оперативку еще до передачи управления в точку входа у нас уже есть все валидные данные и адреса для таких объектов.

Добавлено через 8 минут
Завязываться правда на такое опасно. Мало ли кто поменяет инициализацию со статической на динамическую и получим UB.
1
383 / 281 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
12.08.2014, 01:45  [ТС] 34
Цитата Сообщение от DrOffset Посмотреть сообщение
Константность самого объекта, опять же, необязательна.
Насчет константности сглупил, ведь тема создавалась для выяснения вопросов с константами, а теперь разраслась.
0
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,285
12.08.2014, 01:47 35
Цитата Сообщение от gromo Посмотреть сообщение
Насчет константности сглупил, ведь тема создавалась для выяснения вопросов с константами, а теперь разраслась.
Да я сам на это же налетел на второй странице.
Со всеми бывает, ничего страшного.
0
Заблокирован
12.08.2014, 16:06 36
Цитата Сообщение от gromo Посмотреть сообщение
Многие авторы смешивают статические глобальные объекты и просто глобальные объекты, называя их "static global objects" из-за того, что у обоих статическое расположение в памяти.
вы и понятия не имеете, что есть что.
Глобальные объекты могут иметь внешнюю компоновку и всегда инициализированы, в то время как все статические, - только внутреннюю, именно поэтому сделай глобальный объект статическим и он гарантированно будет иметь внутреннюю компоновку.

Удачи в незнании.
0
383 / 281 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
12.08.2014, 16:30  [ТС] 37
Цитата Сообщение от Trwsdf Посмотреть сообщение
Глобальные объекты могут иметь внешнюю компоновку и всегда инициализированы
Прям таки всегда инициализированы?
Цитата Сообщение от Trwsdf Посмотреть сообщение
сделай глобальный объект статическим и он гарантированно будет иметь внутреннюю компоновку.
И что мне делать с этой внутренней компоновкой? Мне надо чтобы константные объекты были доступны по всей программе. И не имеет смысла для этого делать локальный статический объект внутри функции, чтобы гарантированно получить его инициализированным.

Не по теме:

Цитата Сообщение от Trwsdf Посмотреть сообщение
Но я консультаций за спасибо не оказываю.
А никто и не просил вроде бы

0
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,285
12.08.2014, 20:23 38
Цитата Сообщение от Trwsdf Посмотреть сообщение
Глобальные объекты могут иметь внешнюю компоновку и всегда инициализированы, в то время как все статические, - только внутреннюю, именно поэтому сделай глобальный объект статическим и он гарантированно будет иметь внутреннюю компоновку.
Тут речь идет не про статические объекты с ключом static. А про статическое размещение, оно же static storage duration. А про компоновку тут вообще речи не шло, изначально. Вопрос был совсем о другом.
0
Заблокирован
12.08.2014, 20:59 39
Цитата Сообщение от DrOffset Посмотреть сообщение
Тут речь идет не про статические объекты с ключом static. А про статическое размещение, оно же static storage duration. А про компоновку тут вообще речи не шло, изначально. Вопрос был совсем о другом.
ок, мне было очень интересно
0
12.08.2014, 20:59
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.08.2014, 20:59
Помогаю со студенческими работами здесь

формы и обращения к ним
люди как создать 2-ю форму ну хочу чтоб у мя в проге было больше 1-го окна и как к ней над будь...

Код создания N-го колва checkBox'ов и обращения к ним
Необходимо добавить на форму N-ое количество элементов checkBox. После изменения состояния этих...

Глобальные объекты в разных единицах трансляции
Порядок создания глобальных объектов в разных единицах трансляции не определен. Рассмотрим...


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

Или воспользуйтесь поиском по форуму:
39
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru