Найгірші практики C ++, поширені помилки [закрито]


35

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

Я також вітаю відповіді, вказуючи на величезне зниження продуктивності, де цього зазвичай не очікували. Приклад того, що один з моїх професорів одного разу розповів мені про генератор парсерів LR (1), який я написав:

Ви використовували дещо занадто багато випадків зайвого успадкування та віртуальності. Спадкування робить дизайн набагато складнішим (і неефективним через підсистему RTTI (тип виводу під час виконання)), і тому його слід використовувати лише там, де це має сенс, наприклад, для дій в таблиці розбору. Оскільки ви інтенсивно використовуєте шаблони, вам практично не потрібно спадкування ".


6
Деякі з більш неприємних помилок, які ви можете зробити в C / C ++, здебільшого пов’язані зі спадщиною С ... читайте не визначене поведінку, ручне управління пам’яттю тощо. Порада професора здається неправдивою / неправильною (для мене хто не експерт C ++) - інстанція шаблону повинна дати нормальний клас з vtable для virtualфункцій, правда?

8
Ви або неправильно пам'ятаєте, що сказав ваш професор, або він не мав поняття, про що він говорив. Отримані класи зазвичай не потребують використання RTTI (відображення AKA) для пошуку речей. Якщо вони використовують віртуальні методи, код може знадобитися зробити vtable пошук для відправки, але це перекладається на одну інструкцію ASM для багатьох процесорів. Через проблеми з кешуванням це може сповільнити роботу на певну кількість, але ви навряд чи коли-небудь помітите накладні витрати під будь-якими, але найвибагливішими випадками використання. Існує маса вагомих причин уникати C ++, але стійкі пошуки - це не одна з них.
Мейсон Уілер

5
@FelixDombek: Заявлений настільки загально і застосовується в усьому плані, що цитата вашого професора просто показує величезну кількість незнання. Коли ваш дизайн потребує певного поліморфізму виконання, найчастіше найкращим вибором є використання віртуальних функцій; коли він вам не потрібен, не використовуйте його: вам не потрібні всі методи, щоб бути віртуальними лише тому, що ви використовуєте похідні класи, наприклад.
Фред Нурк

5
@ Mason Wheeler: RTTI містить інформацію про тип, достатню для того, щоб можна було визначити, чи dynamic_castповинен успіх чи ні, та ще декілька речей, але рефлексія охоплює набагато більше, включаючи можливість отримання інформації про атрибути або функції члена, тобто не присутній в C ++.
David Rodríguez - dribeas

5
Коментар професора дещо обманює, оскільки успадкування та віртуальні функції не є великим хітом продуктивності. Рада використовувати спадщину економно, але це швидше проблема структури програми, ніж ефективності. Спадщина, особливо із захищеними членами, приблизно настільки близька, як ви збираєтеся отримати, і якщо вона вам не потрібна, ви не повинні її використовувати.
Девід Торнлі

Відповіді:


69

Торвальдс тут розмовляє зі своєї дупи.


Добре, чому він розмовляє зі своєї дупи:

Перш за все, його зухвалість насправді нічим не буває. Тут дуже мало фактичного вмісту. Єдина причина, яку він справді знаменитий або навіть м'яко поважають, це те, що його зробив Бог Linux. Його головний аргумент полягає в тому, що C ++ - це лайно, і він любить дратувати C ++ людей. Звичайно, взагалі немає причин на це відповідати, і той, хто вважає це розумним аргументом, все одно не підходить для розмови.

Щодо того, що може бути сприйнято як його найбільш об'єктивні моменти:

  • STL і Boost - це суцільне лайно <- що завгодно. Ви ідіот.
  • STL і Boost викликають нескінченну кількість болю <- смішно. Очевидно, що він, мабуть, перебільшує, але тоді яка його реальна заява тут? Не знаю. Виявляти проблеми, які викликають компілятор у блюзніжці Духа чи щось подібне, є більш ніж тривіально складне, але це не більш-менш складно розібратися, ніж налагодження UB, викликане неправильним використанням конструкцій C, таких як void *.
  • Абстрактні моделі, які заохочуються C ++, неефективні. <- Як що? Він ніколи не розширюється, ніколи не надає прикладів того, що він має на увазі, він просто це говорить. BFD. Оскільки я не можу сказати, на що він має на увазі, немає сенсу намагатися "спростувати" заяву. Це звичайна мантра С-фанатів, але це не робить його більш зрозумілим або зрозумілим.
  • Правильне використання C ++ означає, що ви обмежуєте себе аспектами C. <- Насправді код WORSE C ++ там робить це, тому я досі не знаю, про який він говорить.

В основному Торвальдс розмовляє зі своєї дупи. Ні про що не можна робити жодних зрозумілих аргументів. Очікувати серйозного спростування такої дурниці просто нерозумно. Мені кажуть "розширити" на спростування чогось, на що я б очікував розширити, якби там, де я, хто це сказав. Якщо ви справді, чесно подивіться на те, що Торвальдс сказав, ви побачите, що він насправді нічого не сказав.

Просто тому, що Бог каже, що це не означає, що це має сенс або його слід сприймати серйозніше, ніж якби це сказав якийсь випадковий бозо. Правду кажучи, Бог - це ще один випадковий бозо.


Відповідаючи на власне питання:

Мабуть, найгірша, і найпоширеніша, погана практика C ++ - це поводитися з нею як C. Постійне використання функцій API API, таких як printf, отримує (також вважається поганим у C), strtok тощо. системою жорсткішого типу вони неминуче призводять до подальших ускладнень при спробі взаємодії з "реальним" кодом C ++. Тож, в основному, робіть прямо протилежне тому, що радить Торвальдс.

Навчіться використовувати STL та Boost, щоб отримати подальше виявлення помилок у часі та полегшити ваше життя іншими, загальними способами (наприклад, токенізатор підсилення як безпечний, так і кращий інтерфейс). Це правда, що вам доведеться навчитися читати помилки шаблону, що спочатку лякає, але (на моєму досвіді) це відверто набагато простіше, ніж намагатися налагодити щось, що породжує невизначене поведінку під час виконання, що робить C api досить легко зробити.

Не сказати, що C не так добре. Я звичайно люблю C ++ краще. Програмістам на C подобається C краще. У грі є компроміси та суб'єктивні симпатії. Тут також багато дезінформації та FUD. Я б сказав, що навколо С ++ летить більше FUD та дезінформація, але я упереджений у цьому плані. Наприклад, проблеми C ++, які нібито не виникають, є фактично не основними проблемами більшості часу і, безумовно, вибухають із пропорцій реальності.

Що стосується питань, які стосується ваш професор, вони не характерні лише для C ++. В OOP (і в загальному програмуванні) ви хочете віддати перевагу складу над спадщиною. Спадщина - це найсильніший можливий зв'язок, який існує у всіх мовах ОО. C ++ додає ще одне, що сильніше, дружба. Поліморфне успадкування має використовуватися для представлення абстракцій та відносин "є-а", його ніколи не слід використовувати для повторного використання. Це друга найбільша помилка, яку ви можете зробити в C ++, і вона досить велика, але мова далеко не унікальна. Ви також можете створити надто складні відносини успадкування в C # або Java, і вони матимуть однакові проблеми.


1
Іронічно, як і після 2007 року, git працював лише з портативними версіями Linux. Ну, будь-яка система, яка була однаковою. Потім знову, враховуючи обставини, що призвели до створення git, я, безумовно, не проти цього.
Кріс К

9
Лінусу важко знайти будь-яких хороших програмістів на C ++, які хочуть працювати на нього. Цікаво, чому? Я думаю, що це лише проблема куряче-яєчного типу.
Бо Персон

19

Я завжди вважав, що небезпеки C ++ сильно перебільшені недосвідченими, C із програмістами класів.

Так, C ++ важче підібрати, ніж щось на кшталт Java, але якщо ви програмуєте за допомогою сучасних методик, писати надійні програми досить просто. Я чесно не що набагато складніше з часу програмування на мові C ++ , ніж я в таких мовах , як Java, і я часто НЕ хапаю певні C ++ абстракцій , як шаблони і RAII , коли я проектую на інших мовах.

Однак, навіть через роки програмування на C ++, раз у раз я зроблю справді тупу помилку, яка не могла б бути вищою мовою. Один з загальних проблем в C ++ - це ігнорування терміну експлуатації об'єктів: у Java та C # вам, як правило, не потрібно піклуватися про термін експлуатації об’єктів *, оскільки всі об’єкти існують у купі, і ними керує магічний сміттєзбірник.

Зараз, у сучасних C ++, зазвичай, вам також не потрібно особливо дбати про життєвий час об'єкта. У вас є деструктори та розумні покажчики, які керують терміном експлуатації об'єктів для вас. 99% часу це чудово працює. Але раз у раз ви будете накручені висячим покажчиком (або посиланням.) Наприклад, нещодавно у мене був об'єкт (назвемо його Foo), який містив внутрішню змінну посилання на інший об’єкт (назвемо його Bar). В один момент я тупо впорядкував речі так, що раніше Barвиходив за межі сфери Foo, але Fooдеструктор в кінцевому підсумку викликав функцію члена Bar. Потрібно сказати, що все не вийшло добре.

Тепер я не можу реально звинувачувати C ++ у цьому. Це був мій власний поганий дизайн, але справа в тому, що подібні речі не відбудуться на мові вищого рівня, керованою. Навіть із розумними покажчиками тощо, вам іноді все одно потрібно знати про життєвий час об'єкта.


* Якщо керованим ресурсом є пам'ять, тобто.


8
Ніколи насправді не потрібно піклуватися про тривалість життя об’єктів на Java та C #? Їх GC піклується про пам’ять, але це лише мала частина RAII для мене; подивіться, наприклад, різні "одноразові" інтерфейси, якими є ці мови, наприклад.
Фред Нурк

Маючи піклуватися про життя об'єкта буде рідко в Java для незручного дизайну своєї бібліотеки введення / виведення за винятком.
dan04

Ваше запитання, що звисає, - це те, що я хочу намагатися вирішити. Я розпочав дискусію у своєму блозі про напрямок, який я очолюю для її вирішення (вказівник обіцяє). В основному, я думаю, що мова може використовувати ще кілька розумних покажчиків. Приймайте участь у цій дискусії, якщо вам цікаво. Ніхто інший не був таким будь-яким ... але якщо це щось, що ви хотіли б побачити вирішеним ... Я насправді стикаюся з проблемою набагато більше 10% часу.
Едвард Странд

13

Різниця в коді зазвичай більше пов'язана з програмістом, ніж з мовою. Зокрема, і хороший програміст на C ++, і програміст на C будуть приймати аналогічні хороші (навіть якщо різні) рішення. Тепер, C - простіша мова (як мова), і це означає, що менше абстракцій і більшої наочності того, що насправді робить код.

Частина його сказу (він відомий своїми знущаннями проти C ++) ґрунтується на тому, що більше людей приймуть C ++ і пишуть код, не розуміючи, що деякі з абстракцій ховають і роблять неправильні припущення.


3
Яка вартість ітерації над std::vector<bool>зміною кожного значення? for ( std::vector<bool>::iterator it = v.begin(), end = v.end(); it != end; ++it ) { *it = !*it; }? Що абстрагується далеко *it = !*it;?
Девід Родрігес - дрибес

2
Хоча може бути несправедливим вибирати конкретні мовні гидоти, які широко критикуються як помилки ...
Фред Нурк

2
@Fred Nurk: std::vector<bool>це добре відома помилка, але це справді хороший приклад того, про що йде мова: абстракції - це добре, але ви повинні бути обережними, що вони приховують. Те саме може статися і з кодом користувача. Для початку я бачив, як у C ++, так і в Java, які використовують винятки для керування потоком, і код, схожий на виклик функції вкладання, який насправді є пусковим інструментом запуску винятків: void endOperation();реалізований як throw EndOperation;. Хороший програміст уникне цих дивовижних конструкцій, але факт полягає в тому, що ви можете їх знайти.
Девід Родрігес - дрибес

5
Один із моментів Торвальдса полягає в тому, що: він може відігнати початківців, вибираючи C над C ++ (здається, що для початківців більше C ++), а C ++, який є більш складним, має більш круту криву навчання і більше шансів на те, щоб потрапити у кутовий випадок .
David Rodríguez - dribeas

2
+1, саме на це скаржиться Лінус. Він вимикається як анти-C ++, але це насправді не так. Він лише анти-C ++ - програміст.
greyfade

13

Надмірне використання try/catchблоків.

File file("some.txt");
try
{
  /**/

  file.close();
}
catch(std::exception const& e)
{
  file.close();
}

Зазвичай це випливає з таких мов, як Java, і люди будуть стверджувати, що на C ++ відсутнє finalizeзастереження.

Але цей код містить два питання:

  • Потрібно створити fileперед try/catch, тому що ви не можете насправді closeфайлу, який не існує в catch. Це призводить до "витоку сфери", яке fileвидно після закриття. Ви можете додати блок, але ...: /
  • Якщо хтось приходить і додає returnпосеред tryобласті, тоді файл не закривається (саме тому люди сукаться про відсутність finalizeпункту)

Однак у C ++ у нас є набагато ефективніші способи вирішення цього питання, які:

  • Java finalize
  • C # 's using
  • Іди defer

У нас є RAII, дійсно цікаве властивість якого найкраще підсумовується як SBRM(управління масштабними ресурсами).

Створюючи клас так, щоб його деструктор очищав ресурси, якими він володіє, ми не покладаємо на себе управління ресурсом для кожного його користувача!

Це особливість , яку я НЕ вистачає в будь-якому іншому мовою, і , ймовірно, один, найбільш забуте.

Правда полягає в тому, що рідко виникає необхідність навіть писати try/catchблок в C ++, крім верхнього рівня, щоб уникнути припинення без реєстрації.


1
Я не думаю, що це вплив Java настільки, наскільки це є C. (Ви можете безпосередньо замінити fopenі fcloseтут.) RAII - це "правильний" спосіб робити тут справи, але це незручно для людей, які хочуть використовувати бібліотеки C із C ++ .
dan04

Для цього типу відповіді, наводячи приклад правильного рішення, було б доречно.
Клаус Йоргенсен

@ ClausJørgensen: Ну, рішення, на жаль, насправді не є "показовим", оскільки воно передбачає просто, File file("some.txt");і це все (ні open, ні close, ні try...)
Матьє М.

D також має RAII
Demi

@Demetri: Я не надто знайомий з D, чи могли б ви пояснити, як RAII взаємодіє зі збиранням сміття? Я знаю, що в Python можна написати метод "deinit", однак документація попереджає, що у випадку циклу посилань деякі об'єкти не побачать названий метод deinit.
Матьє М.

9

Однією поширеною помилкою, яка відповідає вашим критеріям, є нерозуміння того, як працюють конструктори копій при роботі з виділеною пам’яттю у вашому класі. Я втратив кількість часу, який я витратив на виправлення збоїв або витоків пам'яті, тому що "noob" розмістив свої об'єкти на карті чи векторі та не написав належним чином конструкторів копій та деструкторів.

На жаль, у C ++ повно таких "прихованих" готчей. Але скаржитися на це - це як скаржитися, що ти поїхав до Франції і не розумієш, що люди говорять. Якщо ви збираєтесь туди поїхати, вивчіть мову.


1
Я думаю, що проблема C ++ полягає в тому, що дуже легко стріляти в ногу. Звичайно, навколо є хороші програмісти C ++, багато хорошого програмного забезпечення, написане на C ++. Але дуже складно стати хорошим розробником C ++. Серія "Ефективний C ++" Скотта Майєрса показує, скільки тонкощів має мова.
Марко Мустапік

Я згоден. Частина проблеми полягає в тому, що багато (більшість) програмістів на C ++ думають, що вони знають, що роблять, коли явно цього не роблять. Ви мали на увазі "Ефективний C ++"?
Генрі

Принаймні, це покращується новими досить обмежувальними правилами щодо неявного генерації операцій копіювання / переміщення в C ++ 0x. У багатьох випадках порушення правил, що стосуються трьох правил, неявна генерація копіювальних операцій буде застарілою і повинна попереджати.
sellibitze

6

C ++ дозволяє отримати різноманітні функції та стилі програмування, але це не означає, що це фактично хороші способи використання C ++. А насправді користуватися C ++ невірно просто, неймовірно просто.

Це потрібно засвоїти і зрозуміти належним чином , просто навчання за допомогою (або використання його як би використовували якусь іншу мову) призведе до неефективного та схильного до помилок коду.


4

Ну ... Для початку ви можете прочитати C ++ FAQ Lite

Потім кілька людей побудували кар'єру, пишучи книги про тонкощі C ++:

А саме Герб Саттер і Скотт Мейєрс .

Що стосується нестачі Торвальдса речовини, що не вистачає ... приходьте до людей, серйозно: жодна інша мова там не пролила стільки чорнила, щоб розібратися з нюансами мови. Усі ваші книги Python & Ruby & Java зосереджені на написанні програм ... ваші книги C ++ зосереджені на дурних мовних особливостях / підказках / пастках.


1
Хм ... javapuzzlers.com , jimbrooks.org/web/python/#Pitfalls . Я б сказав, що прискорений C ++ (для одного прикладу) зосереджується набагато більше на тому, як писати код, ніж це робиться ...
Джеррі Коффін

1
Ви зібрали кілька прикладів ресурсів, які вказують крайові випадки на відповідних мовах; речі, які виглядають дивно, і ви не зовсім впевнені, як вони працюватимуть (хоча у списку пітонів близько) ... У C ++ є ціла галузь, яка вказує на речі, які виглядають абсолютно дійсними, але вони ведуть себе так, як ви не очікуєте.
red-dirt

3

Занадто великі шаблони можуть спочатку не призвести до помилок. З часом, однак, людям потрібно буде змінити цей код, і їм буде важко зрозуміти величезний шаблон. Ось тоді вводяться помилки - нерозуміння викликає коментарі "Складається і запускається", які часто призводять до майже-але не зовсім правильного коду.

Як правило, якщо я бачу, як роблю трирівневий глибокий загальний шаблон, зупиняюся і думаю, як це можна звести до одного. Часто проблема вирішується шляхом вилучення функцій або класів.


8
Дотримання складного коду при зміні вимог завжди спричиняє помилки без особливих зусиль, нічого особливого щодо шаблонів там немає.
Фред Нурк

2

Попередження: це не стільки відповідь, скільки критика розмови, з якою "невідомий користувач" пов'язував у своїй відповіді.

Його перший головний пункт - це (нібито) "постійно мінливий стандарт". Насправді приклади, які він наводить, стосуються змін C ++ до того, як існував стандарт. Починаючи з 1998 року (коли був доопрацьований перший стандарт C ++) зміни мови були зовсім мінімальними - насправді багато хто стверджує, що справжньою проблемою є те, що потрібно було внести більше змін. Я абсолютно впевнений, що весь код, який відповідає оригінальному стандарту C ++, все ще відповідає поточному стандарту. Хоча це дещо менш певно, якщо щось не зміниться швидко (і зовсім несподівано), те саме буде в значній мірі і з майбутнім стандартом C ++ (теоретично, весь код, який використовувавсяexportзламається, але практично не існує; з практичної точки зору це не питання). Я можу придумати кілька інших мов, ОС (або багато чого іншого, пов'язаного з комп'ютером), які можуть висловити будь-яку таку заяву.

Потім він переходить у "постійно мінливі стилі". Знову ж таки, більшість його пунктів досить близькі до дурниць. Він намагається охарактеризувати for (int i=0; i<n;i++)як "стару та розбиту" та for (int i(0); i!=n;++i)"нову гарячість". Реальність полягає в тому, що хоча існують типи, для яких такі зміни можуть мати сенс, бо intце не має ніякого значення - і навіть коли ви могли щось отримати, для написання хорошого чи правильного коду рідко потрібно. Навіть у кращому випадку він робить гору з молі.

Наступним його твердженням є те, що C ++ "оптимізується в неправильному напрямку", зокрема, що, хоча він визнає, що використовувати хороші бібліотеки легко, він стверджує, що C ++ "робить написання хороших бібліотек майже неможливим". Тут я вважаю, що це одна з його найбільш фундаментальних помилок. Насправді написати хороші бібліотеки майже для будь-якої мови вкрай складно. Як мінімум, написання гарної бібліотеки вимагає розуміння деякої проблемної області настільки добре, що ваш код працює для безлічі можливих додатків у цьому домені (або пов'язаному з ним). Більшість того, що C ++ насправді робить, - це "підняти планку" - побачивши, наскільки кращою може бути бібліотека , люди рідко хочуть повернутися до написання такого роду шаблонів, які вони мали б інакше.дійсно хороші кодери пишуть досить багато бібліотек, які потім можуть бути використані (легко, як він визнає) "рештою з нас". Це справді випадок, коли "це не помилка, це особливість".

Я не намагатимусь вдарити кожну точку по порядку (це займе сторінки), але переходжу безпосередньо до точки закриття. Він цитує Б'ярна: "Оптимізація всієї програми може бути використана для усунення невикористаних віртуальних таблиць функцій та даних RTTI. Такий аналіз особливо підходить для відносно невеликих програм, які не використовують динамічне посилання".

Він критикує це, висловлюючи непідтримувані твердження, що "Це дійсно важка проблема", навіть порівнюючи це з проблемою зупинки. Насправді це нічого подібного - насправді це зробив линкер, включений до Zortech C ++ (майже перший компілятор C ++ для MS-DOS, ще в 1980-х). Це правда, що важко бути впевненим, що кожен шматочок можливих сторонніх даних був усунений, але все-таки цілком розумно робити досить справедливу роботу.

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

Врешті-решт, це правда, що в цій розпусті є трохи більше речовини, ніж ідіотизм Лінуса, - але це дає йому саме той прокляття з слабкою похвалою, яку вона заслуговує.


1

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

Деякі хіти на продуктивність, які я бачив, зазвичай пов'язані з магічним розподілом пам'яті STL (так, ви можете змінити розподільник, але хто це робить, коли він починає з C ++?). Зазвичай ви чуєте аргументи експертів C ++ про те, що вектори та масиви мають однакову ефективність, оскільки вектори використовують масиви всередині, а абстракція є надзвичайно ефективною. Я виявив це правдою на практиці для доступу до вектора та зміни існуючих значень. Але не вірно для додавання нового входу, будівництва та знищення векторів. gprof показав, що накопичувально 25% часу для програми було витрачено на векторні конструктори, деструктори, memmove (для переміщення всього вектора для додавання нового елемента) та інших перевантажених векторних операторів (як ++).

У цьому ж додатку вектор чогосьМалого був використаний для представлення чогось Великого. Не було потреби у випадковому доступі до чогосьмалого в чомусь великому. Ще замість списку використовувався вектор. Причина, чому використовувався вектор? Тому що оригінальний кодер був знайомий з масивом, як синтаксис векторів, і не дуже добре знайомий з ітераторами, необхідними для списків (так, він із групи C). Далі доводимо, що для того, щоб правильно зрозуміти C ++, потрібно багато рекомендацій експертів. C пропонує настільки мало базових конструкцій, що абсолютно не абстрагуються, що ви зможете зрозуміти це набагато простіше, ніж C ++.


0

Хоча мені подобається Лінус Торвальдс, ця зухвала без суті - просто зухвала.

Якщо вам подобається бачити обґрунтовану сказу, ось ось що: "Чому С ++ шкідливо для навколишнього середовища, спричиняє глобальне потепління та вбиває цуценят" http://chaosradio.ccc.de/camp2007_m4v_1951.html Додатковий матеріал: http: // www .fefe.de / c ++ /

Забавна розмова, імхо


0

STL та прискорення є портативними, на рівні вихідного коду. Я думаю, що Лінус говорить про те, що у C ++ бракує ABI (бінарний інтерфейс програми). Отже, вам потрібно зібрати всі бібліотеки, з якими ви зв’язуєтеся, з тією ж версією компілятора і з тими ж перемикачами, інакше обмежте себе на C ABI на dll-кордонах. Я також вважаю, що це реєструє .. але якщо ви не створюєте сторонні бібліотеки, ви повинні мати можливість взяти під контроль своє середовище збирання. Я вважаю, що обмеження себе на C ABI не варте клопоту. Зручність можливості передачі рядків, векторів та розумних покажчиків з одного dll в інший вартує клопоту з необхідністю відновлення всіх бібліотек під час оновлення компіляторів чи зміни компіляторів компілятора. Золоті правила, яких я дотримуюсь:

-Уміти повторно використовувати інтерфейс, а не реалізацію

-Переглядати агрегацію над успадкуванням

-Зарахуйте, де можливо, безкоштовні функції методам-членам

-Завжди використовуйте ідіому RAII, щоб зробити ваш код сильно винятком безпечним. Уникайте спроб лову.

-Використовуйте розумні покажчики, уникайте голих (невідомих) покажчиків

-Передайте значення семантики значення семантики посилань

-Не вигадуйте колесо, не використовуйте stl та boost

-Використовуйте ідіому Pimpl, щоб приховати приватне та / або надати брандмауер компілятора


-6

Не ставлячи остаточного ;в кінці декларації з клацанням, принаймні в деяких версіях VC.


4
Це, мабуть, дуже поширена помилка для початківців (як це майже все, що хтось ще вивчає основний синтаксис), але чи багато є тих, хто назвав би себе компетентними і все ж вважає цю помилку помітною?
Фред Нурк

1
Написав це лише тому, що компілятор видав вам помилку, яка не мала нічого спільного з відсутністю крапки з комою.
Марко Мустапік

2
так, саме така помилка - це те, що ви отримуєте від компілятора C.
Mircea Chirea
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.