Перейти к содержанию
    

Плавный переход C -> C++ под МК

2 часа назад, Arlleex сказал:

Глобальный массив, например, int buf[100]; будет обнулен перед входом в main().

Глобальный - будет. Член класса не является глобальным и поэтому не будет. Я-то думал - вы в листинг смотрели и там увидели зануление массива...

По стандарту для члена-массива вызываются конструкторы по-умолчанию каждого члена. Конструктор по-усолчанию для POD-типов не делает ничего, поэтому и член-массив uintXX_t инициализироваться не должен.

1 час назад, one_eight_seven сказал:

aligned_storage - это класс, динамический объект, создаётся с помощью new

Чё???

1 час назад, one_eight_seven сказал:

В стандарте дан тривильный пример реализации (https://en.cppreference.com/w/cpp/types/aligned_storage), в нём неинициализированность обеспечивается тем, что место для буфера выделяется на куче.

Покажите пальцем, где там место на куче выделяется?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 минуты назад, Сергей Борщ сказал:

Глобальный - будет. Член класса не является глобальным и поэтому не будет.

Ну так объект класса ведь я создаю глобальным. Соответственно, внутренний массив объекта обнулится.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 minutes ago, Сергей Борщ said:

Член класса не является глобальным и поэтому не будет.

Отдельно не будет, а будет обнулено все содержимое класса, разом: memset(*class, 0, sizeof(class)). Сталкивался. Наступал на эти "грабли" (

Обход как выше прозвучал - через указатель на сами данные, которые инициализируем ручками и не даем обнулять через скрипты линкера и соотв. прагмы. Да костыль, но это точно работает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

18 минут назад, Сергей Борщ сказал:

Конструктор по-усолчанию для POD-типов не делает ничего, поэтому и член-массив uintXX_t инициализироваться не должен.

Инициализация нулями имеет следующее примечание

Цитата

Notes
As described in non-local initialization, static and thread-local (since C++11) variables that aren't constant-initialized are zero-initialized before any other initialization takes place. If the definition of a non-class non-local variable has no initializer, then default initialization does nothing, leaving the result of the earlier zero-initialization unmodified.A zero-initialized pointer is the null pointer value of its type, even if the value of the null pointer is not integral zero.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 минуты назад, Arlleex сказал:

Ну так объект класса ведь я создаю глобальным. Соответственно

Нет. Не соответственно.Если ваш класс не является POD-типом - будет вызван его конструктор, а из него - конструкторы членов. Если же класс является POD-типом - то глобальный объект такого типа будет помещен в секцию .bss и обнулен вместе со всеми остальными переменными глобальным циклом обнуления секции .bss

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 минуты назад, Сергей Борщ сказал:

Нет. Не соответственно. Если ваш класс не является POD-типом - будет вызван его конструктор, а из него - конструкторы членов.

У меня есть класс. В нем массив. А еще конструктор с параметром. И еще мало-много чего.
Я объявляю объект этого класса в глобальной области видимости и вывожу в watch отладчика содержимое массива.
Захожу в main(), останавливаюсь. Записываю в массив что угодно (отладчиком). Сбрасываю МК, захожу снова в main() - массив обнулен.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

18 минут назад, Arlleex сказал:

Т.е. любые инициализации (и их наличие и отсутствие) осуществляется несколько позже зануления.

Хм. не задумывался над этим. Пожалуй, вы правы. То есть все глобальные объекты, если явно не указано иное, помещаются либо в .data, либо в .bss. В .data сразу копируется "образ" начальных значений. .bss обнуляется и потом вызываются конструкторы расположенных в ней объектов (если таковые есть). То есть изначально вы хотите сократить время зануления .bss уменьшив ее размер (или не вы, но кто-то тут такое писал). Следовательно, единственный способ - создать свою секцию вне .bss и явно поместив ваш глобальный объект в нее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 минуты назад, Сергей Борщ сказал:

Следовательно, единственный способ - создать свою секцию вне .bss и явно поместив ваш глобальный объект в нее.

Угу. По сути - весь объект, вместо желаемого одного массива. В целом, страшного мало, можно и так. Просто я думал, что мало ли есть способ указания компилятору "отмены" вообще любых инициализаций к отдельно взятым членам какого-либо класса. Вот у локальных объектов класса удобно - все что нужно делается в конструкторе - если тот отсутствует, то и инициализаций не будет, если кратко.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

16 минут назад, Arlleex сказал:

Угу. По сути - весь объект, вместо желаемого одного массива.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Понял, спасибо.

Пока читал cppreference, наткнулся на интересный момент со статическими локальными переменными

Цитата

Static local variables
Variables declared at block scope with the specifier static or thread_local (since C++11) have static or thread (since C++11) storage duration but are initialized the first time control passes through their declaration (unless their initialization is zero- or constant-initialization, which can be performed before the block is first entered). On all further calls, the declaration is skipped.

Эмм... А это еще как такое возможно? Т.е. где-то должна быть переменная состояния, по которой будет оцениваться "факт инициализированности", и динамически все время проверяться?:shok:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 минуты назад, Arlleex сказал:

Т.е. где-то должна быть переменная состояния, по которой будет оцениваться "факт инициализированности", и динамически все время проверяться?

Да. Поэтому я их и не люблю - переменная реально делает работу один раз, а проверяется при каждом доступе.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Только что, Сергей Борщ сказал:

Да. Поэтому я их и не люблю - переменная реально делает работу один раз, а проверяется при каждом доступе.

Кошмар какой, хоспаде:shok: Правда, в Си инициализация не константой, вроде, вовсе запрещена.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, Сергей Борщ said:

Чё???

Вот, бл... ЧЁ!

image.thumb.png.9ebd920e0969d45c57bc178dd0ce7b29.png

Прямо в стандарте же описано. Даже ссылку ведь дал. Но читать нынче умеют, видимо, не только лишь все.

1 hour ago, Сергей Борщ said:

Покажите пальцем, где там место на куче выделяется?

Вот здесь:

image.thumb.png.34a0b80890e0abec215b2c73ff4a0502.png

 

А иначе оно будет помещено либо в .bss, либо в .data и будет инициализировано. Но, думаю, вы уже из ответов других товарищей это прочитали.

Изменено пользователем one_eight_seven

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

34 минуты назад, one_eight_seven сказал:

Даже ссылку ведь дал. Но читать нынче умеют, видимо, не только лишь все.

Помнится, лет 20 назад The Bat! отсылал примерно такое уведомление о получени письма: "это уведомление не означает, что письмо было прочитано и/или понято адресатом". Последнее, вероятно, относится к вам.

 

34 минуты назад, one_eight_seven сказал:

Вот здесь:

Какое отношение placement new имеет к куче? Это во-первых. Во-вторых - эта фраза об объектах, создаваемых в этой выровненной памяти, но не к самому объекту памяти. Что и подтверждает пример по той же ссылке: объект data[N] типа std::aligned_storage_t<sizeof(T), alignof(T)> является самым обычным членом класса, а не создается на куче, как написали вы. Понимать прочитанное умеют не только лишь все, да.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что-то не соображу. Есть класс, упрятанный в namespace

// .hpp
namespace NS {
  class MyClass {
    friend void func();
    
    void init();
  };
}

// .cpp
using namespace NS;

void MyClass::init() {
  ...
}


Как мне теперь определить функцию func(), дружественную классу MyClass? Так

// .cpp
...
void func() {
  init(); // не видит init() (undefined symbol ...)
}

не работает:nea:

P.S. Вообще идея была в том, чтобы только в .cpp определить static inline функцию, которая имела бы контекст объекта (this), т.е. была дружественной функцией класса, но при этом не светилась в определении самого класса (ведь эта функция используется только внутри файла реализации класса, к тому же хотелось бы ее встроить и не генерировать глобального имени для линкера).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...