madf: (Default)
Я досить часто зустрічаю думку що для написання безпечного з точки зору memory management коду на C++ треба його „обмазати“ std::shared_ptr. Мене ця точка зору дико бісить, бо насправді std::shared_ptr означає що у програміста просто не залишилось іншого виходу. std::shared_ptr дуже складна і доволі небезпечна штука, тому я вважаю що для використання саме цього smart pointer треба чітко розуміти його природу, призначення і вміти відповідати на наступні запитання:


Junior level:

  • Що таке std::smart_ptr?

  • Для чого він потрібен?

  • Які відносини між std::shared_ptr і std::weak_ptr?

  • Навіщо потрібен std::weak_ptr?

  • Чи можна вважати std::weak_ptr smart pointer?

  • Чи можна вважати std::weak_ptr вказівником?

  • Що ж тоді таке std::weak_ptr?



Middle level:

  • Що таке std::enable_shared_from_this?

  • Для чого він потрібен?

  • Як std::enable_shared_from_this взаємодіє з наслідуванням?



Senior/Lead/Architect level:
  • PIMPL і std::enable_shared_from_this — як їх помирити?


Насправді, у 80% випадків достатньо value/reference/std::unique_ptr. До речі, raw pointer, про який кажуть шо його ніколи-ніколи, навіть під дулом автомату не можна використовувати насправді можна використовувати для імітації maybe-семантики (коли std::/boost::optional з якихось причин не підходить). Нічого страшного у ньому немає. Треба просто запам'ятати кілька правил:


  1. Ссилка і вказівник не передають володіння (за винятком new, але від нього треба відмовлятись на користь std::make_shared/std::make_unique). Нам не треба хвилюватись про знищення ресурсу.

  2. Значення робить копію або передає володіння (якщо повертаємо локальний об'єкт із функції). Нам не треба хвилюватись про знищення ресурсу.

  3. std::unique_ptr передає володіння. Знищення ресурсу на нашій совісті (але std::unique_ptr потурбується про це).



Я стверджую що слідування цим правилам ніколи не призводить до проблем з пам'яттю і покриває 80% випадків, коли треба обирати вид smart pointer. Для 20% що залишились все ж доводиться використовувати std::shared_ptr. Один із таких випадків — Boost.ASIO. std::shared_ptr у цьому випадку не потрібен тоді і тільки тоді коли ваші об'єкти гарантовано живуть довше за boost::asio::io_service.

Overdesign

Dec. 31st, 2015 10:29 am
madf: (Default)
Скільки програмістів потрібно щоб замінити лампочкуСкільки LOC потрібно щоб на OpenSSL звмутити base64?

std::string base64(const std::string& value)
{
    BIO* bio = BIO_new(BIO_f_base64());
    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
    BIO_push(bio, BIO_new(BIO_s_mem()));
    BIO_write(bio, value.c_str(), value.size());
    BIO_flush(bio);
 
    std::string res;
    char* data = nullptr;
    size_t size = BIO_get_mem_data(bio, &data);
    if (size != 0 && data != nullptr)
        res.assign(data, size);
 
    BIO_free_all(bio);
 
    return res;
}


Насправді більше, бо треба ж перевіряти виділення пам'яті...
madf: (Default)
Спочатку Bartosz Milewski: „C++17: I See a Monad in Your Future!“.
Потім Ivan Čukić: Meeting C++ with Monads, Berlin“.
Сьогодні Joaquín Mª López Muñoz: „Monads in C++14“.
madf: (Default)
Я завжди знав що тема часових поясів у програмуванні — це пекельні котли і авгієві конюшні (разом з темою локалізації), тому старався уникати її. Коли знайомі адміни дорікали мені за логи у UTC я казав що Грінвіч рулить (не коньяк) і взагалі у логах які скачуть туди-сюди двічі на рік фіг що знайдеш потім. Плюс там всякі політичні складові — переходити, чи не переходити... Тож уникав я цієї теми довго, поки не стикнувся з податковою службою Грузії. Не вдаючись у подробиці, знадобилось на одному проекті зафігачити кастомні часові пояси для перегляду певної статистики. Ржака в тому, що українські користувачі взагалі не скаржилися на час у UTC (відношення було приблизно таке: „лишь были б желуди, ведь я от них жирею“), російські користувачі трохи скаржились що треба перераховувати локальний час щоб подивитись статистику за добу, а грузини покликали на поміч своїх податківців і категорично відмовились щось там рахувати. Ну в принципі, позиція правильна. Я теж завжди кажу що це задача комп’ютера щось там рахувати — він для того створений був.
Read more... )
madf: (Default)
C++ Ranges are Pure Monadic Goodness
Bartosz як завжди прекрасний. Якщо у 17-й стандарт додадуть ranges від Eric Niebler то з C++ уже можна буде жити у сучасному світі. А то там всякі додають optional без fmap з семантикою вказівників і думають що несуть світло й добро...

C++14

Aug. 18th, 2014 09:55 pm
madf: (Default)
Затвердили стандарт: „We have C++14!“.
madf: (Default)
Уявіть собі що у вас є контейнер вказівників на базовий клас і цей контейнер треба відсортувати за типами конкретних об’єктів що лежать у контейнері. Щоб було більше конкретно, живий приклад: маємо журнал виконання певної операції (у моєму випадку то були corporate actions: stock split, merger і spin-off, але це не важливо), треба цю операцію „відкотити“, але порядок виконання операцій при „відкочуванні“ важливий, а записи у журналі можуть іти у довільному порядку.
Проблема у написанні оператора порівняння двох об’єктів за вказівниками (або посиланнями) на базовий клас. Проблема відома під назвою „мультиметоди“ чи „подвійна диспетчеризація“. У C++ зазвичай вирішується або через матрицю відношень, або через dynamic_cast, або через (щасругнусь) паттерн „Visitor“. Але фігачити таблиці порівнянь ліниво, тому використаємо template metaprogramming voodoo щоб заставити компілятор нагенерувати то все самому.
Годі базікати, вйо до коду!
Read more... )
madf: (Default)
Майєрс смалить.

Originally posted by [livejournal.com profile] thedeemon at Scott Meyers o C++
Абсолютно волшебное выступление Мейерса о современном С++, как много там косяков и ненужных сложностей прямо со входа:
http://www.ustream.tv/recorded/47947981
Практически stand-up comedy получилась. Рекомендую.
madf: (Default)
fix
Ерік кльовий чувак, але від цього коду у мене моск в трубочку скручується.
Власне, звідси: „F-Algebras and C++“. У Бартоша на Haskell набагато простіше виходить: „Understanding F-Algebras“.
madf: (Default)
Випадково помітив:
POSIX Shell   C++98/03   C++11   Haskell

#!/bin/sh

for i in {1..4}
do
    echo $i
done
      

 
#include <iostream>

int main()
{
int arr[] = {1, 2, 3, 4};
for (size_t i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i)
std::cout << arr[i] << "\n";
return 0;
}
_Winnie C++ Colorizer

 
#include <iostream>

int main()
{
for (auto i : {1, 2, 3, 4})
std::cout << i << "\n";
return 0;
}
_Winnie C++ Colorizer

 
module Main where

main = mapM_ print [1..4]
      

6 LOC   9 LOC   8 LOC   3 LOC

Для чого це потрібно? Іноді буває необхідно проітеруватись по enumeration. Не городити ж для цього масив, в кінці кінців...
PS: ага, і Shell, і плюсовий код теж можна в один рядок записати. Але ж читабельність...

А да...

Apr. 13th, 2014 12:55 pm
madf: (Default)
„А воз и ныне там“
gcc-4.8.2
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/bits/stl_list.h:871
/** Returns the number of elements in the %list. */
size_type
size() const _GLIBCXX_NOEXCEPT
{ return std::distance(begin(), end()); }
_Winnie C++ Colorizer
madf: (Default)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49561

Коротко:
2011-06-28 08:17:46 UTC
„I realized that the complexity of std::list::size() is O(n), not O(1).

This does not conform to standard. The standard states that size() function is in constant time for alls containers. So, the behavior of gcc is not as expected.“


2011-10-04 22:22:39 UTC
„Done. If you can, please stress std::list in C++0x mode in order to shake possible bugs related to the O(1) size in time for the 4.7.0 release.“

2012-07-03 01:40:12 UTC
„Patch reverted, thus in C++11 mode size() is back to O(n) but std::list can interoperate with the C++98 version of it.“

2012-07-03 03:35:31 UTC
„Why has this been reverted? If std::list<>::size() is not O(1), then GCC's C++11 standard library is not compliant with the C++11 international standard. I have personally spoken with multiple members of the standard body and confirmed that this behavior is REQUIRED by the C++11 standard.

Please re-apply this patch for C++11 mode, or state somewhere in the GCC docs that GCC is not compliant with the C++11 standard. In the C++03 and C++98 standards, it was highly suggested that compiler vendors implement std::list<>::size() as O(1).“


2012-07-03 08:31:18 UTC
„Yes, we're well aware of that, thanks.

This patch made c++98 and c++11 code incompatible and is causing serious problems for distros.

You've lived with O(n) size for 15 years, you can live with it for a while longer until libstdc++'s ABI changes.“


„15 років жрали лайно — жріть і надалі“.

Завтра буду лякати співробітників. Особливо одного який кричав і бризкав слиною шо if (cont.size() == 0) це нормально і не треба писати if (cont.empty()).
madf: (Default)
Що б там не казав Bjarne Stroustrup шановному [livejournal.com profile] ivan_gandhi, Bartosz Milewski з оптимізмом дивиться у майбутнє: http://bartoszmilewski.com/2014/02/26/c17-i-see-a-monad-in-your-future/
Добро перемагає!
madf: (Default)
Тут шановний [livejournal.com profile] sharpc лякає людей синтаксисом C++, а мені згадались два баги компілятора (а точніше реалізації стандартної бібліотеки), на які ми на роботі наштовхнулись буквально минулого тижня.
Кому не страшно — зазирніть під кат )

Вирву із контексту: „... мир окончательно разделится на людей, которые успели выучить C++, пока он еще был простым, и на тех, кто никогда не осилит...“.
madf: (Default)
Read more... )
Для std::map з очевидних причин не працює.
madf: (Default)
BoostCon-2010:
Functional Programming in C++ (on chalkboard) by David Sankel
Functional Programming in C++ by David Sankel

C++Now!-2013 (свіжачок, конфа ще йде — сьогодні останній день!):
The Intellectual Ascent to Agda by David Sankel

Перші дві презентації спираються на C++03, так що деякі речі зараз можна виразити значно простіше. У останній презентації наводиться приклад коли дизайн розробляється у агдочці а потім на його базі пишеться код на C++. Якщо не помиляюсь, [livejournal.com profile] zamotivator колись писав про те що дизайнив шаблонні метапрограми у Scheme (чи іншому ліспі) а потім кодував на плюсах.
madf: (Default)
Bartosz Milewski підняв цікаву тему: як функтори, аплікативні функтори і монади допомагають боротися з інверсією управління при використанні асинхронного API (в контексті C++).
Відео: „Вступ і про функтори“, „Аплікативні функтори“, „Монади“.
Слайди: https://www.fpcomplete.com/wp-content/uploads/2012/09/Functional-Patterns.pdf
Read more... )

Profile

madf: (Default)
madf

April 2017

S M T W T F S
      1
2345678
9101112131415
1617 1819202122
23242526272829
30      

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 23rd, 2017 08:41 pm
Powered by Dreamwidth Studios