Självklart är C++ bättre vid OOP än C. Men jag tänkte bara kolla om det finns ett behov utav funktionspekare i strukturer. Bara för att få till en liten enkel OOP-funktion som man gjorde förr på DOOM och Quake spelen.
Ah, då har du bättre syn än mig. Peka gärna ut i Doom koden var de någonstans använder indirekta hopp (funktionspekare). För en sak spel spelprogrammerare och definitivt embedded-programmerare försökte undvika så mycket det bara gick med CPUer från 1990-2000 talens HW var indirekta hopp. Än idag finns det i extrema fall en klar kostnad med indirekta hopp, var det jag belyste med C vs C++ fallet.
Sättet C++ är designat gör att man långt oftare kan undvika indirekta hopp fast ändå ha hög grad av generalism i koden. Det kommer specifikt av någon C++ (och även Rust) har, men C saknar: stöd för generisk programmering där kompilatorn kraftigt utnyttjar den informationen vid optimering (tar man fallet Java saknas i praktiken dessa optimeringsmöjligheter trots språkstödet).
Jag tror fortfarande att Rust är inte framtiden. Varför?
Rust är säkert ett jätte bra språk. Men dessa fina och goda språk dyker upp hela tiden. Det är bara en tidsfråga innan t.ex. Facebook uppfinner ett nytt språk som anses vara bättre än Rust och då minskar Rust's användare där.
Kvar blir C++ som uppdaterar sitt språk under tystnad.
Fast hur kommer du runt en av dina absolut viktigaste käpphästar, "brett industristöd"? C++ ISO-kommittén är väl medveten om fördelar i Rust, inom ramen för att vara bakåtkompatibel har de senaste versionerna fått rejäla förbättringar på flera områden. Ställd mot t.ex. Java och C# tycker i alla fall jag att man egentligen tätat de relevanta fördelarna som tidigare fanns, t.ex. LINQ brukar lyftas fram som "riktigt coolt" vilket C++20 rätt mycket har fått med "ranges" + sättet C++ kan optimera saker vid kompilering gör att det har potential att bli rejält effektivt.
Men en sak varken C++, C#, Java eller något annat språk kan fixa med mindre än att helt bryta bakåtkompatiblitet är detta
use std::thread;
fn main() {
let v = vec![1, 2, 3];
let handle = thread::spawn(|| {
println!("Accessing 'v' here without explicit synchronization is a data-race, it won't compile in Rust! {:?}", v);
});
handle.join().unwrap();
}
use std::thread;
fn main() {
let v = vec![1, 2, 3];
let handle = thread::spawn(move || {
println!("Can access 'v' as ownership is explicitly transfered to this thread {:?}", v);
});
println!("Accessing 'v' here is now a data-race as ownership of 'v' moved to a different thread, won't compile in Rust {:?}", v);
handle.join().unwrap();
}
Jämför det med C++, och fungerar på exakt samma sätt i C11, C#, Java, Python, Go, etc (men inte JS då stöd för trådar saknas där!!!)
#include <fmt/ranges.h>
#include <thread>
#include <vector>
int main() {
std::vector<int> v{1, 2, 3};
std::thread handle{ [&v] () {
fmt::print("Compiles just fine with race... {}\n", v);
} };
fmt::print("Compiles just fine with race... {}\n", v);
handle.join();
}
D.v.s. detta är, än så länge, en unik finess i Rust. Finns språk som har andra lösningar på problemet, t.ex. tror jag Erlang inte heller kan ha race men de löser det på ett betydligt mer ineffektivt sätt.
Och framförallt: C, C++ och Rust är unika i att vara designade som systemspråk, d.v.s. de kan köras helt utan "runtime" vilket är ett krav för att göra OS (och "OS" inkluderar att använda dem direkt på metallen i mikrokontrollers) med dem. Sedan finns varianter av andra språk, finns t.ex. Java med manuell minneshantering samt MicroPython. Men dessa är inte längre standardversioner av resp. språk, de råkar påminna om Java resp. Python. C, C++ och Rust har en "free-standing" variant som del av deras specifikation, är den man kör med för OS etc.
Språk som inte hanterat detta från start har två val: leva med problemet, som är en av de absolut mest kostsamma problem vi har i dagens multi-core värld, eller göra en fork av språket där problemet fixas i en ny och bakåtinkompatibel version. Historien har visat att den typen av fork kan vara förödande, det dödade i praktiken Perl och det tog Python över ett decennium att i någon mån bli av med föregående version.
Vore i praktiken otänkbart för de "stora" språken, d.v.s. C++, C# och Java (JS har som sagt inte just detta problem) att göra en sådan fork. D.v.s. problemet är olösbart där!
Det är inte troligt att förlita sig på några enkla algoritmer för att jämföra C mot C++. Ungefär som fysiker endast befinner sig i linjära dynamiska (matematik) tillstånd för att beräkna på sina formler, utan att ta hänsyn till verkligheten. Jag har kört program gjorda i C och C++ och i praktiken så är dessa program som är gjorda i C, mycket snabbare än program som är gjorda i C++. Jag tycker detta kriteriet räknas.
Inte "Vilket språk gör sortering snabbast?". Detta är irrelevant.
Poängen är inte algoritmen i sig, poängen är att visa typexempel på hur man i vettig C resp. C++ löser den här typen av problem. Och sättet man löser det i C++ leder till att kompilatorn kan göra ett betydligt bättre optimeringsjobb.
Men vore skitkul att lära sig nya infallsvinklar här: då du har egen förstahandsinformation är det ju en smal sak att ge ett eller ett par konkreta exempel. Vill inte tala för andra, men gissar alla som följer tråden skulle uppskatta det
Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer