Re[8]: Zero initialization
От: rg45 СССР  
Дата: 08.09.21 13:05
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Класс станет не POD, но std::string -то нормально инициализируется. Т.е. всё зависит от самим членов структуры, так что, я считаю, это нормальное поведение.


Я про другое — non-POD класс по-разному инициализируется при default и при value инициализации. Такое возможно только если конструктор сгенерирован компилятором. Если дефолтный конструктор определен программистом, то оба вида инициализации будут работать строго одинаково — через конструктор, предоставленный программистом. То есть, не может программист определить дефолтный конструктор, равнозначный тому, который может сгенерировать компилятор.
--
Отредактировано 08.09.2021 13:33 rg45 . Предыдущая версия .
Re[5]: Zero initialization
От: Videoman Россия https://hts.tv/
Дата: 08.09.21 13:57
Оценка:
Здравствуйте, imh0, Вы писали:

I>По теме вопроса — посмотрите, это действительно важно — будет ли у вас работать такое...


I>map<int,{ваш тип}> mmm;


I>mmm[234]++;


I>При условии, что по умолчанию, предположим, в вашем типе, поумолчанию ноль.


Будет работать, почему нет ?! Если такого ключа нет, то он проинициализируется конструктором по умолчанию, также как простой int.
http://www.gravatar.com/avatar/60560936caa07b944d4c3cecf1c06cc5?s=80&d=identicon
Re[9]: Zero initialization
От: Videoman Россия https://hts.tv/
Дата: 08.09.21 14:17
Оценка:
Здравствуйте, rg45, Вы писали:

Что тебя смущает в этом выхлопе:

g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
{ 706447552, 6.94257e-310, 0x7fcd2a1b8f20, '' }
{ 0, 0, 0, '' }
{ 0, 0, 0, '' }

???
Что POD мемберы инициализируются как все POD, а не-POD как нормальные классы? По-моему это логично, так и должно быть.
http://www.gravatar.com/avatar/60560936caa07b944d4c3cecf1c06cc5?s=80&d=identicon
Re[10]: Zero initialization
От: rg45 СССР  
Дата: 08.09.21 14:33
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Что тебя смущает в этом выхлопе:

V>g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
V>{ 706447552, 6.94257e-310, 0x7fcd2a1b8f20, '' }
V>{ 0, 0, 0, '' }
V>{ 0, 0, 0, '' }

V>???
V>Что POD мемберы инициализируются как все POD, а не-POD как нормальные классы? По-моему это логично, так и должно быть.

Меня смущает, что я, как разработчик, не могу предоставить собственную реализацию дефолтного конструктора, обладающего таким же поведением, как у конструктора, сгенерированного компилятором.
--
Re[11]: Zero initialization
От: Videoman Россия https://hts.tv/
Дата: 08.09.21 14:39
Оценка:
Здравствуйте, rg45, Вы писали:

R>Меня смущает, что я, как разработчик, не могу предоставить собственную реализацию дефолтного конструктора, обладающего таким же поведением, как у конструктора, сгенерированного компилятором.


Опиши какую проблему ты рассматриваешь и когда это может понадобиться?
http://www.gravatar.com/avatar/60560936caa07b944d4c3cecf1c06cc5?s=80&d=identicon
Re[12]: Zero initialization
От: rg45 СССР  
Дата: 08.09.21 14:57
Оценка:
Здравствуйте, Videoman, Вы писали:

R>>Меня смущает, что я, как разработчик, не могу предоставить собственную реализацию дефолтного конструктора, обладающего таким же поведением, как у конструктора, сгенерированного компилятором.


V>Опиши какую проблему ты рассматриваешь и когда это может понадобиться?



Вот прямо реальную задачу придумать сходу затрудняюсь. Но допустим, по каким-то причинам конструктор, сгенерированный компилятором (объявленный как "= default"), не подходит и хочется дать собственное полное определение (со списком инициализации и с телом). В этом случае мы тут же возвращаемся к той проблеме, которая заставила тебя создать эту тему. Конечно, тут самое время вспомнить о существовании default member initializers, которые позволяют разрулить самые сложные потребности при инициализации. Тем не менее, лично у меня как-то вот нет уверенности, что таким образом можно разрулить 100% всех проблем и обойтись без конструктора, определенного пользователем.
--
Отредактировано 08.09.2021 16:11 rg45 . Предыдущая версия .
Re[12]: Zero initialization
От: rg45 СССР  
Дата: 08.09.21 16:19
Оценка:
Здравствуйте, Videoman, Вы писали:

R>>Меня смущает, что я, как разработчик, не могу предоставить собственную реализацию дефолтного конструктора, обладающего таким же поведением, как у конструктора, сгенерированного компилятором.


V>Опиши какую проблему ты рассматриваешь и когда это может понадобиться?


Я вот тут подумал хорошенько и пришел к выводу, что все, что я писал постом выше — от лукавого. Формально: сгенерированный компилятором дефолтный конструктор порождает различное поведение для default и для value инициализаций. Я хотел похожего поведения и для дефолтных конструкторов, определенных пользователем. То есть, по сути, возможности написать разные конструкторы для этих двух видов инициализации. При этом придумать какую-нибудь прикладную задачу, при решении которой эта фича могла бы оказаться полезной я так и не смог. Зато представил, сколько новых вопросов может поднять появление нового вида конструктора. Пришел к выводу, что незачем усложнять язык без видимых на то причин.
--
Re[13]: Zero initialization
От: Videoman Россия https://hts.tv/
Дата: 08.09.21 18:12
Оценка: +1
Здравствуйте, rg45, Вы писали:

R>Я вот тут подумал хорошенько и пришел к выводу, что все, что я писал постом выше — от лукавого. Формально: сгенерированный компилятором дефолтный конструктор порождает различное поведение для default и для value инициализаций. Я хотел похожего поведения и для дефолтных конструкторов, определенных пользователем. То есть, по сути, возможности написать разные конструкторы для этих двух видов инициализации. При этом придумать какую-нибудь прикладную задачу, при решении которой эта фича могла бы оказаться полезной я так и не смог. Зато представил, сколько новых вопросов может поднять появление нового вида конструктора. Пришел к выводу, что незачем усложнять язык без видимых на то причин.


Я как раз с этого начал и, в итоге, ты мне напомнил нормальное решение, так что для меня было сюрпризом что обсуждение пошло на второй круг .
http://www.gravatar.com/avatar/60560936caa07b944d4c3cecf1c06cc5?s=80&d=identicon
Re[5]: Zero initialization
От: Максим Россия  
Дата: 29.10.21 20:32
Оценка: 32 (5)
R>А тебе принципиально, чтобы этот конструктор был определен тобой? Автоматически сгенерированный компилятором дефолтный конструктор не подойдет тебе? В этом случае ты можешь иметь в классе набор каких-то кастомных конструторов, но при этом класс сохранит поведение при инициализации подобное POD-ам:

Тут, кстати, узнал, что С++ еще по разному трактует место в котором конструктор объявлен как default

#include <iostream>

struct foo {
    foo() = default;
    int a;
};

struct bar {
    bar();
    int b;
};

bar::bar() = default;

int main() {
    foo a{};
    bar b{};
    std::cout << a.a << ' ' << b.b;
}

https://stackoverflow.com/questions/54350114/c-zero-initialization-why-is-b-in-this-program-uninitialized-but-a-is-i

Конструктор bar в этом примере, с точки зрения компилятора, уже user-defined и соответсвенно приходит ub и произвольное значение для b.b.
Errare humanum est
Отредактировано 29.10.2021 20:33 Максим . Предыдущая версия .
Re[6]: Zero initialization
От: Videoman Россия https://hts.tv/
Дата: 29.10.21 21:40
Оценка:
Здравствуйте, Максим, Вы писали:

М>Конструктор bar в этом примере, с точки зрения компилятора, уже user-defined и соответсвенно приходит ub и произвольное значение для b.b.


Класс! А что тогда теперь делать если bar содержит какой-нибудь incomplete type в качестве члена, типа:
// .h file
// forward declaration 
class incomplete;
// ...
struct bar
{
bar();

// ...
std::uniqe_ptr<incomplete> m_i;
// ...
};

// .cpp file
bar::bar() = default;

и default конструктор нужно реализовать позже, где-нибудь в cpp файле ?
http://www.gravatar.com/avatar/60560936caa07b944d4c3cecf1c06cc5?s=80&d=identicon
Отредактировано 29.10.2021 21:41 Videoman . Предыдущая версия .
Re[7]: Zero initialization
От: Максим Россия  
Дата: 30.10.21 06:03
Оценка:
V>Класс! А что тогда теперь делать если bar содержит какой-нибудь incomplete type в качестве члена.
V>и default конструктор нужно реализовать позже, где-нибудь в cpp файле ?

Да, могут возникнуть проблемы. Я на что-то подобное наткнулся как раз при играх с pimpl паттерном. С++ не дает расслабиться

П.С.
Забыл сказать. Clang на маке с опциями -Wall — Wextra не выдавал предупреждения на то, что переменная не инициализирована, потом проверил с gcc, тут предупреждение было. Такие вещи добавляют еще красок в отладку.

https://i.imgur.com/3wlxtI0.gifv
Errare humanum est
Отредактировано 30.10.2021 7:43 Максим . Предыдущая версия . Еще …
Отредактировано 30.10.2021 7:43 Максим . Предыдущая версия .
Отредактировано 30.10.2021 7:43 Максим . Предыдущая версия .
Re[5]: Zero initialization
От: _NN_ www.nemerleweb.com
Дата: 30.10.21 20:14
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Здравствуйте, flаt, Вы писали:


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


V>Жаль. В принципе я готов к такой реальности. Вопрос на самом деле возник лишь из-за удобства и надежности написания шаблонного кода. Просто не зная какой конкретно тип передается мне придется писать:
V>type_t a;    // Если я не хочу "занулять" экземпляр и,
V>type_t a(0); // Если я хочу "занулить" экземпляр. Что накладывает определенные ограничения на типы, чего хотелось бы избежать.


А какие ограничения накладываются ?

https://gcc.godbolt.org/z/ed5j4ncWq

#include <string>
#include <vector>

struct B {
    std::vector<std::string> v;
    double d;
};

struct A {
    std::string s;
    B b;
    int i;
};


template <typename T>
constexpr int default_init()
{
    T t;
    return t.i;
}

template <typename T>
constexpr int null_init()
{
    T t{};
    return t.i;
}

int main() {
    return null_init<A>();
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: Zero initialization
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 31.10.21 20:41
Оценка:
Здравствуйте, Videoman, Вы писали:


V>Жаль. В принципе я готов к такой реальности. Вопрос на самом деле возник лишь из-за удобства и надежности написания шаблонного кода. Просто не зная какой конкретно тип передается мне придется писать:[ccode]

V>Весь сыр-бор разгорелся из-за кода в шаблонной библиотеке, где я по привычке вызываю type_t() для инициализации. Потом оказалось что в моем собственном классе T, который по сути тоже POD, конструктор по умолчанию, с инициализацией нулями, жрал слишком много CPU и инициализацию пришлось убрать. После этого шаблонный код type_t() стал работать то инициализируя, то нет, в зависимости от переданного типа. Пока всё это лишь вопрос удобства и надежности кода.

А нельзя определить POD или не POD, и делать по-разному?
Маньяк Робокряк колесит по городу
Re[6]: Zero initialization
От: Videoman Россия https://hts.tv/
Дата: 01.11.21 20:09
Оценка:
Здравствуйте, Marty, Вы писали:

M>А нельзя определить POD или не POD, и делать по-разному?


Можно конечно "магию" применить, но во-первых — зачем такие сложности на ровном месте, а во-вторых — я не уверен что в будущем это не выльется в ещё какие-нибудь проблемы. Всегда думал что чем проще, тем лучше.
http://www.gravatar.com/avatar/60560936caa07b944d4c3cecf1c06cc5?s=80&d=identicon
Re[7]: Zero initialization
От: B0FEE664  
Дата: 02.11.21 10:06
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Класс! А что тогда теперь делать если bar содержит какой-нибудь incomplete type в качестве члена, типа:

V>
V>// .h file
V>// forward declaration 
V>class incomplete;
V>// ...
V>struct bar
V>{
V>bar();

V>// ...
V>std::uniqe_ptr<incomplete> m_i;
V>// ...
V>};

V>// .cpp file
V>bar::bar() = default;
V>

V>и default конструктор нужно реализовать позже, где-нибудь в cpp файле ?

Насколько я понял, конструктор для bar.m_i всё равно вызывается, так что тут ничего страшного, а поля типа int можно инициализировать прямо при объявлении:
#include <iostream>

struct foo {
    foo() = default;
    int a;
};

struct bar {
    bar();
    int b = 0;
};

bar::bar() = default;

int main() {
    foo a{};
    bar b{};
    std::cout << a.a << ' ' << b.b;
}
И каждый день — без права на ошибку...
Re[7]: Zero initialization
От: rg45 СССР  
Дата: 11.11.21 18:09
Оценка:
Здравствуйте, Videoman, Вы писали:

М>>Конструктор bar в этом примере, с точки зрения компилятора, уже user-defined и соответсвенно приходит ub и произвольное значение для b.b.


V>Класс!


Что-то не соображу, какую практическую пользу можно извлечь из этой возможности.
--
Re[6]: Zero initialization
От: rg45 СССР  
Дата: 11.11.21 18:14
Оценка:
Здравствуйте, Максим, Вы писали:

М>

М>struct bar {
М>    bar();
М>    int b;
М>};

М>bar::bar() = default;
М>


Интересно, такое определение конструктора чем-то отличается от традиционного:

bar::bar(){}

?

По-моему, они дают один и тот же эффект: все подобъекты non-POD типов будут проинициализированы их дефолтными конструкторами, а все POD-ы останутся без инициализации — в обоих вариантах. И zero-initialization в обоих вариантах оказывается недоступной.
--
Отредактировано 11.11.2021 18:22 rg45 . Предыдущая версия . Еще …
Отредактировано 11.11.2021 18:18 rg45 . Предыдущая версия .
Re[8]: Zero initialization
От: AndrewJD США  
Дата: 11.11.21 20:58
Оценка:
Здравствуйте, rg45, Вы писали:

R>Что-то не соображу, какую практическую пользу можно извлечь из этой возможности.

Для конструктора, наверное, пользы никакой, но для деструктора может быть удобно подчеркивает намерения автора кода.
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Re[7]: Zero initialization
От: Videoman Россия https://hts.tv/
Дата: 11.11.21 22:39
Оценка:
Здравствуйте, rg45, Вы писали:

R>По-моему, они дают один и тот же эффект: все подобъекты non-POD типов будут проинициализированы их дефолтными конструкторами, а все POD-ы останутся без инициализации — в обоих вариантах. И zero-initialization в обоих вариантах оказывается недоступной.


Да нет же. Если написать:
// в .h или .cpp - не важно где
bar::bar(){}; 
// или в .cpp
bar::bar() = default;
то:
bar b; // POD члены не будут инициализированы, т.е. как и у любого стандартного POD типа
auto b = bar(); // POD члены также не будут инициализированы, что неожиданно в случае default


Если же написать:
// именно в .h
bar::bar() = default;
то:
bar b; // POD члены не будут инициализированы
auto b = bar(); // POD члены станут нулями, как и ожидаешь от любого конструктора по умолчанию
http://www.gravatar.com/avatar/60560936caa07b944d4c3cecf1c06cc5?s=80&d=identicon
Отредактировано 11.11.2021 22:41 Videoman . Предыдущая версия . Еще …
Отредактировано 11.11.2021 22:40 Videoman . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.