da hier sonst kaum jemand antwortet...vorab: ich bin nichtakademischer "Hobbyist" mit wenig erfahrung, kein experte...leg' nicht zuviel gewicht darauf was ich hier schwätze, ich hab' einfach langeweile... 😉
zunächst einmal muss man sehen, dass die open source/gnu/linux welt stark aufbauend auf bibliotheken ist. für jedes anwendungsgebiet gibt's quasi schon eine bibliothek, die einen gewissen funktionsumfang bereitstellt oder vereinfacht. anders als in der kommerziellen welt, wo man (wohl) lieber alles aus eigener hand macht, oder gekaufte lösungen mit dem produkt gleich mitliefert, gibt es innerhalb dieses speziellen kosmoses keine rechtlichen/finanziellen hürden, und es ist sogar erwünscht, im funktionsumfang möglichst wenig redundanzen und bibliothekskonflikte zu erzeugen. zumal die entwickler recht viel zeit und energie sparen können, wenn sie sich in bezug auf bestimmte funktionalitäten ihres programmes auf die betreuer der jeweilig dafür genutzten komponenten verlassen: hier klappt das zusammenspiel oft überraschend gut!
wenn nun jemand eine bibliothek bereitstellt, die einen begrenzten funktionsumfang für die eigentlichen anwendungen anbieten soll, so will derjenige natürlich, dass sie nicht nur unter c++ funktioniert, sondern auch unter reinem c, python, java, scala, ruby, assembler (für masochisten oder sudoku-fans...) und unter was nicht allem sonst noch, das genutzt werden kann, um programmlogiken zu definieren. dafür eignet sich nunmal reines c am allerbesten:
die programmiersprache c ist, wie du selbst schon angemerkt hast, sehr einfach gehalten in ihren sprachlichen werkzeugen, aber dabei durchaus mächtig. sie spiegelt den programmablauf im eigentlich ausgeführten maschinencode sehr gut wieder: es gibt wenig impliziertes verhalten - aus meiner sicht neben der eigentlichen übersetzung in maschinensprache samt optimierungen nur in etwa das, was die genutzen bibliotheken im hintergrund machen und die "calling convention" zwischen bibliotheks-/funktionsaufrufen. deswegen ist es sehr leicht, c-programme oder -bibliotheken auch in andere sprachen zu übernehmen, auch wenn deren grundkonzepte die objektorientierte programmierung nicht beinhalten.
c++ wiederum ist wie ein c, dass man um gewisse implikationen und stilmittel erweitert hat, um den eigentlichen akt der programmierung von mittleren bis grossen systemen zu beschleunigen und zu vereinfachen: templates (stark verbesserter macro-mechanismus um grundkonzepte mit einem schlag auf verschiedene anwendungsgebiete zu bringen), klassen und vererbung (vereinfachen objektorientiertes programmieren immens), operatoren und overloading (vereinfachen stark den quelltext in vielen anwendungsgebieten, auch die verständlichkeit dessen), namespaces (halten den raum für eindeutige variablen/funktionsnamen frei, wo man unter reinem c immer diffenrenzieren musste) und zuguterletzt ganz andere standardbibliotheken und die standard-templates, die oft genutzte standardfunktionen, und auch dinge, die man unter c von hand oder mit drittbibliotheken machen musste, in einer art und weise verpacken, die eine ganz andere programmierphilosophie wiederspiegeln als bei reinem c.
dabei kann man durchaus unter "c++" auch im c-stil programmieren, und auch die ganzen standardbibliotheken von c problemlos nutzen - haarspalter und puristen werden dann immer im sinne der portablität und sprachreinheit meckern, aber: "es funktioniert". wobei es dann natürlich immer den "nachteil" des "name-mangling" gibt, der wohl auch mit einer der gründe ist, dass grundbibliotheken eher in c als in c++ gehalten werden, um die anbindung zu vereinfachen.
genauso kann man eigentlich alles, was in c++ möglich ist, auch in c umsetzen. auch objektorientierte programmierung mit allen feinheiten. man muss nur eben wesentlich mehr fussarbeit leisten, und der code selbst wird schnell unübersichtlich und unintuitiv, und ausserdem von der textmenge her für aussenseiter/neueinsteiger des projektes unverständlich ohne lange, mühsame einarbeitung.
deswegen ist es oft so, dass c-bibliotheken von c++ "end"-anwendungen genutzt werden. die grundfunktionalitäten, die oft nicht so überragend komplex sind, dass sie erweiterte oder komplexe objektorientierung benötigten fliessen so in ein komplexeres rahmenwerk ein, dass die eigentliche anwendung darstellt. für viele populäre (c)-bibliotheken gibt es zudem c++-übersetzungsbibliotheken ("c++ wrapper"), die die funktionalität der bibliothek in mehr oder weniger guter objektorientierter c++-mentalität wiederspiegeln, so dass das c++ projekt nichtmal stilistisch auf dem "prozeduralen" pfad zwischenschritte machen muss. in den meisten einfacheren fällen, die mir bis jetzt so unter die augen gekommen sind, werden aber c-bibliotheken im c-stil benutzt, und in die objektorientierung eingegliedert: das ist ja das schöne, es schliesst sich nichts gegenseitig aus. je komplexer der zusammenhang aber ist (z.b. gtk als "komplexe" bibliothek gegen sowas wie libsndfile als "schlichter spezielfunktionsbereitsteller"), desto eher werden c++ programmierer danach trachten, die funktionalität der bibliothek im c++-stil in ihre anwendung zu integrieren.
aber abseits davon sehe ich das mitlerweile so, dass die sprache fast egal ist...die funktionskonzepte in der "maschine", die man zusammenbaut sind viel wichtiger! und nicht nur wie sie eigentlich funktioniert, sondern auch wie man den bauplan (= quellcode, build-environment...) organisiert. da steckt meiner ansicht nach, neben der erfindung von besonders effizienten algorithmen für bestimmte problemlösungen, das hauptgenie eines wirklich guten programmierers. und das kriegt man selten gut vermittelt. ich denke etwa 60% an der arbeit an einem etwas grösseren programm sind schon getan, wenn man programmstruktur, schnittstellen und modularisierung sauber durchgeplant hat. tut man's nicht, und hackt einfach d'rauf los, erlebt man schnell frustrationen und überraschungen, und muss die planungsarbeit im zweifel "am lebenden objekt" nachholen, mit allen kompromissen, neuanpassungsarbeit und zeitverlust, der damit verbunden ist.