Pull to refresh
25
0
Laphroaig Vi @laphroaig

User

Send message
За жену не переживайте, у электрика нет соответствующего сертификата
Да она уже давным-давно атрофирована! Электричество пропадет и все, конец света
Так человечество в этом направлении и движется. Представьте себе недалекое будущее, ты сидишь дома программируешь в свое удовольствие, жена говорит: «Дорогой, в туалете темно, сделай что-нибудь!». Ты как настоящий мужик отправляешь сообщение в сервисную службу: «В туалете темно». Приходит сертифицированный специалист и делает все как надо, и нет тебе дела до того, как работает лампочка и при чем тут электричество.
Если электронщику нужно написать программу, он вызовет сертифицированного программиста.
А вообще это сарказм был.
Лампочку менять должен только электрик, а программы писать — программист
Уровень младенческой смертности в Японии 3.2 на 1000 рождение. Возьмем проще 1 на 1000 — это вероятность того что ваши родители не умерли в младенчестве и породил вас на свет. Вероятность того, что так будет происходить 10 поколений подряд 99%, а 100 ~ 90%. Ну предположим, что человечество существует 100000 поколений, тогда вероятность моего существования стремиться к нулю ( 3.5e-44 ). Офигеть какой я везунчик!

А вообще вероятность того, что мы просто одни из первых не такая уж и маленькая. Я думаю жизнь будет бурлить возле красных карликов лет так 5-10 миллиардов
Ну прямо парад C++ в последнее время! что не может не радовать
Тут проблема не в «Да» или «Нет», а в адекватной оценке сроков и ресурсов. Мы могём хоть в космос полететь, хоть ОС написать — дайте только мне людей и денег время. Как правило ресурсы ограничены твоей командой — от этого и будем отталкиваться.

Ок, ты профи, у тебя за плечами опыт и много завершенных проектов, ты прекрасно можешь оценить сроки с учетом доступных ресурсов. А вот дальше начинается самая веселуха. Давайте упростим ситуацию — задачу ставит менеджер проекта. Менеджер тоже «профи», он хочет услышать от тебя конкретную цифру по срокам, чтобы в уме ее умножить на два (он тоже «профи» — учитывает все риски). Но если ты реально имеешь опыт, то не можешь дать точную цифру для абстрактной задачи (например как в статье). На вскидку ты можешь определить срок с точностью (внимание!) -80%...+400%!!! Если озвучить эти цифры неподготовленному к ним менеджеру, им это будет воспринято даже не как показатель вашей некомпетентности, а как жесткий троллинг. Я конечно понимаю, менеджеры на то и созданы, чтобы над ними стебаться, но и задачи как-то надо решать.

На самом деле все просто. Нужно вбить в голову себе, менеджерам, руководству и подчиненным, что оценка сроков не всегда тривиальная задача. У вас наверняка найдется пара проектов, где очень похожие «внешне» задачи решались в одном случае добавлением пару строк кода, а в другом перелопачиванием всей системы, который можно привести в пример. Но и здесь нужно уметь держать контрудар — а почему элементарную функциональность может быть внести так тяжело? Любой проект — это поиск компромиссов, между гибкостью, производительностью и сроками разработки. Ок, мы сделаем то-то и то-то в два раза быстрее, но с добавлением того или иного функционала будут проблемы. Цепочка таких компромиссов может быть очень длинной, а начальство очень быстро об этом забывает (да и вы сами) поэтому важно все фиксировать.

Поэтому оценка сроков, любой нетривиальной задачи (а это уже вам решать насколько она тривиальная), требует постановки задачи на оценку сроков. И здесь не все так просто, те же -80%...+400%. Можно зафиксировать для себя верхний предел, допустим 4 часа. Т.е. буквально от нескольких минут до 4-х часов. Если вы не укладываетесь в верхний предел, то тут понятно задача далеко не тривиальна, и на дополнительную оценку нужно просить несколько дней. Уже на этом этапе отсеивается 80% «гениальных» идей типа «давайте сделаем и посмотрим, попрет или нет».

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

Ну и наконец, ты же не быдло-тимлид, чтобы тупо взять задачу, оценить сроки и взять в разработку. Любое «все» можно поделить на 80/20 (или 90/10 или по «золотому сечению», не важно). Нужно быть ленивым и меркантильным (не в плане денег, разумеется). Ок, 80% функционала мы сделаем за неделю, на остальные 20% нужен месяц — а так ли он вам нужен? В 80% он оказывается не особо то и нужным.

Еще один важный момент. Руководство хочет получить конкретную дату, когда проект будет готов, а ты реально можешь оценить сроки в человеко-часах. Опять же с большой погрешностью, может и не в соотношении 80/20, но все же большой. Погрешность примет адекватные очертания после 25%..50% реализации функционала. Ответ простой — ребят, вы отвечаете за разработку, внешние факторы не в вашей компетенции. Отдел тестирования завален работой, менеджеры тупят с уточнением по задачи, у админов факап — это не ваши проблемы, абсолютно. На это есть руководители проекта, менеджеры и пр. Не надо брать на себя их работу. Тем более, возможно, кому-то и платят больше чем вам.

Итеративная разработка. Клевая штука, и не важно какую методологию вы используете, но при 20-25% процентах готовности у вас должен быт работающий прототип системы, который можно «пощупать» и даже отдать на тестирование. Как привило, начальство, не старые пердуны, которые кроме как про водопадную модель ничего не знают. Просто надо деликатно напомнить (даже если об этом и не спрашивают), то что «это» даже если и работает, то основная работа еще впереди, которая подразумевает не просто навешивание «рюшечек».

Итого. Если ты не быдло-кодер, быдло-менеджер, быдло-тимлид, быдло-гендир, то в любом случае должен иметь смелость откровенно общаться со своим непосредственным начальством. Предельно деликатно, без хамства, наездов, без доказательств чей-то (не)компетентности, но аргументировано и развернуто. Если ты держишься за свое место, у тебя дети, жена, ипотека, теща, больная бабушка, съемная квартира, холодильник в кредит и пр. отмазки — то поздравляю = ты неудачник ))
Так в том то все и дело гарантированно доказать UB невозможно, на то оно и UB. В примере из статьи (это очень частный случай) с этой задачей не справились ни clang ни g++, но и оптимизировали они этот код по разному. В итоге clang оптимизирует «неправильно», а g++ «правильно» (в кавычках еще раз, т.к. UB ). В примере выше показал как «обмануть» clang чтобы он не оптимизировал т.к. «не надо».

Другой пример. Использование не инициализированной переменой это UB. Большинство компиляторов детектирует это в простых случаях и выдают warning. Но:
void init(int&){}
int main() {
  int i;
  init(i);
  printf("%d",i);
} 

g++ определил обманку, и выдал warning, а clang проглотил и не поперхнулся. И тот и другой действовали по стандарту.
на сколько я помню, это не относиться к функции main()
Вот еще как можно понять, чем «думает» clang. Простенькая обертка, которую нужно вынести в отдельную единицу трансляции (а то он шибко «умный»):
void *my_realloc(void *ptr, size_t size)
{
  return realloc(ptr, size);
}

Она скроет realloc, и clang не сможет делать каких-либо предположений о «p» и производить какие-либо оптимизации. Опять-же это не отменяет UB и к другим компиляторам это не относиться (gcc «думает» по другому)
Просто представьте, что вы и есть компилятор, и «руками» хотите максимально оптимизировать программу. После realloc, p стал недействительным (его использовать нельзя) и бог с ним, что он указывает туда-же куда и q, для компилятора это уже два разных указателя, и именно поэтому он не оптимизирует if (q==p). И по этой же причине в printf он не разыменовывает p и q, а сразу подставляет числа 1 и 2, потому как с момента присваивания никаких манипуляций с ними сделано не было. А вот если перед условием поставить p=q; то if можно выкидывать, а в printf подставлять 2 (что clang и делает). А если int заменим на volatile int, то это не отменит UB, но заставит компилятор разыменовывать все указатели, и программа отработает правильно. UB на то он UB
Я о них не думаю — я их читаю
обычно таких деятелей, сажают лет так на десять и доводят всему офицерскому составу (в рамках подразделений по все стране). Работает гораздо эффективней печатей на компах, когда ты знаешь, что каждый месяц кого-то где-то сажают за нарушение режима секретности. А рядовых, туда где можно просто что-то стырить, обычно не допускают.
Статью удалили, обсуждение осталось
Разве марихуана на влияет на гипофиз и синтез соматотропных гормонов? Я бы записал это в недостатки
13 сентября 2013
Конечно, есть ряд отрицательных сторон употребления. Не понимаю, как «спортсмен» может сформировать объективное мнение по поводу курения Марихуаны, когда общий контекст этой статьи склоняет читателя в положительную сторону к употреблению. Побольше смахивает на пропаганду. Как бы не закрыли…
6 июня 2014
Спасибо за замечания, статью удалили.
12 июля 2014
Источник: goo.gl/jM8vMe
Для такой задачи есть стандартный механизм:
Примерно так и работают операции со списками типов (в статье есть пример fas::lenght ), но плюс всегда есть специализация, для ускорения компиляции.
Как это реально влияет можно посмотреть в этом ответе выше. А посему я лучше напишу простенький враппер приводящий бустовые последовательности в списки типов
Я не спорю, boost::mpl прекрасный инструмент, а вы перечислили различие концепций с faslib:
ИМХО, это правильно — позволяет менять внутреннее представление данных без изменений клиентского кода. Буст предоставляет интерфейс доступа аналогичный обычным контейнерав времени выполнения.
В faslib во главе угла списки типов, могут меняться инструменты, но представление всегда одно. На ранних этапах я пытался скрыть представление, но отказался от этого.
Это плата за то что оно может работать на куче разных компиляторов, включая древние.
Я не готов за это «платить» )
В бусте это специально сделано, чтоб можно было работать со сложными выражениями не упираясь в ограничение компилятора на максимальную вложенность шаблонов
Это не спасает от ограничения. Вы можете сколь угодно сложные конструкции, а в ограничение вы упретесь при обработке таких выражений. Опять же пример, строим «вектор» из 1600 элементов:
template<int I, typename List >
struct push {
  typedef typename boost::mpl::push_front< List, fas::int_<I> >::type result;
  typedef typename push< I-1, result>::type type;
};

template< typename List >
struct push<0, List> {  typedef List type; };

int main()
{
  typedef boost::mpl::vector<> lst;
  typedef push<800, lst>::type lst800;
  typedef push<800, lst800>::type lst1600;
  std::cout << boost::mpl::size<lst800>::value << std::endl;
  std::cout << boost::mpl::size<lst1600>::value << std::endl;
}

Используя этот способ мы не можем построить за раз вектор больше чем 900 элементов (у меня такое ограничение по умолчанию), потому что именно в push мы упремся в это ограничение. Аналогично мы и список типов можем построить такой же длинны:
template<int I, typename List >
struct push2 {
  typedef typename fas::push_front< fas::int_<I>, List >::type result;
  typedef typename push2< I-1, result>::type type;
};

template< typename List >
struct push2<0, List> {  typedef List type; };

int main()
{
  typedef fas::empty_list lst;
  typedef push2<800, lst>::type lst800;
  typedef push2<800, lst800>::type lst1600;
  std::cout << fas::length<lst800>::value << std::endl;
  std::cout << fas::length<lst1600>::value << std::endl;
}

Кроме того, насколько я помню «вектора» быстрее компилируются обычно (не уверен, т.к. последний раз я в этом копался очень давно).

Время компиляции примера на faslib:
0m1.027s
На boost::mpl:
2m16.836s
Да-да я сам в шоке (от буста, конечно-же)
Дальше, больше 3200 элементов:
faslib: 0m1.400s
boost: 16m58.397s
Вот она сила специализаций. Хотел попробовать сделать крестики-нолики на бусте, чтобы изучить матчасть, но уже больше не хочу
С векторами это я дал конечно, совсем другое имел ввиду. Проще на примере:
  typedef boost::mpl::list<float,double,long double> floats;
  typedef boost::mpl::push_front<floats,int>::type types;
  /* types: 
         boost::mpl::l_item<mpl_::long_<4l>, int, boost::mpl::list3<float, double, long double> >  */

  typedef fas::type_list_n< float,double,long double>::type floats;
  typedef fas::push_front< int, floats>::type types;
  /* types: 
         fas::type_list<int, fas::type_list<float, fas::type_list<double, fas::type_list<long double, fas::empty_list> > > > */

В faslib результатом операции всегда будет список типов — с ним проще работать, а в бусте непонятно что, результат уже на специализациях не отработаешь. В статье я уже писал, что это сильно сокращает время компиляции. Да и вообще монструозно там все как-то, а про препроцессор я вообще молчу
faslib быстрее в плане времени компиляции, и многие конструкции можно реализовать компактнее (меньше кода)
В свое время я рассматривал boost::mpl, но т.к. я игрался с оптимизацией времени компиляции нужны были свои решения с которыми можно экспериментировать. Кроме того boost::mpl работает с векторами, а faslib со списками. Много других нюансов. Например boost::mpl::lamba< fun<_1,_2> >::apply — это шаблон с большим числом параметров (не помню сейчас точно), а в fas::lamba< fun<_1,_2> >::apply — это шаблон ровно с двумя параметрами. Да и вся мощь boost::mpl в faslib мне не нужна была. А в общем, то конечно, играть в крестики-нолики можно научить и с помощью boost::mpl
После многочасового писка глупой ошибки в программе, достаточно сказать ему «Зато хрен ты у меня в крестики-нолики выиграешь» и сразу легче на душе

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity