Препроцессор, которым имитируют модульность. Нормальная модульность в языке появилась совсем недавно - комитет по стандартизации много лет демонстративно "не замечал" просьб разработчиков. Препроцессор же - архаизм 1960-х годов, без которого современные языки прекрасно обходятся.
Низкоуровневые механизмы, которые можно бесконтрольно использовать в любом месте кода. В современных языках низкоуровневые механизмы явно отделяются от нормального кода блоками unsafe.
UB. Соглашения, реализованные компиляторами, позволяют наступить на грабли UB в самых неожиданных местах. Такого бреда с "неопределённым поведением", как в C/C++, нет больше ни в одном языке высокого уровня.
Отсутствие ортогональности: язык содержит множество механизмов, делающих одно и то же разными способами. Это очень сильно раздувает язык и резко усложняет изучения зыка. И самое грустное, что этот зоопарк никак не увеличивает область использования языка. Такое ощущение, что в язык бездумно пихают всё, что модно на момент принятия очередного стандарта.
Слишком развесистые средства обобщенного программирования, представляющие собой отдельный тьюринг-полный язык. Фактически, посредством шаблонов можно написать полноценную программу, которая в процессе компиляции будет генерировать код программы. Это очень любит Александреску (который "modern design..."
![Wink ;) ;)](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
. Но читать такой код-годоволомку - занятие для мазохистов.
Множественное наследование, создающее больше проблем, чем решающее. Интерфейсы в более поздних языках обеспечивают намного более надёжную реализацию в точности тех же возможностей.
P.S. Это то, что с ходу вспомнилось.