Re[3]: Инициализация
От: Vzhyk  
Дата: 20.12.13 10:21
Оценка: +5 :)
12/20/2013 12:24 PM, skeptic пишет:

> Как то слишком уж радикально ты...

Просто надоело быть толерантным здесь. Как не почитаешь идеи по С++
здесь, так за голову хватаешься, страшно становится.
Причем 90% обсуждений в 2 стилях, а как мне забомбить вот такую странную
нетривиальную фигню в коде (шоб никто не догадался) и ой, а чей-то у
меня память течет, нет ли доктора-телепата.
Posted via RSDN NNTP Server 2.1 beta
Re: Инициализация
От: Кодт Россия  
Дата: 20.12.13 10:36
Оценка: 6 (2) +2 -1
Здравствуйте, Alexander G, Вы писали:

AG>Ну вот какого хрена в век, когда лямбды уже не вызывают "это ты выпендрился?"-реакцию на код ревью, когда все самые необходимые смарт-поинтеры уже есть в std, а в boost есть вообще все нужные, до сих пор можно наткнуться на непредсказуемую инициализацию переменных?


Потому что функция в случае неудачи может
— не инициализировать
— инициализировать удобным дефолтным или сигнальным значением (0)
— инициализировать неудобным сигнальным значением (-1 или 0xFFFFFFFF, или 0xDEADFACE какое-нибудь)
— инициализировать случайным мусором

Выход из этого — протаскивание в API самонесущих типов — boost::optional, например. Только это очень недружественно для FFI.

AG>Почему не введут инициализацию для всех простых типов?

AG>Для маньяков, которые не желают "платить за то, что не используют", можно же ввести синтаксис для "старой доброй русской рулетки".

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

AG>Может, это можно протянуть как пропозл?


Идея прикольная, но может оказаться достаточно дорогой.
Лучше уж ввести какую-нибудь прагму #pragma zeroinit, которая форсировала бы инициализацию всех переменных подряд.
Перекуём баги на фичи!
Re: Инициализация
От: B0FEE664  
Дата: 20.12.13 10:17
Оценка: 6 (1) +2 -1
Здравствуйте, Alexander G, Вы писали:

AG>Ну вот какого хрена в век, когда лямбды уже не вызывают "это ты выпендрился?"-реакцию на код ревью, когда все самые необходимые смарт-поинтеры уже есть в std, а в boost есть вообще все нужные, до сих пор можно наткнуться на непредсказуемую инициализацию переменных?

Потому, что массивы бывают длинны.

AG>
AG>int count;
AG>RegQueryValue(count); // забыли проверить возвращаемое значение
AG>for (int i = 0 ; i < count ; i++) // и приплыли - цикл повторяется непредсказуемое количество раз
AG>

А что собственно вы тут собрались проверять?

AG>Почему не введут инициализацию для всех простых типов?

А зачем она нужна? Если вы про приведённый пример, то хочется спросить, почему он не записан так:
  const int count = RegQueryValue();
  for (int i = 0 ; i < count ; i++)


AG>Для маньяков, которые не желают "платить за то, что не используют", можно же ввести синтаксис для "старой доброй русской рулетки".

Обратная совместимость важнее удобства.

AG>Может, это можно протянуть как пропозл?

Я против.
И каждый день — без права на ошибку...
Re[5]: Инициализация
От: Tilir Россия http://tilir.livejournal.com
Дата: 25.12.13 08:06
Оценка: 1 (1) +2 :)
Здравствуйте, Alexander G, Вы писали:

AG>Нет, я хочу, чтобы просто


Скажите, а вот:

struct megabyte_t {
  char i[1048576];
};

int
foo(void)
{
  struct megabyte_t x;
  ... /* lot of code here */
}


Вы как хотите чтобы компилилось?

То есть вы реально готовы пойти на скрытый оверхед в инициализации мегабайтной переменной на стеке нулями просто вот так на пустом месте? Я полагаю, ваше скромное предложение, формально обратно совместимое, реально поломает обратную совместимость в том смысле, что весь код написанный в old-style все равно придется переписывать на =undefined из-за немыслимых просадок по перфомансу в легаси.

Но это ещё ладно. А теперь представьте у вас хитрый и стрёмный volatile вот такого вида:

extern volatile int port_b; // это не переменная, это порт ввода-вывода
                            // чтение -- состояние боевого лазера
                            // запись команды: port_b = 1; -- уничтожение флота пришельцев
                            //                 port_b = 2; -- самоуничтожение
                            //                 port_b = 0; -- уничтожение планеты Земля


Вы точно хотите дефолтно инициализировать её нулём? Не предупреждая разработчиков?
Инициализация
От: Alexander G Украина  
Дата: 20.12.13 09:11
Оценка: +2 -2
Ну вот какого хрена в век, когда лямбды уже не вызывают "это ты выпендрился?"-реакцию на код ревью, когда все самые необходимые смарт-поинтеры уже есть в std, а в boost есть вообще все нужные, до сих пор можно наткнуться на непредсказуемую инициализацию переменных?

int count;
RegQueryValue(count); // забыли проверить возвращаемое значение
for (int i = 0 ; i < count ; i++) // и приплыли - цикл повторяется непредсказуемое количество раз



Почему не введут инициализацию для всех простых типов?

Для маньяков, которые не желают "платить за то, что не используют", можно же ввести синтаксис для "старой доброй русской рулетки".
Варианты, как это можно сделать:

int i = uninitialized;  // "uninitialized" - не спец. значение, а magic, работающий только в инициализаторах, означающий, что мы хотим адреналина

int i = void;  // мы даже можем не вводить новый кейворд, если это так важно

[[uninitialized]]
int i; // придумали аттрибуты, значит почему бы не использовать


Может, это можно протянуть как пропозл?
Русский военный корабль идёт ко дну!
Re: Инициализация
От: Vzhyk  
Дата: 20.12.13 09:22
Оценка: +4
12/20/2013 12:11 PM, Alexander G пишет:

> Почему не введут инициализацию для всех простых типов?

Потому что тупую голову и кривые руки инструментом не поправишь.
Posted via RSDN NNTP Server 2.1 beta
Re: Инициализация
От: мыщъх США http://nezumi-lab.org
Дата: 21.12.13 05:27
Оценка: 12 (1) :)
Здравствуйте, Alexander G, Вы писали:

AG>Почему не введут инициализацию для всех простых типов?

предвижу такую проблему -- после того как это введут в стандарт и выйдут компиляторы это поддерживающие, народ перестанет иницилизировать переменные, а старые компиляторы останутся и начнется реальная непредсказуемость.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re: Инициализация
От: visual_wind  
Дата: 20.12.13 11:03
Оценка: 9 (2)
Здравствуйте, Alexander G, Вы писали:

AG>
AG>int count;
AG>RegQueryValue(&count); // забыли проверить возвращаемое значение
AG>for (int i = 0 ; i < count ; i++) // и приплыли - цикл повторяется непредсказуемое количество раз
AG>

Вероятно, вы имели ввиду выделенное.

AG>Почему не введут инициализацию для всех простых типов?

AG>Для маньяков, которые не желают "платить за то, что не используют", можно же ввести синтаксис для "старой доброй русской рулетки".
AG>Варианты, как это можно сделать:
AG>
AG>int i = uninitialized;  // "uninitialized" - не спец. значение, а magic, работающий только в инициализаторах, означающий, что мы хотим адреналина
AG>int i = void;  // мы даже можем не вводить новый кейворд, если это так важно
AG>

Вы добавляете головной боли эмбеддед разработчикам. Не совсем понятно, что компилятор должен вставлять для случаев, связанных с регистрами железки, рассчитанными только на чтение, которые как-то мапятся на переменные. Или, например, для переменных из пространства ввода-вывода для процессоров с гарвардской архитектурой.

AG>
AG>[[uninitialized]]
AG>int i; // придумали аттрибуты, значит почему бы не использовать
AG>

То, что вы хотите, уже есть в эмбеддед, где существуют секции (сегменты), которые в известной степени позволяют прописывать правила размещения и инициализации переменных. Используются в сочетании с #pragma. И да, бывают случаи, когда глобальные переменные умышленно не инициализируются. Для того, например, чтобы информация была доступна после ресета процессора. В любом случае, момент инициализации досточно специфичен для каждого процессора и компилятора, чтобы быть легко стандартизированным.
Re[2]: Инициализация
От: Alexander G Украина  
Дата: 20.12.13 11:11
Оценка: +1 :)
Здравствуйте, Abyx, Вы писали:

A>комлятор и так проинициализровал тебе переменную значением 0xCDCDCDCD (в дебажной конфигурации).


Вот и сработало в дебажной конфигурации, 0xCDCDCDCD — отрицательное значение, в цикл не вошел.
И пришлось дебажить релизную, чтобы поймать баг.

С этим 0xCDCDCDCD ещё как-то было, когда в релиз попал туда 0, и произошло деление на 0, которого в дебаге никогда не было.

Так что 0xCDCDCDCD был бы хорош, если бы во всех конфигурациях, а так он даже иногда мешает.

A>а вообще говнокод писать не надо, и всё будет хорошо.


Да. Но почему бы компилятору не помочь в написании неговнокода.
Русский военный корабль идёт ко дну!
Re[12]: Инициализация
От: Alexander G Украина  
Дата: 20.12.13 17:53
Оценка: +1 -1
Здравствуйте, Erop, Вы писали:

E>Для перечислений что будет?..


Да тот же нуль, даже если его нету среди значений перечисления.

Всё равно предсказуемое значение.
Русский военный корабль идёт ко дну!
Re: Инициализация
От: opener  
Дата: 14.01.14 09:14
Оценка: 12 (1)
Здравствуйте, Alexander G, Вы писали:

AG>Ну вот какого хрена в век, когда лямбды уже не вызывают "это ты выпендрился?"-реакцию на код ревью, когда все самые необходимые смарт-поинтеры уже есть в std, а в boost есть вообще все нужные, до сих пор можно наткнуться на непредсказуемую инициализацию переменных?


AG>
AG>int count;
AG>RegQueryValue(count); // забыли проверить возвращаемое значение
AG>for (int i = 0 ; i < count ; i++) // и приплыли - цикл повторяется непредсказуемое количество раз
AG>


Приучи себя к простейшим правилам написания безопасного кода, и подобные проблемы отпадут сами собой.
Re[9]: Инициализация
От: Evgeny.Panasyuk Россия  
Дата: 20.12.13 10:46
Оценка: 1 (1)
Здравствуйте, Alexander G, Вы писали:

S>>Какой предсказуемостью? Как ты узнаешь что 0 это неинициализированная переменная а не кто то присвоил 0?

AG>С реализацией такого предложения будет не важно, присвоил ли кто-то 0, или оно там само.
AG>Предсказуемость в том, что даже если 0 там не есть то, что хотели, ошибочное поведение будет стабильным, а не зависеть от конфигурации, компилятора, ОС, и того, какая функция вызывалась на этом стеке раньше.

Я бы предпочёл нестабильное поведение на ошибочном коде — пусть ошибки дают о себе знать как можно раньше. valgrind или какой-нибудь sanitazer прикрученный к юнит или интеграционным тестам, поймал бы это (+ другие классы ошибок).
А то так и до two's complement int недалеко

Вот даже в твоём коде:
int count;
RegQueryValue(count);
for (int i = 0 ; i < count ; i++) // ладно, был бы ноль - был бы noop
    ;
// А тут-то что делать? RegQueryValue ведь вернул ошибку
Re[2]: Инициализация
От: enji  
Дата: 20.12.13 12:44
Оценка: 1 (1)
Здравствуйте, visual_wind, Вы писали:

_>Вы добавляете головной боли эмбеддед разработчикам. Не совсем понятно, что компилятор должен вставлять для случаев, связанных с регистрами железки, рассчитанными только на чтение, которые как-то мапятся на переменные. Или, например, для переменных из пространства ввода-вывода для процессоров с гарвардской архитектурой.

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

AG>>
AG>>[[uninitialized]]
AG>>int i; // придумали аттрибуты, значит почему бы не использовать
AG>>

_>То, что вы хотите, уже есть в эмбеддед, где существуют секции (сегменты), которые в известной степени позволяют прописывать правила размещения и инициализации переменных. Используются в сочетании с #pragma. И да, бывают случаи, когда глобальные переменные умышленно не инициализируются. Для того, например, чтобы информация была доступна после ресета процессора. В любом случае, момент инициализации досточно специфичен для каждого процессора и компилятора, чтобы быть легко стандартизированным.
Нету этого в эмбедед. Он пишет в частности про стековые переменные, как ты их собрался класть в секции?
Опять же, никто тебе не мешает и под десктопом переменные по секциям раскладывать...
Re[8]: Инициализация
От: Alexander G Украина  
Дата: 20.12.13 10:13
Оценка: +1
Здравствуйте, skeptic, Вы писали:

S>Какой предсказуемостью? Как ты узнаешь что 0 это неинициализированная переменная а не кто то присвоил 0?


С реализацией такого предложения будет не важно, присвоил ли кто-то 0, или оно там само.

Предсказуемость в том, что даже если 0 там не есть то, что хотели, ошибочное поведение будет стабильным, а не зависеть от конфигурации, компилятора, ОС, и того, какая функция вызывалась на этом стеке раньше.
Русский военный корабль идёт ко дну!
Re[3]: Инициализация
От: Figaro Россия  
Дата: 20.12.13 12:35
Оценка: -1
AG> Да. Но почему бы компилятору не помочь в написании неговнокода.

Есть понятие "стандарт"... И есть, до хрена, кода работающего под этим "стандартом"... Обсуждать больше нечего...
avalon/1.0.433
Re: Инициализация
От: TarasB  
Дата: 21.12.13 10:12
Оценка: :)
Здравствуйте, Alexander G, Вы писали:

AG>Ну вот как


AG>Почему не введут инициализацию для всех простых типов?


AG>Для маньяков, которые не желают "платить за то, что не используют", можно же ввести синтаксис для "старой доброй русской рулетки".

AG>Варианты, как это можно сделать:

мне кажется, ближе к С++ будет что-то такое:
auto i = unitialized<int>

ну и заодно, я предлагаю убрать наконец auto и const (сделав их модификаторами по умолчанию), а для того, чтобы избежать путаницы между объявлением новой переменной и заменой старой, ввести слово change. Ну и добавить нормальный кортежи, типа
(i, b) = ShittyFuncWhichReturnsIntAndBool();

Зачем это нужно? Просто именно код, состоящий исключительно из объявлений новых констант, вычисляемых из старых, вызывает у меня наибольшее эстетическое удовольствие.
Re: Инициализация
От: skeptic  
Дата: 20.12.13 09:18
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Почему не введут инициализацию для всех простых типов?


Обратная совместимость + увеличится объём кода.
В силу того что компилятор выдаёт предупреждения по поводу неинициализированных переменных,
никому спец синтаксис для этого не нужен.

AG>Может, это можно протянуть как пропозл?


Можно попробовать, но вряд ли.
Re[2]: Инициализация
От: skeptic  
Дата: 20.12.13 09:24
Оценка:
Здравствуйте, Vzhyk, Вы писали:

V>12/20/2013 12:11 PM, Alexander G пишет:


>> Почему не введут инициализацию для всех простых типов?

V>Потому что тупую голову и кривые руки инструментом не поправишь.

Как то слишком уж радикально ты...
Re[2]: Инициализация
От: Alexander G Украина  
Дата: 20.12.13 09:39
Оценка:
Здравствуйте, skeptic, Вы писали:

S>Обратная совместимость


С чем? Кто-то рассчитывает прочитать определённый мусор?

S> + увеличится объём кода.


Чтобы пофиксить local static variables, сделав их потокобезопасными, на это пошли.

Вообще, в большинстве случаев переменные явно инициализированы в месте объеявления.
Если чуть позже места объявления — можно соптимизировать.
Если вообще не инициализированы, но использованы — это, скорее всего, та самая ошибка.

S>В силу того что компилятор выдаёт предупреждения по поводу неинициализированных переменных,

S>никому спец синтаксис для этого не нужен.

студия спокойно глотает с /W4 и даже /WAll


inline void f(int&) {}

int main()
{
    int i;
    f(i);
    return i;
}
Русский военный корабль идёт ко дну!
Re[3]: Инициализация
От: skeptic  
Дата: 20.12.13 09:44
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Здравствуйте, skeptic, Вы писали:


S>>Обратная совместимость


AG>С чем? Кто-то рассчитывает прочитать определённый мусор?


Ну, если я тебя правильно понял, то ты хочешь что бы переменную нельзя было объявить без определения, так?
Ну в таком случае у тебя куча уже написанного кода перестанет работать.
Re[4]: Инициализация
От: Alexander G Украина  
Дата: 20.12.13 09:46
Оценка:
Здравствуйте, skeptic, Вы писали:


S>Ну, если я тебя правильно понял, то ты хочешь что бы переменную нельзя было объявить без определения, так?

S>Ну в таком случае у тебя куча уже написанного кода перестанет работать.

Нет, я хочу, чтобы просто

int i;

компилилось как

int i = 0;


а если не нужен этот "= 0", то синтаксис, как выше.
Русский военный корабль идёт ко дну!
Re[5]: Инициализация
От: skeptic  
Дата: 20.12.13 09:50
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Здравствуйте, skeptic, Вы писали:



S>>Ну, если я тебя правильно понял, то ты хочешь что бы переменную нельзя было объявить без определения, так?

S>>Ну в таком случае у тебя куча уже написанного кода перестанет работать.

AG>Нет, я хочу, чтобы просто


AG>
AG>int i;

AG>

AG>компилилось как

AG>
AG>int i = 0;

AG>


AG>а если не нужен этот "= 0", то синтаксис, как выше.


А что такое — "= 0"? и для любого ли типа такой 0 прокатит?
Ну и в конце концов чем отличается такой вот 0 от мусора?
Re[6]: Инициализация
От: Alexander G Украина  
Дата: 20.12.13 09:54
Оценка:
Здравствуйте, skeptic, Вы писали:

S>А что такое — "= 0"? и для любого ли типа такой 0 прокатит?


Дефолтная инициализация.
У любого типа есть она.

Вот такое дефолтно инициализирует структуру, содержащую любые поля.
struct {
  int i;
  void* p;
} s = {};


S>Ну и в конце концов чем отличается такой вот 0 от мусора?


Предсказуемостью. Меньше будет проблем которые воспроизводятся только в определённой фазе луны.
Русский военный корабль идёт ко дну!
Re[7]: Инициализация
От: skeptic  
Дата: 20.12.13 10:02
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Здравствуйте, skeptic, Вы писали:


S>>Ну и в конце концов чем отличается такой вот 0 от мусора?


AG>Предсказуемостью. Меньше будет проблем которые воспроизводятся только в определённой фазе луны.

Какой предсказуемостью? Как ты узнаешь что 0 это неинициализированная переменная а не кто то присвоил 0?
Re[9]: Инициализация
От: skeptic  
Дата: 20.12.13 10:27
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Здравствуйте, skeptic, Вы писали:


S>>Какой предсказуемостью? Как ты узнаешь что 0 это неинициализированная переменная а не кто то присвоил 0?


AG>С реализацией такого предложения будет не важно, присвоил ли кто-то 0, или оно там само.


AG>Предсказуемость в том, что даже если 0 там не есть то, что хотели, ошибочное поведение будет стабильным, а не зависеть от конфигурации, компилятора, ОС, и того, какая функция вызывалась на этом стеке раньше.


Ну, по спец.синтаксису я резко против, по понятным причинам — поломается много кода.
А по дефолтному присваиванию я думаю это не решит проблемы, зато добавит их разработчикам стандарта и компиляторов.
Ну и всё таки не ясно как выбирать дефолтные значения для разных типов?
Re[10]: Инициализация
От: Alexander G Украина  
Дата: 20.12.13 10:34
Оценка:
Здравствуйте, skeptic, Вы писали:

S>Ну и всё таки не ясно как выбирать дефолтные значения для разных типов?


Они уже давно выбраны.
Я привёл выше синтаксис как до них добраться, вот другой синтаксис:
template<class T>
void InitializeDefault()
{
   T t = T(); // для чисел - 0, для bool - false, для указателей - nullptr, для классов - дефолтный конструктор.
  // на большинстве платформ двоичное представление этих значений - все байты нули.
}
Русский военный корабль идёт ко дну!
Re[9]: Инициализация
От: uzhas Ниоткуда  
Дата: 20.12.13 10:35
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Предсказуемость в том, что даже если 0 там не есть то, что хотели, ошибочное поведение будет стабильным, а не зависеть от конфигурации, компилятора, ОС, и того, какая функция вызывалась на этом стеке раньше.


в целом согласен, что пока мы в прошлом веке, т.к. спотыкаемся о подобные проблемы. рандомные баги из-за неинициализированных данных очень неприятны. хочется, чтобы программы вели себя детерминировано и баги можно было легко воспроизводить
проблему можно частично решать не на уровне языка, а на уровне средств : компиляторы должны выявлять такие моменты и очень часто это довольно простой код (члены класса в конструкторе не инициализируются, переменные на стеке)
Re[2]: Инициализация
От: Alexander G Украина  
Дата: 20.12.13 10:44
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Потому, что массивы бывают длинны.


Принимается.
Хотя я предложил и варианты эскейпа для явной не-инициализации, которые можно применить и к массивам.

int a[1000] = { void };

[[uninitialized]]
int a[1000];


AG>>RegQueryValue(count); // забыли проверить возвращаемое значение


BFE>А что собственно вы тут собрались проверять?


Это функция некоторого system API или legacy API, сообщающая результат через код возврата, который надо было бы проверить.

BFE>Обратная совместимость важнее удобства.


Компиляция старого кода не ломается же.
Да, перформанс инициализации массивов ломается в некоторых случаях.
Русский военный корабль идёт ко дну!
Re: Инициализация
От: Mr.Delphist  
Дата: 20.12.13 10:44
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Ну вот какого хрена в век, когда лямбды уже не вызывают "это ты выпендрился?"-реакцию на код ревью, когда все самые необходимые смарт-поинтеры уже есть в std, а в boost есть вообще все нужные, до сих пор можно наткнуться на непредсказуемую инициализацию переменных?


AG>
AG>int count;
AG>RegQueryValue(count); // забыли проверить возвращаемое значение
AG>for (int i = 0 ; i < count ; i++) // и приплыли - цикл повторяется непредсказуемое количество раз
AG>


Найдите 10 отличий:
int count;
if (ERROR_SUCCESS != RegQueryValue(count)) // не забыли проверить возвращаемое значение
    break; // return, continue, throw, etc - короче, включаем мозги по ситуации
for (int i = 0 ; i < count ; i++) // и не приплыли - цикл повторяется предсказуемое количество раз
Re[2]: Инициализация
От: Mr.Delphist  
Дата: 20.12.13 10:46
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>int count = -1; // даже так
Re[2]: Инициализация
От: Alexander G Украина  
Дата: 20.12.13 10:51
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>Найдите 10 отличий:

MD>
MD>int count;
MD>if (ERROR_SUCCESS != RegQueryValue(count)) // не забыли проверить возвращаемое значение
MD>    break; // return, continue, throw, etc - короче, включаем мозги по ситуации
MD>for (int i = 0 ; i < count ; i++) // и не приплыли - цикл повторяется предсказуемое количество раз
MD>


К сожалению, не все таки умные.
В своё оправдание могу сказать только то, что я это не писал, оно мне досталось.
Русский военный корабль идёт ко дну!
Re[3]: Инициализация
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 20.12.13 10:55
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Здравствуйте, skeptic, Вы писали:


S>>Обратная совместимость


AG>С чем? Кто-то рассчитывает прочитать определённый мусор?


Нет, просто где-то незначительно, где-то может и ощутимо просядет производительность у всего C++ кода, которого дофига. Непонятно, в чем проблема ввести требование обязательной инициализации?
Re: Инициализация
От: Abyx Россия  
Дата: 20.12.13 10:55
Оценка:
Здравствуйте, Alexander G, Вы писали:

комлятор и так проинициализровал тебе переменную значением 0xCDCDCDCD (в дебажной конфигурации).
а вообще говнокод писать не надо, и всё будет хорошо.
In Zen We Trust
Re[2]: Инициализация
От: Alexander G Украина  
Дата: 20.12.13 11:01
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Потому что функция в случае неудачи может

К>- не инициализировать
К>- инициализировать удобным дефолтным или сигнальным значением (0)
К>- инициализировать неудобным сигнальным значением (-1 или 0xFFFFFFFF, или 0xDEADFACE какое-нибудь)
К>- инициализировать случайным мусором

Инициализация не приведёт к желаемому результату только в последних двух случаях.

В WinAPI я таковых не встречал. В WinAPI чаще первый случай, хотя изредка второй.
В других API последние два тоже редкость.

И то, хоть инициализация и не поможет, дополнительного вреда она не принесёт.

К>Такая же логическая ошибка, только более регулярная: будет ходить не по разным граблям, а по одним и тем же.


Я за регулярность. Чтобы ошибка, которая вылезла только у меня, вылезла и у чувака, который это закоммитил.
Русский военный корабль идёт ко дну!
Re[2]: Инициализация
От: Alexander G Украина  
Дата: 20.12.13 11:13
Оценка:
Здравствуйте, visual_wind, Вы писали:

AG>>
AG>>int count;
AG>>RegQueryValue(&count); // забыли проверить возвращаемое значение
AG>>for (int i = 0 ; i < count ; i++) // и приплыли - цикл повторяется непредсказуемое количество раз
AG>>

_>Вероятно, вы имели ввиду выделенное.

Забыл указать, я о С++, а не о С.
Это — ссылка.
Русский военный корабль идёт ко дну!
Re[3]: Инициализация
От: B0FEE664  
Дата: 20.12.13 11:15
Оценка:
Здравствуйте, Alexander G, Вы писали:

BFE>>Потому, что массивы бывают длинны.

AG>Принимается.
AG>Хотя я предложил и варианты эскейпа для явной не-инициализации, которые можно применить и к массивам.

Не надо этого. Ключи компиляции или прагмы какие тут лучше подойдут.

AG>>>RegQueryValue(count); // забыли проверить возвращаемое значение

BFE>>А что собственно вы тут собрались проверять?
AG>Это функция некоторого system API или legacy API, сообщающая результат через код возврата, который надо было бы проверить.

Договорится не использовать напрямую. Всегда через обертку:
int ApiRegQueryValue(int& err)
{
  int count = 0;
  err = RegQueryValue(count);
  return count;
}
И каждый день — без права на ошибку...
Re[3]: Инициализация
От: Mr.Delphist  
Дата: 20.12.13 12:22
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>К сожалению, не все таки умные.

AG>В своё оправдание могу сказать только то, что я это не писал, оно мне досталось.

Прекрасно понимаю — быть по колено в legacy часть нашей профессии. Но часть нашей профессиональной ответственности — выправлять если не архитектуру (ибо не всегда апрувят), то хоть такие мелкие залепухи, чтобы линейный код был устойчивым к жизни. Благо в большинстве компаний для таких фиксов не требуется благословления менеджмента.
Re[3]: Инициализация
От: visual_wind  
Дата: 20.12.13 13:10
Оценка:
Здравствуйте, enji, Вы писали:

E>Здравствуйте, visual_wind, Вы писали:


E>Ну вообще-то регистры железа обычно объявляются как дефайны с адресом... А не как переменные, смапленные на память.

Обычно в этом дефайне содержится разыменованный указатель на volatile int, к которому приведен этот самый адрес.

AG>>>[ccode]

E>Нету этого в эмбедед. Он пишет в частности про стековые переменные, как ты их собрался класть в секции?
E>Опять же, никто тебе не мешает и под десктопом переменные по секциям раскладывать...
Здесь да, согласен, я протупил. Увы, стековые переменные никак не проинициализируешь, положив их в секцию.
Re: Инициализация
От: Шахтер Интернет  
Дата: 20.12.13 13:28
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Ну вот какого хрена в век, когда лямбды уже не вызывают "это ты выпендрился?"-реакцию на код ревью, когда все самые необходимые смарт-поинтеры уже есть в std, а в boost есть вообще все нужные, до сих пор можно наткнуться на непредсказуемую инициализацию переменных?


AG>
AG>int count;
AG>RegQueryValue(count); // забыли проверить возвращаемое значение
AG>for (int i = 0 ; i < count ; i++) // и приплыли - цикл повторяется непредсказуемое количество раз
AG>



AG>Почему не введут инициализацию для всех простых типов?


Повторяя вслед за Кодтом, "потому что забытый ноль и.т.д.".
Это не решение проблемы. В данном конкретном случае нужно было просто завернуть вызов в функцию с контролем и выбросом исключения.
Нужно просто правильно проектировать интерфейсы. Если используются старые библиотеки или системное API, то следует использовать их не напрямую, а через
облагораживающие прокладки.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[11]: Инициализация
От: Erop Россия  
Дата: 20.12.13 15:42
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Я привёл выше синтаксис как до них добраться, вот другой синтаксис:

AG>
AG>template<class T>
AG>void InitializeDefault()
AG>{
AG>   T t = T(); // для чисел - 0, для bool - false, для указателей - nullptr, для классов - дефолтный конструктор.
AG>  // на большинстве платформ двоичное представление этих значений - все байты нули.
AG>}

AG>


Для перечислений что будет?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Инициализация
От: Pavel Dvorkin Россия  
Дата: 21.12.13 05:06
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>for (int i = 0 ; i < count ; i++) // и приплыли — цикл повторяется непредсказуемое количество раз


Никуда я не приплыл


void RegQueryValue(int count)
{
}

int _tmain(int argc, _TCHAR* argv[])
{
    int count;
    RegQueryValue(count); // забыли проверить возвращаемое значение
    for (int i = 0 ; i < count ; i++) // и вот здесь выдается окно Run-Time Check Failure #3 - The variable 'count' is being used without being initialized.
        return 0;
}


VS 2008, Debug
With best regards
Pavel Dvorkin
Re[2]: Инициализация
От: Abyx Россия  
Дата: 21.12.13 09:50
Оценка:
Здравствуйте, мыщъх, Вы писали:

М>"после того как это введут в стандарт"

расслабься, такой бред никогда не будет в стандарте.
In Zen We Trust
Re[2]: Инициализация
От: TarasB  
Дата: 21.12.13 10:20
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Потому, что массивы бывают длинны.


Можно ввести понятие "статический массив размера N, у которого имеют смысл только первые M членов".
N — определяется при создании массива и меняться при его жизни не может. К сожалению, оно пока что в С++ может существовать лишь как константа времени компиляции, ведь alloca — некроссплатформенная хрень.
M — может меняться со временем.
Попытки обратиться к членам, находящимся за M-ым, пресекаются ассертом.

Так вот, массивы можно по умолчанию инициализировать как "изначально M=0". Если надо считать в массив информацию — то по одному наращиваем M, добавляя в конец конкретное значение.
Если надо сразу резко увеличить M — то тогда все новые элементы либо заполняются заранее оределённым значением, либо для них вызывается конструктор по умолчанию.
Re[10]: Инициализация
От: niXman Ниоткуда https://github.com/niXman
Дата: 21.12.13 16:00
Оценка:
чтоб этого не добавлять в стандарты, в clang и GCC добавили UndefinedBehaviorSanitizer.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[4]: Инициализация
От: wander  
Дата: 21.12.13 17:35
Оценка:
Здравствуйте, Vzhyk, Вы писали:

V>у меня память течет, нет ли доктора-телепата.


Компилятор, гад, неправильно работает.
Re[3]: Инициализация
От: Erop Россия  
Дата: 21.12.13 19:02
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>>>
AG>>>RegQueryValue(&count); // забыли проверить возвращаемое значение
AG>>>


AG>Забыл указать, я о С++, а не о С.

AG>Это — ссылка.

Если таки RegQueryValue -- это не С-шная апишная функция, а таки С++ обёртка, то просто её надо было писать по-человечески, а не на компилятор пенять.
Например оно могло бы быть примерно таким:
int RegQueryValue( int& errCode, int defaultValue = 0 );
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Инициализация
От: Философ Ад http://vk.com/id10256428
Дата: 22.12.13 21:33
Оценка:
Здравствуйте, Erop, Вы писали:

E>Если таки RegQueryValue -- это не С-шная апишная функция, а таки С++ обёртка, то просто её надо было писать по-человечески, а не на компилятор пенять.

E>Например оно могло бы быть примерно таким:
int RegQueryValue( int& errCode, int defaultValue = 0 );


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

В BCL очень грамотно подошли к этому вопросу: названия тех методов, которые не бросают исключение начинается Try, например: Double.TryParse() не бросает, а Double.Parse().

ЗЫ: За игнорирование возвращаемых значений нужно бить по рукам, желательно автоматически. Если уж хочется проигнорировать, то нужен способ сделать это явно (например, подавить варнинг директивой).
Всё сказанное выше — личное мнение, если не указано обратное.
Re[5]: Инициализация
От: Vzhyk  
Дата: 23.12.13 07:33
Оценка:
12/23/2013 12:33 AM, Философ пишет:

> Зело убого смотрится, не согласен.

> В таких случаях нужно исключение бросать, его проигнорировать
> невозможно.
Бред. Все определяется только задачей.
Posted via RSDN NNTP Server 2.1 beta
Re[5]: Инициализация
От: Erop Россия  
Дата: 23.12.13 17:18
Оценка:
Здравствуйте, Философ, Вы писали:

Ф>Зело убого смотрится, не согласен.

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

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

Кстати, исключение проигнорировать так же просто, как и специально заведённую для кода ошибки переменную...

Ф>В BCL очень грамотно подошли к этому вопросу: названия тех методов, которые не бросают исключение начинается Try, например: Double.TryParse() не бросает, а Double.Parse().

Есть разные соглашения и подходы к тому, как и для чего надо использовать исключения.
Я, например, сторонник их использования, но только для реально исключительных ситуаций...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: Инициализация
От: andyp  
Дата: 25.12.13 10:57
Оценка:
+1 Для многих объектов (в том числе встроенных типов) вполне хорошо и привычно находиться в частично инициализированном состоянии, в котором ему либо что-то будет присвоено, либо он будет разрушен. Я с этим смирился, а некоторые видимо нет .
Re: Инициализация
От: Lepsik Индия figvam.ca
Дата: 07.01.14 21:22
Оценка:
пользуйтесь Borland C++ — там всегда все типы инициализируются
Re[10]: Инициализация
От: opener  
Дата: 14.01.14 09:09
Оценка:
Здравствуйте, skeptic, Вы писали:

S>Здравствуйте, Alexander G, Вы писали:


AG>>Здравствуйте, skeptic, Вы писали:


S>>>Какой предсказуемостью? Как ты узнаешь что 0 это неинициализированная переменная а не кто то присвоил 0?


AG>>С реализацией такого предложения будет не важно, присвоил ли кто-то 0, или оно там само.


AG>>Предсказуемость в том, что даже если 0 там не есть то, что хотели, ошибочное поведение будет стабильным, а не зависеть от конфигурации, компилятора, ОС, и того, какая функция вызывалась на этом стеке раньше.


S>Ну, по спец.синтаксису я резко против, по понятным причинам — поломается много кода.

S>А по дефолтному присваиванию я думаю это не решит проблемы, зато добавит их разработчикам стандарта и компиляторов.
S>Ну и всё таки не ясно как выбирать дефолтные значения для разных типов?

А в чем проблема с дефолтными значениями? Во всяких там джавах именно так и делают — инициализируют все переменные по умолчанию.
Re[2]: Инициализация
От: opener  
Дата: 14.01.14 09:15
Оценка:
Здравствуйте, Lepsik, Вы писали:

L>пользуйтесь Borland C++ — там всегда все типы инициализируются


Ужос
Прямо джава какая-то.
Re[2]: Инициализация
От: Alexander G Украина  
Дата: 14.01.14 10:34
Оценка:
Здравствуйте, opener, Вы писали:

O>Приучи себя к простейшим правилам написания безопасного кода, и подобные проблемы отпадут сами собой.


не отпадут, пока приходится поддерживать и чужой код.
Русский военный корабль идёт ко дну!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.