LINUX.ORG.RU

Тёмные углы C и C++

 ,


13

8

Изначально даный пост предназначался для habrahabr, но местные модераторы его не пропустили без объяснения причин:

Увы, ваш топик «Тёмные углы C и C++» не был одобрен и не попал в общую ленту. Причин этому может быть много, но просим не терроризировать службу технической поддержки, так как там вашу статью даже не видели. Расстраиваться тоже не стоит - попробуйте опубликовать что-нибудь еще.

С уважением, Хабрахабр

В связи с этим выкладываю его сюда.

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

Я не гуру C++. Я не могу похвастаться тем, что с уверенностью распознаю любую шаблонную конструкцию данного языка или возьму и вспомню, что возвращает какая-то редко используемая мной функция из стандартной библиотеки без помощи документации.

Думаю, вы со мной согласитесь, что C++ — язык с очень высоким порогом вхождения. Серьёзно! Я изучаю этот язык уже больше 3 лет, и практически каждую неделю открываю в нём что-то новое и удивительное. Именно об этом «новом и удивительном» и пойдёт речь в данной статье.

За то время, пока я изучал C++, у меня потихоньку накапливались интересные задачки, сниппеты и просто необычные куски кода, которыми я делился с коллегами по работе и знакомыми. У нас даже появилась своего рода традиция — каждый рабочий день с того момента, как я пришёл в компанию, я выкладывал по две новых задачки, которые мы старались по возможности обсудить в перерывах. Постепенно их набиралось всё больше и больше, пока, наконец, я не стал забывать некоторые из них. Именно в тот момент я решил предпринять попытку составления сборника так называемых «тёмных углов» C и C++. Я собрал воедино все те куски кода, что видел до сих пор, дополнил их цитатами из различных стандартов и продолжил копить свою «коллекцию». Изначально моей целью было собрать вместе всего 100 задачек, но я и оглянуться не успел, как их стало уже 200, 300 и вот теперь 400. На самом деле, их даже больше, но на данном этапе я решил ограничиться именно этим количеством.

Итак, представляю Вашему вниманию книгу «C and C++ Dark Corners». Конечно, назвать её книгой можно с натяжкой, ведь это, как я уже и сказал, сборник интересных и для кого-то малоизвестных мест C и С++.

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

В качестве примера приведу несколько вопросов из книги:

97. Что попадёт в stdout в результате выполнения след. кода и почему?

#include <iostream>
#include <memory>

#include <boost/smart_ptr/scoped_ptr.hpp>

class Foo
{
public:
 ~Foo() { std::cout << "Foo::~Foo() \n"; }
};

class Bar : public Foo
{
public:
 ~Bar() { std::cout << "Bar::~Bar() \n"; }
};

class Baz : public Bar
{
public:
 ~Baz() { std::cout << "Baz::~Baz() \n"; }
};

int main()
{
 std::cout << 1 << '\n';
 {
  Foo* instance = new Baz;
  delete instance;
 }

 std::cout << 2 << '\n';
 {
  std::shared_ptr<Foo> instance(new Baz);
 }

 std::cout << 3 << '\n';
 {
  std::shared_ptr<Foo> instance(false ? new Bar : new Baz);
 }

 std::cout << 4 << '\n';
 {
  boost::scoped_ptr<Foo> instance(new Baz);
 }

 std::cout << 5 << '\n';
 {
  std::unique_ptr<Foo> instance(new Baz);
 }

 std::cout << 6 << '\n';
 {
  std::auto_ptr<Foo> instance(new Baz);
 }
}

A: Первый случай уже обсуждался ранее – здесь UB в чистом виде (как правило, это приводит к тому, что не будет вызван деструктор производного класса).

Второй случай выдаст на экран следующее:

Baz::~Baz()

Bar::~Bar()

Foo::~Foo()

Почему? Что произошло? Ведь мы же ясно видим, что деструкторы у данных классов не являются виртуальными. Или это один из частных случаев UB? На самом деле, тут всё вполне законно и должно работать так, как указано выше. Посмотрим в документацию к std::shared_ptr и boost::shared_ptr:

http://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr

Proper delete expression corresponding to the supplied type is always selected, this is the reason why the constructors are implemented as templates using a separate parameter Y.

http://www.boost.org/doc/libs/1_51_0/libs/smart_ptr/shared_ptr.htm

This constructor has been changed to a template in order to remember the actual pointer type passed. The destructor will call delete with the same pointer, complete with its original type, even when T does not have a virtual destructor, or is void.

Третий случай выдаст:

Bar::~Bar() Foo::~Foo()

Почему? Ведь мы только что обсуждали поведение std::shared_ptr! Что тут не так? Вспомните поведение тернарного оператора в C++ — он требует, чтобы второй и третий его операнды были одинакового типа. Более того, каст от базового к производному касту без лишних действий не выполнить, в отличие от обратной ситуации:

#include <iostream>

class Base
{
};

class Derived : public Base
{
};

int main()
{
 Base* first;
 Derived* second;

 Base* foo = second; // Ok
 Derived* bar = first; // Error: invalid conversion from 'Base*' to 'Derived*'
}

Наткнуться на данный момент, связанный с тернарным оператором, можно также и в подобном случае:

#include <iostream>
#include <typeinfo>

template <typename T, typename U>
auto foo(bool b, T t, U u)-> decltype(b ? t : u)
{
 return b ? t : u;
}

int main()
{
 auto _1 = foo(true, 0, 'c');
 std::cout << typeid(_1).name() << '\n';
 auto _2 = foo(false, 0, 'c');
 std::cout << typeid(_2).name() << '\n';
}

Переменные _1 и _2 будут одного и того же типа – int.

Именно поэтому Baz в данном случае будет приведён к Bar.

4, 5 и 6 случаи ничем не отличаются от первого – здесь UB. Надо помнить, что поведение std::shared_ptr отличается от остальных умных указателей.

43. Зачем может понадобиться писать так

#define DO_JOIN(FOO, BAR) DO_JOIN1(FOO, BAR)
#define DO_JOIN1(FOO, BAR) FOO##BAR

вместо

#define DO_JOIN(FOO, BAR) FOO##BAR

A: Потому что препроцессор отработает конкатенацию не так, как того ожидал программист, в том случае, если в качестве аргумента(-ов) мы передадим в макрос DO_JOIN другой макрос:

#include <iostream>

#define DO_JOIN(FOO, BAR) DO_JOIN1(FOO, BAR)
#define DO_JOIN1(FOO, BAR) FOO##BAR

#define MY_MACRO 5

int main()
{
 std::cout << DO_JOIN(1, MY_MACRO) << '\n';
}

Output:

15

#include <iostream>

#define DO_JOIN(FOO, BAR) FOO##BAR

#define MY_MACRO 5

int main()
{
 std::cout << DO_JOIN(1, MY_MACRO) << '\n';
}

error: unable to find numeric literal operator 'operator"" MY_MACRO'

Получается, макрос MY_MACRO не успел раскрыться, в результате чего была попытка провести конкатенацию с 1 и MY_MACRO, что, разумеется, привело к ошибке.

ISO/IEC 14882:2011

16.3.1 Argument substitution [cpp.subst]

1 After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded. Before being substituted, each argument’s preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.

44. Что попадёт в stdout в результате выполнения след. кода?

#include <iostream>
#include <stdexcept>

struct Foo
{
 Foo() { std::cout << "Foo::Foo()" << std::endl; }
 ~Foo () { std::cout << "Foo::~Foo()" << std::endl; }
};

void foo()
{
 Foo bar;
 throw std::runtime_error("Error");
}

int main ()
{
 foo();
}

A: Зависит от реализации.

// 1

Foo::Foo()

// 2

Foo::Foo() Foo::~Foo()

ISO/IEC 14882:2011

15.3 Handling an exception [except.handle]

9 If no matching handler is found, the function std::terminate() is called; whether or not the stack is unwound before this call to std::terminate() is implementation-defined (15.5.1).

Например, в документации к gcc сказано, что раскрутки стека не произойдёт:

The stack is not unwound before std::terminate is called.

Сборник выкладывается на бесплатной основе, желающим помочь каким угодно образом буду безумно признателен и благодарен. По любым вопросам, рекомендациям и пожеланиям Вы можете обращаться на мой электронный ящик nikita.trophimov@gmail.com. Буду рад услышать абсолютно любое мнение по данному поводу.

В книге ещё много чего можно и даже нужно дорабатывать. Обещаю, что если сообщество проявит хоть какой-то интерес к данному проекту, я продолжу развивать его согласно Вашим предпочтениям и пожеланиям, дополнять новыми задачками и исправлять ошибки. У меня есть много мыслей по поводу улучшения «C and C++ Dark Corners» — среди них добавление тематических разделов, workaround'ы для различных компиляторов и т.д. Главное, чтобы этот интерес был не только с моей стороны.

Жду Ваших положительных и отрицательных отзывов, рекомендаций и, конечно, новых задачек.

Внимательно ознакомьтесь с тем, что указано во «введении», и приятного чтения!

Ответ на: комментарий от void_ptr

Попытки применения как раз и привели к тому, что некоторые из представленных в данной книге вопросов там вообще оказались. Например, вопрос 66 был составлен на основе проблемы из реального проекта.

NikitaTrophimov
() автор топика
Ответ на: комментарий от xaizek

В принципе, да, согласен. Подумаю насчёт этого, спасибо.

NikitaTrophimov
() автор топика
Ответ на: комментарий от asaw

Вот я об этом и говорю: в итоге синьорам приходится разбираться в сабжевом шлаке.

Ай-яй-яй, сеньоров заставляют учить язык программирования.

Ты данную книжку открывал вообще?

Chaser_Andrey ★★★★★
()

Думаю, вы со мной согласитесь, что C++ — язык с очень высоким порогом вхождения. Серьёзно! Я изучаю этот язык уже больше 3 лет, и практически каждую неделю открываю в нём что-то новое и удивительное.

Эти вещи никак не связаны, и C++ не является языком с высоким порогом вхождения. Вообще говоря, я лично начал изучать программирование как раз с C++ (до этого чуть-чуть кодил на паскале и даже сдал на нём ЕГЭ, но дальше предпочёл плюсы).

Можно ещё привести в качестве примера Objective-C: в нём очень много тонкостей вроде KVO, NSThread, ключевого слова @private — а реально эти конструкции просто никто не использует, потому что есть более простые и удачные способы. Так что сложности Objective-C никого не волнуют и многие о них не знают. В чём проблема так же работать с C++?

quiet_readonly ★★★★
()
Последнее исправление: quiet_readonly (всего исправлений: 1)
Ответ на: комментарий от Chaser_Andrey

Открывал и видел там такое:

#include <iostream> 
 
template <typename T> 
void foo() 
{ 
 std::cout << "T \n"; 
} 
 
template <> 
void foo<int>() 
{ 
 std::cout << "int \n"; 
} 
 
int main() 
{ 
 foo<true ? int : char>(); 
} 

С какого боку тут изучение языка программирования? Оно вообще какой гипотетический смысл может нести?

asaw ★★★★★
()

Статью не читал вообще, но прокомментирую:

Common Lisp! :)

Zubok ★★★★★
()
Ответ на: комментарий от asaw

4.2. Джуниоров про такие тонкости редко спрашивают, а сеньйоры — на то они и сеньйоры, чтобы знать подводные камни.

Вот я об этом и говорю: в итоге синьорам приходится разбираться в сабжевом шлаке.

Сеньорам нужно в этом шлаке разбираться, чтобы понимать, из-за чего именно и при каких условиях взорвётся то говно, которое понаписали жуниоры, которым разбираться ни в чём не нужно.

const86 ★★★★★
()
Ответ на: комментарий от const86

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

asaw ★★★★★
()
Ответ на: комментарий от NikitaTrophimov

Или же сами проводите интервью и ищете какие-то нестандартные вопросы для тех, кто будет их впоследствии проходить?

за такие вопросы в приличных местах бьют

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

Да, это нормально. Как говорится рыбак рыбака... Другое дело считать не ответы на подобные вопросы снижением «баллов». Я понял, что для тех кто их задает надо набираться смелости и задавать собственные вопросы. Уверен, что половина на них не ответит - потому что не сталкивалась, как и я не сталкивался с их проблемами. Но подобное поведение не принято и имеет негатив в виде необоснованного завышения ЧСВ. И все же, для ряда людей-выскочек можно делать исключения :)

gh0stwizard ★★★★★
()

Работа конечно проделана большая. Но я пожалуй читать не буду (на самом деле просто очень некогда). ИМНО пример из введения надуманный - в такой ситуации деструктор при наследовании ДОЛЖЕН БЫТЬ ВИРТУАЛЬНЫМ. На вопрос «а что будет если деструктор не виртуальный?» ответ все тот же «деструктор при наследовании ДОЛЖЕН БЫТЬ ВИРТУАЛЬНЫМ»;-)

Мне бы хотелось увидеть книгу «как не отстрелить себе ногу программируя на С++». А Вы похоже написали книгу, посвященную тому какую именно ногу я себе отстрелю, как пройдет пуля, почему пройдет именно так, как мне эту ногу перевязывать, как жить с одной ногой и т.д.

Думаю, вы со мной согласитесь, что C++ — язык с очень высоким порогом вхождения.

Не соглашусь. Вы путаете «порог вхождения» и «изучение в полном объеме со всеми темными углами». Порог вхождения - это уровень, начиная с которого человек начинает самостоятельно писать работающий код для актуальных задач. Для С++ порог не сильно выше, чем для какого нить питона. Ну и в любом ЯП есть свои темные углы, в С++ их просто много.

И конечно тексты такого объема писать в ворде, это мазохизм чистой воды. Для каждой задачи свои инструменты, это глубоко правильно - так вот ворд это инструмент для написания служебных записок. Для написания таких текстов инструментом является LaTeX. У которого кстати порог вхождения тоже невысокий, но темных углов тоже весьма много;-)

AIv ★★★★★
()

Книга называется «тёмные углы C и C++». Есть ли в ней что-то действительно интересное по C, или он тут просто так приписан? Промотал книгу, ни одного сишного примера не увидел.

Да, и сделай содержание. Даже в ворде это можно сделать.

Laz ★★★★★
()
Ответ на: комментарий от Laz

Есть. Многие вопросы задаются одновременно как по C, так и по C++, причём ответы могут меняться в зависимости от языка.

NikitaTrophimov
() автор топика
Ответ на: комментарий от AIv

На вопрос «а что будет если деструктор не виртуальный?» ответ все тот же «деструктор при наследовании ДОЛЖЕН БЫТЬ ВИРТУАЛЬНЫМ»;-)

Ну, это не ответ. Уж хотя бы в этом случае надо знать, что именно будет происходить. Я согласен в другом (и никогда не считал обратного, в принципе) - несмотря на поведение std::shared_ptr, помечать деструктор виртуальным просто необходимо, если существует вероятность того, что от данного класса будут наследоваться.

И конечно тексты такого объема писать в ворде, это мазохизм чистой воды. Для каждой задачи свои инструменты, это глубоко правильно - так вот ворд это инструмент для написания служебных записок. Для написания таких текстов инструментом является LaTeX. У которого кстати порог вхождения тоже невысокий, но темных углов тоже весьма много;-)

Да, про LaTeX я уже понял, буду смотреть на досуге. Спасибо!

NikitaTrophimov
() автор топика
Ответ на: комментарий от NikitaTrophimov

Ну, это не ответ.

Какой вопрос, такой и ответ. На самом деле правильный вопрос - «как в подобной ситуации сделать что бы работало». На него есть правильный ответ «деструктор должен быть виртуальным» и несколько правильных, но неверных (шайред птр и т.д.).

Уж хотя бы в этом случае надо знать, что именно будет происходить.

Зачем? Монтажник-высотник должен знать как обеспечить страховку на высоте. Точный расчет скорости и угла прихода его тушки на землю в случае неправильной страховки, расчет числа переломанных костей и разорванных внутренних органов на основе компьютерного моделирования, методы первой помощи и организации похоронных мероприятий - этого всего ему знать уже не не обязательно. А Вы предлагаете ему изучать именно это, хотя лучше бы он потратил время на изучение организации страховки. Что будет если он свистнется? Дык понятно что плохо будет...

AIv ★★★★★
()

Я изучаю этот язык уже больше 3 лет

Итак, представляю Вашему вниманию книгу

facepalm.jpg

Рецензирую коротко.

Половину времени мы лепим махровейший быдлокод. Вторую половину пытаемся понять почему он не работает.

Как вас терпит работодатель — загадка.

anonymous
()
Ответ на: комментарий от AIv

Зачем? Монтажник-высотник должен знать как обеспечить страховку на высоте. Точный расчет скорости и угла прихода его тушки на землю в случае неправильной страховки, расчет числа переломанных костей и разорванных внутренних органов на основе компьютерного моделирования, методы первой помощи и организации похоронных мероприятий - этого всего ему знать уже не не обязательно. А Вы предлагаете ему изучать именно это, хотя лучше бы он потратил время на изучение организации страховки. Что будет если он свистнется? Дык понятно что плохо будет...

В таком случае человек будет просто тупо писать то, чего сам не в силах объяснить. А потом его однажды спросят «Эй, а зачем ты деструктор виртуальным помечаешь?», на что он ответит «Да кто его знает, мне так сказали делать во избежание каких-то проблем».

NikitaTrophimov
() автор топика
Ответ на: комментарий от anonymous

Как вас терпит работодатель — загадка.

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

NikitaTrophimov
() автор топика
Ответ на: комментарий от NikitaTrophimov

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

AIv ★★★★★
()
Ответ на: комментарий от AIv

Согласен, я думал, что мы говорим в целом о причинах наличия виртуальных деструкторов.

NikitaTrophimov
() автор топика
Ответ на: комментарий от AIv

Но ведь ваш ответ неправильный и неверный одновременно :)

Я использую наследование с невиртуальными деструкторами и чувствую себя сухо и комфортно.

anonymous
()
Ответ на: комментарий от anonymous

Я не говорил (во всяком случае не имел ввиду), что деструктор должен быть виртуальным при любом наследовании;-)

AIv ★★★★★
()
Ответ на: комментарий от AIv

На вопрос «а что будет если деструктор не виртуальный?» ответ все тот же «деструктор при наследовании ДОЛЖЕН БЫТЬ ВИРТУАЛЬНЫМ»;-)

anonymous
()
Ответ на: комментарий от anonymous

Не надо выдергивать фразы из контекста, фу быть таким. Речь шла об описанной ТС ситуации (или ее аналогах).

AIv ★★★★★
()
Ответ на: комментарий от AIv

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

shared_ptr — весьма полезная штука и за пределами такого контекста. Как и техника сохранения истинного типа вообще, ведь послайсить объект можно многими весьма креативными способами.

Кстати, когда Страуструп (хотя, что его слушать — он оценивает свои знания крестов всего 7/10) приезжал к нам рекламировать 11-й стандарт, он умолял не использовать указатели без обёрток unique_ptr или shared_ptr. Вообще. Ибо он не знаком с людьми, которые в состоянии их осилить в современных сложных проектах.

anonymous
()
Ответ на: комментарий от anonymous

А никто и не говорит, что shared_ptr использовать не надо. Но ТС то другое иллюстрировал (насколько я его смог понять).

умолял не использовать указатели без обёрток unique_ptr или shared_ptr.

Зависит от задач. Мы не используем эти обертки почти почти что никогда;-)

AIv ★★★★★
()
Ответ на: Зависит от задач от anonymous

Это слишком широко. Мы работаем над современными сложными числодробилками, и там это почти нигде ненужно.

AIv ★★★★★
()
Ответ на: комментарий от AIv

В «Дизайне и эволюции», если не ошибаюсь сложность определялась (весьма условно, конечно) в количестве строк кода. Хороший программист может удержать у себя в голове тонкости взаимодействий нескольких десятков тысяч строк (вы, по-моему, хвастались пятью). В 80-х, когда пришлось выдумывать плюсы, всё больше и больше проектов начинало измеряться сотнями тысяч строк. Сегодня мы говорим о миллионах.

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

Тогда наброшу для оживления треда. Популярность функциональных языков, ИМХО, движется не в последнюю очередь теми, кто не осилил нормальный дизайн на объектно-ориентированных.

anonymous
()

[offtop]
Какое счастье, что я сделал сворачивание огромных блоков кода!
[/offtop]

Что-то в примерах только С++, а в названии книжки и С есть. Или это не так?

Anon
()
Ответ на: комментарий от anonymous

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

Я уж и не помню где я чем хвастался, но я откровенно могу заявить, что в состоянии анализировать только то, что у меня влезает на экран в настоящий момент;-(

Популярность функциональных языков, ИМХО, движется не в последнюю очередь теми, кто не осилил нормальный дизайн на объектно-ориентированных.

Популярность ФП двигается исключительно ее удобством (возможностью писать 1 строку там, где в ООП стиле пришлось бы лепить 10). С тем же успехом можно сказать, что популярность станков с ЧПУ обусловлена большим числом неасиляторов, не способных работать на обычном токарном-фрезеровочном и т.д.;-)))

Но это не значит, что ФП серебряная пуля - есть места где все с точностью до наоборот.

AIv ★★★★★
()

Вопервых говно - никакае «тёмные углы сишки» ты не раскрыл, ибо ты её тупо не осилил. Половина примеров с банальными фейлами аля 377 и прочее.

Выпили из названия Си, заменив его «неочевидны для анскильных крестовиков отличия Си и крестов».

Да и про плюсы это не дарсайд, а банальности в 70% случаев - в остальных особенности гнилого недоООП, которое нормально на матчасть не ложится и у крестов с этим постоянные проблемы.

Да и вся эта болтавня про уб бесполезна в реальном мире. Если продолжать эту болтологию, то в сишке вообще всё уб для плюсовика и неосилятора.

И да, С89 не нужно и протухло уже давно, дефолтная сишка не нужна - уже лет 100 как есть вменяемые диалекты от фичей которых у плюсовиков будет бомбить ещё больше. А так для тех, кто до сих пор в каменном веке в самый раз.

anonymous
()
Ответ на: комментарий от AIv

Копипасту, хоть ручную, хоть автоматическую считать, конечно, не надо.

отсюда следует что вообще не бывает сложных числодробилок

С точки зрения software engineering — да. Поэтому их принято писать на фортране.

Для выжимания последних капель производительности вы можете в этих нескольких тысячах строк швыряться указателями направо, налево и по кругу, можете лезть грязными руками внутрь структур... и при этом ужерживать все эти хаки в голове чтобы ничего не сломать. Зачем пытаться оборачивать их в абстракции (которые, к тому же, судя по вашим тредам, весьма прилично текут)? Не понимаю. Советую вспомнить народную мудрость: «программист на фортране может писать на фортране с использованием любого языка программирования». ИМХО это будет эффективнее (во многих смыслах) всего.

возможностью писать 1 строку там, где в ООП стиле пришлось бы лепить 10

Это касается только факториалов. Кому-то рядом с ЧПУ стоять, а кому-то писать для него софт...

anonymous
()

Спасибо, почитаю.

Скорее всего, найду для себя что-нибудь новое.

З.Ы.: А на комментарии не обращай внимания, здесь это обычное дело...

solovey ★★
()
Ответ на: комментарий от anonymous

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

Там до последних капель производительности как до луны пешком - обычная шблонно-плюсовая лапша, которая бездумно и хрен знает зачем лепится. Тотальное неосиляторство конпеляторов, их возможностей и прочего пораждает мифы и легенды про то, что шаблонный аргумент лучше константного и прочее. Или там во что ещё плюсовики верят - во всякие move, ссылки, константность и прочий бесполезный бред.

Указатели он не осилил - он лепит форановскую, бездарную тормазную лапшу на форах и счётчиках.

Глупая неосиляторская вера в ООП/кресты и их компактность, которая на самом деле на днище морском.

Советую вспомнить народную мудрость: «программист на фортране может писать на фортране с использованием любого языка программирования». ИМХО это будет эффективнее (во многих смыслах) всего.

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

Это касается только факториалов. Кому-то рядом с ЧПУ стоять, а кому-то писать для него софт...

Лучшеб не писали. Это образец тотальной бездарности.

anonymous
()
Ответ на: комментарий от anonymous

друг, попробуй сформулировать основные черты своего стиля, или по крайней мере три ключевых слова, по которым твое творчество распознается из-под анонимуса уже начиная с первого абзаца :3

stevejobs ★★★★☆
()
Ответ на: комментарий от stevejobs

но под Вендой MS забило на C99 когда ты еще тёлочек за косы дергал

Зачем это говно нужно мне, как илите сишкамира? Для неё есть вы и всякие с89 анскильности, которые даже указаетли не осилили.

Я буду ещё про каждое говнецо думать, может мне ещё о тебе подумать, что типа ты не осилишь читать мой код и не юзать 99% фич? Как собственно вы и делаете.

Я клал на твою венду ещё тогда, когда ты своим тёлочкам хвосты крутил и подстол пешком ходил.

anonymous
()
Ответ на: комментарий от AIv

так вот ворд это инструмент для написания служебных записок. Для написания таких текстов инструментом является LaTeX

Давай свой модуль для русского интаксиса и грамматики в латехе. TITS OR GTFO.

Олсо, начерта вы используете этот LaTeX? Почему не кошерный TeX?

stevejobs ★★★★☆
()
Ответ на: ЯННП от anonymous

какой же ты анонимус, если тебя с третьей строчки видно? Давай рассказывай, как нужно писать тексты, чтобы каждый Семен мог стать тобой, тогда и поговорим как анонимус с анонимусом

stevejobs ★★★★☆
()
Ответ на: комментарий от anonymous

Настоящие си-лорды, прошаренные в кроссплатформенности, тестирующие коды для микроволновки на спутниках, рядом срать постремаются с таким платформо-залоченным кул-фиче-холопом

stevejobs ★★★★☆
()
Ответ на: комментарий от asaw

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

unt1tled ★★★★
()
Ответ на: комментарий от anonymous

дефолтная сишка не нужна - уже лет 100 как есть вменяемые диалекты от фичей которых у плюсовиков будет бомбить ещё больше.

Примеры можно?

DarkEld3r ★★★★★
()
Ответ на: комментарий от stevejobs

Настоящие си-лорды, прошаренные в кроссплатформенности

Ты перепутал заедушных животных с кем-то. И ты перепутал хардварную платформу с софтварной, глупая софтварная балаболка.

рядом срать постремаются с таким платформо-залоченным кул-фиче-холопом

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

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

Гдеж код твоих «лордов»? Я жду пхп на восьмибитке.

anonymous
()
Ответ на: комментарий от anonymous

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

не протягивай мне больше, пожайлуйста, свои влажные фантазии, не хотелось бы зашквариться

платформа, которая выполняется прямо на процессоре - это жава, а ты даже не чииал стандарт, если не понимаешь как работает переносимость. Глупые мартышки научились рисовать на айпаде, скоро так же вслепую без стандарта научатся тыкать кнопки в конпеляторе, и всех скиллованных на бездумных кулфичах индусов выбросят в безвоздушное пространство. А нормальные чуваки будут кодить на нормальных языках со статическими проверками, тайпклассами, IDE итп, а ваше крестоговно отправится получать Премию Дарвина

Я жду пхп на восьмибитке

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

stevejobs ★★★★☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.