IME основная проблема многих проектов заключается в том, что разработчики используют низкоуровневые библиотеки. особенности C ++, такие как ручное управление памятью, обработка строк в стиле C и т. д., хотя они очень редко когда-либо необходимы (и тогда только хорошо инкапсулируются в классы). Это приводит к повреждению памяти, недействительным указателям, переполнению буфера, утечкам ресурсов и многому другому. При этом доступны красивые и чистые конструкции высокого уровня.
Я был частью команды для большого (несколько MLoC) приложения в течение нескольких лет, и количество сбоев в работе различных частей приложения хорошо коррелировало со стилем программирования, используемым в этих частях. На вопрос, почему они не меняют свой стиль программирования, некоторые из виновников ответили, что их стиль в целом дает больше производительности. (Это не только неправильно, но также факт, что клиенты предпочитают более стабильную, но более медленную программу, чем быструю, которая постоянно дает сбой. Кроме того, большая часть их кода даже не требовала быстрой работы ...)
Что касается многопоточности: я не чувствую себя достаточно экспертом, чтобы предлагать здесь решения, но я думаю Herb Sutter ' ■ Столбцы «Эффективный параллелизм» очень полезны для чтения по этой теме.
Отредактируйте, чтобы учесть обсуждения в комментариях :
Я не писал, что «обработка строк в стиле C не более производительна». (Конечно, в этом предложении много отрицания, но, поскольку я чувствую себя неправильно понятым, я стараюсь быть точным.) Я сказал, что конструкции высокого уровня в целом не менее эффективны: std :: vector
isn ' t в целом медленнее, чем выполнение вручную динамически выделяемых массивов C, поскольку это динамически выделяемый массив C. Конечно, бывают случаи, когда что-то, закодированное в соответствии с особыми требованиями, будет работать лучше, чем любое общее решение - , но это не обязательно означает, что вам придется прибегать к ручному управлению памятью . Вот почему я написал, что если такие вещи необходимы, то только хорошо инкапсулированные в классы.
Но что еще важнее: в большинстве случаев разница не имеет значения. Удерживает ли кнопка нажатие 0,01 секунды после того, как кто-то ее нажал, или 0,05 секунды, просто не имеет значения, поэтому даже 5-кратное увеличение скорости не имеет значения в коде кнопки. Однако имеет значение , всегда ли происходит сбой кода.
Подводя итог моему аргументу: сначала заставьте его работать правильно. Лучше всего это делать, используя хорошо зарекомендовавшие себя готовые строительные блоки. Затем измерьте. Затем улучшайте производительность там, где это важно, используя проверенные стандартные идиомы.
01 секунда после того, как кто-то нажал на нее, или 0,05 секунды просто не имеет значения, поэтому даже 5-кратное увеличение скорости не имеет значения в коде кнопки. Однако имеет значение , всегда ли происходит сбой кода.Подводя итог моему аргументу: сначала заставьте его работать правильно. Лучше всего это делать, используя хорошо зарекомендовавшие себя готовые строительные блоки. Затем измерьте. Затем улучшайте производительность там, где это важно, используя проверенные стандартные идиомы.
01 секунда после того, как кто-то нажал на нее, или 0,05 секунды просто не имеет значения, поэтому даже 5-кратное увеличение скорости не имеет значения в коде кнопки. Однако имеет значение , всегда ли происходит сбой кода.Подводя итог моему аргументу: сначала заставьте его работать правильно. Лучше всего это делать, используя хорошо зарекомендовавшие себя готовые строительные блоки. Затем измерьте. Затем улучшайте производительность там, где это важно, используя проверенные стандартные идиомы.
используя хорошо зарекомендовавшие себя готовые идиомы. используя хорошо зарекомендовавшие себя готовые идиомы.На самом деле я собирался опубликовать вопрос, который задавал прямо противоположный - считают ли другие, как и я, что вы почти не тратите время на использование отладчика при работе с C ++? Честно говоря, я не могу вспомнить, когда в последний раз пользовался им - должно быть, около полугода назад.
Честно говоря, если вы проводите большую часть времени в отладчике, я думаю, что что-то очень не так с вашими основными методами программирования.
Если вы действительно находитесь в ситуации, когда у вас уже есть плохой код, который ломается, лучший план, вероятно, состоит в том, чтобы задействовать как можно больше инструментов (проверка памяти на уровне ОС / библиотеки, автоматическое тестирование, ведение журнала, дампы ядра и т. д.), чтобы найти проблемные области. Затем перепишите код, чтобы сделать что-нибудь более детерминированное. Большинство ошибок возникает из-за того, что люди делают то, что в большинстве случаев работает, но C ++ предлагает более надежные гарантии, если вы используете правильные инструменты и подходы.
Еще не видел этого упомянутого:
только 3, о которых я могу думать в данный момент ... могу отредактировать позже :)
бесконечная рекурсия
несовпадение версий динамических библиотек
На самом деле это не проблема C ++, но наблюдается в проекте C / C ++.
Самой сложной проблемой, с которой мне пришлось столкнуться, была проблема инициализации при запуске ОС на нашей платформе, которая приводила к необычные сбои. Потребовались годы, прежде чем мы узнали, что произошло. До этого мы запускали систему в течение ночи, и если она не вылетала, значит, нормально. К счастью, ОС больше не продается.
Условия гонки.
Это одна из немногих вещей, от которых у меня все еще дрожит голова, когда она возникает при отладке (или в системе отслеживания проблем). По сути, ужасно отлаживать и очень легко создавать. Три наиболее распространенных причины ошибок в моем программном обеспечении на C ++ - это состояние гонки, зависимость от неинициализированной памяти и
адреса и память, используемые до выделения или после освобождения, ошибки сегментации, arrayoutofbounds, смещение, блокировки потоков, непонятная перегрузка оператора, встроенная сборка, void exit и void в целом, когда требуются возвращаемые значения, усложняет, когда функции math.h заслуживают внимания, поскольку все функции math.h имеют рабочие аргументы и возвращаемые значения по сравнению с другими библиотеками, чрезмерно недействительными, тесты на пустоту , нули, нули и пустоты. Я рекомендую 4 общих соглашения: возвращаемые значения, аргументы, троичный выбор и обратимые изменения. Неисправности, которых следует избегать, являются векторы (вместо этого используйте массивы), пустые с пустыми аргументами, и, по моему субъективному мнению, я избегаю оператора switch в пользу более понятного или читаемого if ... elseif или более абстрактного "is".
C ++ также имеет довольно плохую прямую совместимость по сравнению со сценариями и интерпретируемыми, чтобы попробовать Java десятилетней давности, он все еще работает без изменений и безопасно в более поздних версиях vm.
void exit и void в целом, когда желательны возвращаемые значения, усложняет, когда функции math.h заслуживают внимания, поскольку все функции math.h имеют как рабочие аргументы, так и возвращаемые значения по сравнению с другими библиотеками, чрезмерно недействительными, тестами на пустоту, nils, nulls и voids. Я рекомендую 4 общих соглашения: возвращаемые значения, аргументы, троичный выбор и обратимые изменения. Неисправности, которых следует избегать, являются векторы (вместо этого используйте массивы), пустые с пустыми аргументами, и, по моему субъективному мнению, я избегаю оператора switch в пользу более понятного или читаемого if ... elseif или более абстрактного "is".C ++ также имеет довольно плохую прямую совместимость по сравнению со сценариями и интерпретируемыми, чтобы попробовать Java десятилетней давности, он все еще работает без изменений и безопасно в более поздних версиях vm.
void exit и void в целом, когда желательны возвращаемые значения, усложняет, когда функции math.h заслуживают внимания, поскольку все функции math.h имеют как рабочие аргументы, так и возвращаемые значения по сравнению с другими библиотеками, чрезмерно недействительными, тестами на пустоту, nils, nulls и voids. Я рекомендую 4 общих соглашения: возвращаемые значения, аргументы, троичный выбор и обратимые изменения. Неисправности, которых следует избегать, являются векторы (вместо этого используйте массивы), пустые с пустыми аргументами, и, по моему субъективному мнению, я избегаю оператора switch в пользу более понятного или читаемого if ... elseif или более абстрактного "is".C ++ также имеет довольно плохую прямую совместимость по сравнению со сценариями и интерпретируемыми, чтобы попробовать Java десятилетней давности, он все еще работает без изменений и безопасно в более поздних версиях vm.
На функции h стоит обратить внимание, поскольку все функции math.h имеют как рабочие аргументы, так и возвращаемые значения по сравнению с другими библиотеками, чрезмерно недействительными, тестами на пустоту, nils, nulls и void. Я рекомендую 4 общих соглашения: возвращаемые значения, аргументы, троичный выбор и обратимые изменения. Неисправности, которых следует избегать, являются векторы (вместо этого используйте массивы), пустые с пустыми аргументами, и, по моему субъективному мнению, я избегаю оператора switch в пользу более понятного или читаемого if ... elseif или более абстрактного "is".C ++ также имеет довольно плохую прямую совместимость по сравнению со сценариями и интерпретируемыми, чтобы попробовать Java десятилетней давности, он все еще работает без изменений и безопасно в более поздних версиях vm.
На функции h стоит обратить внимание, поскольку все функции math.h имеют как рабочие аргументы, так и возвращаемые значения по сравнению с другими библиотеками, чрезмерно недействительными, тестами на пустоту, nils, nulls и void. Я рекомендую 4 общих соглашения: возвращаемые значения, аргументы, троичный выбор и обратимые изменения. Неисправности, которых следует избегать, являются векторы (вместо этого используйте массивы), пустые с пустыми аргументами, и, по моему субъективному мнению, я избегаю оператора switch в пользу более понятного или читаемого if ... elseif или более абстрактного "is".C ++ также имеет довольно плохую прямую совместимость по сравнению со сценариями и интерпретируемыми, чтобы попробовать Java десятилетней давности, он все еще работает без изменений и безопасно в более поздних версиях vm.
Я рекомендую 4 общих соглашения: возвращаемые значения, аргументы, троичный выбор и обратимые изменения. Неисправности, которых следует избегать, являются векторы (вместо этого используйте массивы), пустые с пустыми аргументами, и, по моему субъективному мнению, я избегаю оператора switch в пользу более понятного или читаемого if ... elseif или более абстрактного "is".C ++ также имеет довольно плохую прямую совместимость по сравнению со сценариями и интерпретируемыми, чтобы попробовать Java десятилетней давности, он все еще работает без изменений и безопасно в более поздних версиях vm.
Я рекомендую 4 общих соглашения: возвращаемые значения, аргументы, троичный выбор и обратимые изменения. Неисправности, которых следует избегать, являются векторы (вместо этого используйте массивы), пустые с пустыми аргументами, и, по моему субъективному мнению, я избегаю оператора switch в пользу более понятного или читаемого if ... elseif или более абстрактного "is".C ++ также имеет довольно плохую прямую совместимость по сравнению со сценариями и интерпретируемыми, чтобы попробовать Java десятилетней давности, он все еще работает без изменений и безопасно в более поздних версиях vm.