Just FO with your c++ and stupid article. I've repeated this 1000 times and will repeat again, there's no point in using c++ in 2018 unless you want to be a moron :)
why not use rust? do you want to bring all security vulnerabilities to the internet too? Man these c++ guys haven't learnt a thing from recent vuln facepalm
This brings me back... I was doing this exact sort of stuff at the turn of the century, although admittedly in C - not C++ - and using/linking to the Delphi CGI library.
Actually, this new hip function-as-a-service thing feels a lot like CGI/inetd…
well, at least in terms of not keeping the server process up all the time, only when it's used.
To combine "only running when necessary" and "not restarting for every request when there's a lot of requests", I made a thing: https://github.com/myfreeweb/soad — little wrapper listens on a socket, spawns your server with the socket passed in, terminates the server when there were no new connections in a while, rinse, repeat.
You can check inetd which does exactly that and comes preinstalled and pre activated with Linux installations. Or at lest it was common once upon a time. Don't know if it still is.
That's part of what I'd argue is the main argument against: not reinventing the wheel. The only argument for is experimenting. These are all toy examples. I'd argue that through CGI it won't even be more performant than opcode cached interpreted languages.
Might want to integrate an existing C++ code base into a server without developing an API or IPC in between the two. The security issues would be similar in either case and this would be much quicker to develop.
> Might want to integrate an existing C++ code base into a server without developing an API or IPC in between the two.
Or perhaps you might want to use a belt sander to refinish your table without removing the tablecloth from the table first. Not all the things one “might want to do” are good ideas, even if there’s a wikihow on best ways to do them.
C++ is a great language but it’s a very hard language to wield correctly. The odds there is an exploitable buffer overflow or injection attack buried deep in some part of the code are simply too high compared to memory managed languages with standard libraries designed from the ground up for web-facing applications.
There is almost literally no chance that this is the case. The amount of pointless boilerplate code that you'd have to write would be many, many, many times in excess of a thin API layer.
Rust would be equally unsuitable to this task. Web development in C++ or Rust? Why?
There may be some advantages to writing a middle tier application server in either of these languages, but using a system language to manage a web front-end is effectively like using a hatchet to shave. Sure, the hatchet is faster at cutting wood than a safety razor, and if one is careful, it could be used to remove stubble, but chances are that one is not clearly thinking about the problem at hand to suggest such a tool.
I love the downvotes from the typical HN "Rust for everything" fans. Perhaps try re-reading the comment and understanding that this is not an attack on Rust, but rather a post questioning the use of a system language to build a web front-end.
Why do people think the C++ of today is the same as the C++ of 1998? Today we have concepts such as RAII to clean up our objects when they go out of scope. We have references which are essentially safe pointers to an extent (see dangling references). References have always existed, but people insist on using raw pointers still. Finally, for those use cases where heap allocated memory is absolutely necessary, we have smart pointers which clean up the memory they own when the smart pointer object goes out of scope (an application of RAII). Other unsafe practices carried over from C such as void * type erasure are being replaced with type-safe objects (see std::any for C++17, boost::any for pre-C++17).
I can’t speak for everyone but I think of the C++ of today as being dangerously close to the C++ of 1998 because there is so much 1998 C++ code still being linked into most C++ projects. C++17 is incredibly powerful but it’s also hard to wield correctly and most people don’t have those skills yet (and almost none did while writing that 1998-originated library you eventually find yourself need to use). It’s not just the language that matters, it’s how that language gets used and by whom.
Because Rust lets you hire noobs that don't know what they're doing and contains their damage. C++ is fine if you know what you're doing. It's ridiculous to claim that memory safety is helped by the use of references.
Every programmer who has ever written c++ knows the worst thing to do in 2018 would be to bring c++ to web. All our operating systems are plagued with undefined behaviors and buffer overflows and what not! Let's not use c++ anymore, there are many better alternatives for us :)
Its always interesting to see C++ but as someone else mentioned I expected to see Wt. If I want nearest to C++ speeds I rather go with D (using vibe.d) or Rust. C++ isn't my area of expertise though but those two other languages are years more approachable for me personally. Not saying I could never do C++ though. I know OkCupid is C++ using Wt iirc. I wish they'd give D a try or Rust to see how much more productive they become.
Why would you assume that D or Rust would be make developers more productive? If the developer already knows C++, then switching to D or Rust would make the developer significantly less productive over six months to a year, after which, the developer would likely be just as productive as he/she was when writing C++.
Languages are not panaceas. Rust and D are both hard languages, as is C++. Selecting one of these only makes sense if the application warrants it. Each have advantages and disadvantages. I don't really think any of them are suited to web development, but claiming that D or Rust would be a more productive web development language than C++ seems equally silly to seriously considering C++ as a web development language.
> Why would you assume that D or Rust would be make developers more productive? If the developer already knows C++, then switching to D
Because D is very obviously C++ but better. Rust isn't, though. But D, down to the very name, has lots of things that appeal to C++ users. It has advanced metaprogramming, is multiparadigm, it compiles down to machine code, and has very similar syntax to C++.
D has had other influences, but it is written by C++ compiler writers who think they can do better than C++. I say this as someone raised on C++ and who is now trying D. It is a very natural progression to make, if you're inclined to try something new.
Furthermore, Vibe.d is kind of a burgeoning "killer app" for D. D's package manager, for example, was originally made for Vibe.d. This isn't the only way in which Vibe.d has influenced D development. Vibe.d is one of the most popular D libraries. It's the only D library I know that has its own published book,
The reason that C++ sucks is that it is a FAUX object-oriented language. Many things that you CAN do with an object-oriented language are impossible with C++ (unless you like hackery... no, I don't like hackery).
The reason is purely about runtime speed. At the time that C++ was designed, processors were horribly slow (compared to today's). OOP runtimes were dreadful. So all of the work was put in at compile-time in order to speed up run-time.
Except for one thing. It meant that it was no longer OOP but pseudo-OOP. It kinda-quacked like a duck, kinda-looked like a duck, but really wasn't a duck at all.
For example, one aspect that was ripped from the hands of the developer was the ability to store the address to a function in a variable. Pretty damn useful. You can't do that in C++. There are HACKS to do it, but natively, the language can't.
It is this "can't" that makes the language so bad. Sure, you might think "I don't need to store an address to a function in a variable" but try to build GUI API's without that - it's a PITA. So much so, that Qt uses a preprocessor to handle things that C++ can't do.
Wow. Now we're having to write preprocessors to get over stuff the language is incapable of handling.
I've written a lot of C++ code. There are parts of C++ I like. But for the most part, it is a broken language from the start. It is highly flawed. No one spent ANY time thinking through the problems with ctors or dtors (yeah, they said they did, but they didn't).
Why not try rust? Its faster than c++ and comes with absolutely no disadvantages...
Now you might ask what are the reasons C++ is considered bad?
Probably easiest to compare C++ with C. C was a beautifully designed language.
The features of the C language were added with purpose. They were intended to solve a real problem and solve that problem they did. Simple arithmetic with promotion. Automatic register allocation with a portable (between compilers) ABI. A simple-but-handy preprocessor. And so on. C is also a lean language: a single person can feasibly write a C compiler in a relatively short time (tinycc is a C99-compliant C compiler written in just 65kLOC of C!). C set out to achieve a clear goal and it achieved its goal. Thanks to the cleanness of C lots of quality compilers came on the market quickly and even decent OSS solutions were available early on.
In contrast, C++ never had a clear goal. The features of C++ were added almost at random. Stroustrup's original idea was essentially "C is cool and OOP is cool so let's bolt OOP onto C". Retrospectively, OOP was massively overhyped and is the wrong tool for the job for most of the people most of the time. Half of the GoF design patterns just emulate idioms from functional programming. Real OOP languages like Smalltalk and IO express many useful things that C++ cannot. The feature that C needed most was perhaps parametric polymorphism (aka generics in Java and C#, first seen in ML in the late 1970s) but instead of that C++ got templates that weren't designed to solve any particular problem but rather to kind of solve several completely unrelated problems (e.g. generics and metaprogramming). Someone actually discovered by accident that C++ templates are Turing complete and they wrote and published a program that computed prime numbers at compile time. Wow. A remarkable observation that led to decades of template abuse where people used templates to solve problems much better solved by other pre-existing solutions such Lisp macros and ML polymorphism. Worse, this abuse led to even more language features being piled on top, like template partial specialization.
The massive incidental complexity in C++ made it almost impossible to write a working compiler. For example, it remains extremely difficult to write a parser for the C++ language. The syntax also has horrible aspects like List<Set<int>> being interpreted as logical shift right. None of the original C++ compilers were reliable. During my PhD in 2000-2004 I was still stumbling upon dozens of bugs in C++ compilers from GNU, Intel and SGI. Only after two decades did we start to see solid C++ compilers (by which time C++ was in decline in industry due to Java and C#).
C++ is said to be fast but the reality is that C++ is essentially only fast when you write C-like code and even then it is only fast for certain kinds of programs. Due to the "you don't pay for what you don't use" attitude, C++ is generally inefficient. RAII injects lots of unnecessary function calls at the end of scope, sometimes even expensive virtual calls. These calls often require data that would otherwise be dead so the data are kept alive, increasing register pressure and spilling and decreasing performance. The C++ exception mechanism is very inefficient (~6x slower than OCaml) because it unwinds the stack frame by frame calling destructors rather than long jumping. Allocation with new and delete is slow compared to a modern garbage collector so people are encouraged to use STL collections but these pre-allocate huge blocks of memory in comparison so you've lost the memory-efficiency of C and then you are advised to write your own STL allocator which is no better than using C in the first place. One of the main long-standing advantages of C over modern languages is the unpredictable latency incurred by garbage collectors. C++ offers the worst of both worlds by not having a garbage collector (making it impossible to leverage useful concepts like purely functional data s...
You can build a website with any language… I mean, sometimes it’s nice to go back to the basics, but aren’t there better packages and frameworks written in C++ to handle the job?
Why not try rust? Its faster than c++ and comes with absolutely no disadvantages...
Now you might ask what are the reasons C++ is considered bad?
Probably easiest to compare C++ with C. C was a beautifully designed language.
The features of the C language were added with purpose. They were intended to solve a real problem and solve that problem they did. Simple arithmetic with promotion. Automatic register allocation with a portable (between compilers) ABI. A simple-but-handy preprocessor. And so on. C is also a lean language: a single person can feasibly write a C compiler in a relatively short time (tinycc is a C99-compliant C compiler written in just 65kLOC of C!). C set out to achieve a clear goal and it achieved its goal. Thanks to the cleanness of C lots of quality compilers came on the market quickly and even decent OSS solutions were available early on.
In contrast, C++ never had a clear goal. The features of C++ were added almost at random. Stroustrup's original idea was essentially "C is cool and OOP is cool so let's bolt OOP onto C". Retrospectively, OOP was massively overhyped and is the wrong tool for the job for most of the people most of the time. Half of the GoF design patterns just emulate idioms from functional programming. Real OOP languages like Smalltalk and IO express many useful things that C++ cannot. The feature that C needed most was perhaps parametric polymorphism (aka generics in Java and C#, first seen in ML in the late 1970s) but instead of that C++ got templates that weren't designed to solve any particular problem but rather to kind of solve several completely unrelated problems (e.g. generics and metaprogramming). Someone actually discovered by accident that C++ templates are Turing complete and they wrote and published a program that computed prime numbers at compile time. Wow. A remarkable observation that led to decades of template abuse where people used templates to solve problems much better solved by other pre-existing solutions such Lisp macros and ML polymorphism. Worse, this abuse led to even more language features being piled on top, like template partial specialization.
The massive incidental complexity in C++ made it almost impossible to write a working compiler. For example, it remains extremely difficult to write a parser for the C++ language. The syntax also has horrible aspects like List<Set<int>> being interpreted as logical shift right. None of the original C++ compilers were reliable. During my PhD in 2000-2004 I was still stumbling upon dozens of bugs in C++ compilers from GNU, Intel and SGI. Only after two decades did we start to see solid C++ compilers (by which time C++ was in decline in industry due to Java and C#).
C++ is said to be fast but the reality is that C++ is essentially only fast when you write C-like code and even then it is only fast for certain kinds of programs. Due to the "you don't pay for what you don't use" attitude, C++ is generally inefficient. RAII injects lots of unnecessary function calls at the end of scope, sometimes even expensive virtual calls. These calls often require data that would otherwise be dead so the data are kept alive, increasing register pressure and spilling and decreasing performance. The C++ exception mechanism is very inefficient (~6x slower than OCaml) because it unwinds the stack frame by frame calling destructors rather than long jumping. Allocation with new and delete is slow compared to a modern garbage collector so people are encouraged to use STL collections but these pre-allocate huge blocks of memory in comparison so you've lost the memory-efficiency of C and then you are advised to write your own STL allocator which is no better than using C in the first place. One of the main long-standing advantages of C over modern languages is the unpredictable latency incurred by garbage collectors. C++ offers the worst of both worlds by not having a garbage collector (making it impossible to leverage useful concepts like purely functional data s...
I'm gonna tell you from 30 years of experience, c++ aint gonna survive any longer child. So why not try rust? Its faster than c++ and comes with absolutely no disadvantages...
Now you might ask what are the reasons C++ is considered bad?
Probably easiest to compare C++ with C. C was a beautifully designed language.
The features of the C language were added with purpose. They were intended to solve a real problem and solve that problem they did. Simple arithmetic with promotion. Automatic register allocation with a portable (between compilers) ABI. A simple-but-handy preprocessor. And so on. C is also a lean language: a single person can feasibly write a C compiler in a relatively short time (tinycc is a C99-compliant C compiler written in just 65kLOC of C!). C set out to achieve a clear goal and it achieved its goal. Thanks to the cleanness of C lots of quality compilers came on the market quickly and even decent OSS solutions were available early on.
In contrast, C++ never had a clear goal. The features of C++ were added almost at random. Stroustrup's original idea was essentially "C is cool and OOP is cool so let's bolt OOP onto C". Retrospectively, OOP was massively overhyped and is the wrong tool for the job for most of the people most of the time. Half of the GoF design patterns just emulate idioms from functional programming. Real OOP languages like Smalltalk and IO express many useful things that C++ cannot. The feature that C needed most was perhaps parametric polymorphism (aka generics in Java and C#, first seen in ML in the late 1970s) but instead of that C++ got templates that weren't designed to solve any particular problem but rather to kind of solve several completely unrelated problems (e.g. generics and metaprogramming). Someone actually discovered by accident that C++ templates are Turing complete and they wrote and published a program that computed prime numbers at compile time. Wow. A remarkable observation that led to decades of template abuse where people used templates to solve problems much better solved by other pre-existing solutions such Lisp macros and ML polymorphism. Worse, this abuse led to even more language features being piled on top, like template partial specialization.
The massive incidental complexity in C++ made it almost impossible to write a working compiler. For example, it remains extremely difficult to write a parser for the C++ language. The syntax also has horrible aspects like List<Set<int>> being interpreted as logical shift right. None of the original C++ compilers were reliable. During my PhD in 2000-2004 I was still stumbling upon dozens of bugs in C++ compilers from GNU, Intel and SGI. Only after two decades did we start to see solid C++ compilers (by which time C++ was in decline in industry due to Java and C#).
C++ is said to be fast but the reality is that C++ is essentially only fast when you write C-like code and even then it is only fast for certain kinds of programs. Due to the "you don't pay for what you don't use" attitude, C++ is generally inefficient. RAII injects lots of unnecessary function calls at the end of scope, sometimes even expensive virtual calls. These calls often require data that would otherwise be dead so the data are kept alive, increasing register pressure and spilling and decreasing performance. The C++ exception mechanism is very inefficient (~6x slower than OCaml) because it unwinds the stack frame by frame calling destructors rather than long jumping. Allocation with new and delete is slow compared to a modern garbage collector so people are encouraged to use STL collections but these pre-allocate huge blocks of memory in comparison so you've lost the memory-efficiency of C and then you are advised to write your own STL allocator which is no better than using C in the first place. One of the main long-standing advantages of C over modern languages is the unpredictable latency incurred by garbage collectors. C++ offers the worst of both worlds by not having a ...
If you say that C++ is not memory safe you really don't know the modern C++. Of course you can use only `void *` everywhere... but you can also write your software in a totally different way. My C++ code has no pointers, just objects, which are automatically destroyed when I want to. The nice feature is that I know when the destructor is called, so the object will clear itself in a very nice way.
It's futile battle though to achieve both performance and safety in C++: as an example, safety requires avoiding moves, using reference counting, while achieving performance means avoiding copies and passing occasional references around, among other things. That's why advertising C++ solution as fast does not work well with "but C++ can be safe too!".
C++ is a language that can be used like a sawed-off shotgun propped against a developer's foot, and with a hair trigger. Granted, it does not _have_ to be used this way, but it can be.
A good developer can be "safe by default" and can use profile-directed optimization to speed up areas that are performance critical. A great developer can build proofs that such performance improvements maintain safety guarantees. For the average developer, following modern C++ development practices creates code on par with other languages in terms of both safety and performance.
For most languages, a lot can be done in terms of optimization, profiling, and security. Even in higher-level languages, an FFI is available to rewrite critical portions of code in a lower level language for performance improvements. Careful attention to detail can provide critical performance improvements in any language without compromising on safety. Getting there requires model checking or formal methods, but that is also becoming more of a part of modern development practices.
Not sure I necessarily agree with all your examples, but yes, this trade-off between safety and performance does exist in C++. It is particularily acute whenever you're forced to work with third party libraries that don't agree on a single approach to memory management.
Rust is essentially a bet on the impossibility of working around that trade-off in C++. And they are right, it is impossible to close that gap completely. C++ simply doesn't have the language features to enforce all necessary ownership rules without a performance penalty.
But I see trouble on the horizon for Rust, because that gap is quickly shrinking to its formally irreducible minimum as more C++ libraries are adopting a "modern" style. What's left of that gap may be too small to fit an entire new programming language built around fixing this single issue.
I know it's more than that. But what you can't do, in my opinion, is love Rust for its other modern features and merely tolerate the new approach to memory management.
Memory management in Rust is so dominant in terms of syntax and in terms of restrictions imposed on common idioms that it must be either embraced or rejected wholeheartedly.
This is just my personal opinion obviously, not any sort of truth or prediction.
Yeah, I totally hear you. I shared that opinion too, but, surprisingly enough, it seems to some degree that that's in the minority. Or at least, there's a pretty significant number of people who do "love Ruts for its other modern features and merely tolerate the new approach to memory management."
I feel that way myself now, but figured that I was just too close to have a mainstream opinion about it :)
Two main components of Rust's approach to memory management are i) the imposing/exploiting of scope lifetimes on objects and references, and ii) the restriction that a mutable reference may not co-exist with any other references (to the same object).
I suggest that with C++ there is kind of the option of embracing the former, without so much of the latter, to achieve a performance-safety combination that is closer to Rust's than current "modern C++" practices. That's sort of the premise of the SaferCPlusPlus library [1]. If you're a C++ programmer, the barrier to adoption is low. Though without a "borrow checker" or something equivalent, you wouldn't be able to match Rust's performance-safety combination in all cases.
I'm in the early stages of a FaaS platform that uses CGI for the functions. As such, I have been collecting articles about general CGI development, and have them listed in my docs. If anyone is interested in writing large scale CGI apps (CGI is popping up a lot around here lately), these are some good resources: https://bigcgi.com/docs
CGI is slow because of the spin up time for individual processes for each request. FastCGI is fast because they run as one long running process that handles multiple requests.
While plain CGI is a slower, the advantage is that you don't have long running and potentially idle processes for low traffic periods, and process isolation is a little security boost.
I chose to have a slightly slower startup time, which hopefully remain constant in a load balanced cluster, to gain the advantages above.
Also the spinup time is considerably larger problem for various interpreters and virtual machines than for native code binary.
I would even expect that you can write non-trivial CGI application whose startup time is smaller than the additional overhead from parsing of the FastCGI protocol.
If you want to use something like that for web, then use http://websocketd.com. There's no need to generate html on the server, unless you really don't want to touch JS at all.
> In this article, I’ll explain how you can use C++ to develop a website and some concrete reasons why you might consider doing so.
I only saw one reason: performance. Did I miss some? Do people have other good use cases that justify paying the dev cost of using C++ for a web server? I'd guess with caching and a decent backend, it would be fairly hard to demonstrate a true need for performance that requires C++, but I'm sure there are a few demanding applications out there that need it.
Since a web page's throughput is usually network bottlenecked and not CPU bound, I'm curious (just for fun) what the max possible performance benefit of going C++ is, especially behind a CGI interface?
There's probably a small latency benefit at all times, and I'd guess there's a throughput benefit that is only visible if you're doing more than a few thousand requests per second..?
Preferably one would use some kind of network protocol with a native management console, but nowadays it is fashionable to have a mini webserver exposing a Web UI instead.
I did? I just read the article again, and I don't see any mention of IOT or small or embedded devices aside from Docker, can you point me to what you saw? The article is assuming Apache is running...
> Most router admin panels are probably written in C++
What makes you say that? The modern routers I've used all run a full embedded Linux like BusyBox, and they have no need for compiled high performance panels. It'd be more expensive and less portable to write the admin panel in C++, and I can't really think of any strong benefits that would make it worth using C++. I would have assumed they run a scripting language. But I'm checking some of the OS projects now instead of assuming.
Poking around, I see that Tomato is a busybox distribution, all the Linux tools including httpd are C (not C++), and the admin panal pages are .asp (written in VBScript).
DD-wrt appears to have PHP admin panels.
Looks like Asuswrt-Merlin uses .asp.
M0n0wall is all php.
Let me know if you find one with admin panels in C++, I'm interested.
A large existing C++ code base is one good reason. It’s possible to write wrappers for most of the more web-friendly languages but they are a pain to debug and maintain for any complex API. So if you need a relatively lightweight web front-end for a complex C++ backend something like this may be a good choice. I still wouldn’t go the cgi route, or use makefiles for that matter.
I doubt the performance of a c++ web site would be better than c#/java or some other compiled languages for most non-trivial web sites. Once things like jits come into play, and you see large projects (1million+ loc) the performance advantage of c++ often disappears or it becomes less performant for things like web sites. Most companies do not have the time nor ability to do all those optimizations that theoretically exist that would make c++ more performant.
Can you quantify & explain what you mean by notable? I've written a lot of C++ and also a lot of scripted web services like node.js and flask (python). For most normal websites, I doubt that you could make significant and noticeable performance improvements to a decent scripted backend by switching to c++, from the user's point of view. A latency savings of a millisecond or two across the board I could buy, but making it obviously faster to a user, I'm skeptical, unless the site has non-traditional high performance requirements.
> What exactly is the "performance" you're talking about? How do you define it?
You can see that that was precisely my question, right? Did you mean to reply to the parent comment? The article says the reason to use C++ over rails or node or another scripting language is "performance", the parent comment to mine said that the performance difference would be "notable". I'm asking exactly what you're asking -- what is performance, what is notable?
On top of that, I did define performance loosely in my comment -- as something that is noticeably faster to the user. If a user running Chrome can feel the difference on a site, and the only difference is the language it was written in, then I could buy that C++ gives better "performance". I suspect it's rather difficult to write a custom C++ web server and make it load or run any faster, from the point of view of the person on the other end, than a generic rails/flask/nodejs web site, for most sites.
Thanks. Yes. I said this very thing in my top comment. It takes a lot of users (many more than 10!) in any modern web server framework to get noticeable slowdowns, unless you've done something horribly wrong. So the question on the table -- still -- is what web applications might actually require a C++ web server, in practice?
C++ advocates often talk about the performance gains. The problem with that is that what C++ buys you is not better performance or even predictable performance, but repeatable performance, which is not that useful for anything not hard-realtime.
For typical large OO codebase some kind of tracing GC is almost always better than various reference counting and tracking schemes. For the unpredictability the problem has to do with the fact that even simplest C++ statement might cause the compiler to generate several kilobytes of inlined code.
C++ only has repeatable performance if used in certain ways.
> various reference counting and tracking schemes.
Reference counting doesn't always have repeatable performance.
Maybe for a program image started from scratch on exactly the same non-real-time input. But then almost anything has repeatable performance for that, including ordinary mark-and-sweep garbage collection.
My point was that only reason to use C++ is when you want repeatable performance which implies that you will not do things that are against this goal (and in fact C++ makes various tricks to achieve this goal trivial, eg. per-timestep heaps)
My other point was that for anything other you do not want to use C++.
Edit: and also "when used in certain ways" is exactly the problem with C++ I tried to point out. The language and it's interactions with real implementations is simply too complex for any kind of useful analysis.
Is their performance demonstrably better than other sites? Parent wasn't saying that c++ sites don't exist, just speculating that it doesn't necessarily make the site clearly faster to browse. I'd speculate the same, but would appreciate if there's hard data around to educate me, I'm genuinely curious what the benefits of going c++ are.
Wouldn't this have very similar performance characteristics to something like serverless functions on Amazon/Google cloud ? (assuming using same language)
Pion[0] is a fairly robust and well-written HTTP server implementation in C++. You can spin up a server very quickly and reverse proxy through Apache or Nginx. Microsoft has a cross-platform offering of some sort in the works using C++11, now I don’t remember the name but I think Herb Sutter has a write-up in it from a couple years ago. It’s definitely possible to write modern web applications in C++, I feel like the cgi route is pretty old school.
121 comments
[ 3.1 ms ] story [ 192 ms ] threadCGI in 2018 seems a bit passé...
well, at least in terms of not keeping the server process up all the time, only when it's used.
To combine "only running when necessary" and "not restarting for every request when there's a lot of requests", I made a thing: https://github.com/myfreeweb/soad — little wrapper listens on a socket, spawns your server with the socket passed in, terminates the server when there were no new connections in a while, rinse, repeat.
https://en.wikipedia.org/wiki/Inetd
Or perhaps you might want to use a belt sander to refinish your table without removing the tablecloth from the table first. Not all the things one “might want to do” are good ideas, even if there’s a wikihow on best ways to do them.
C++ is a great language but it’s a very hard language to wield correctly. The odds there is an exploitable buffer overflow or injection attack buried deep in some part of the code are simply too high compared to memory managed languages with standard libraries designed from the ground up for web-facing applications.
There is almost literally no chance that this is the case. The amount of pointless boilerplate code that you'd have to write would be many, many, many times in excess of a thin API layer.
There may be some advantages to writing a middle tier application server in either of these languages, but using a system language to manage a web front-end is effectively like using a hatchet to shave. Sure, the hatchet is faster at cutting wood than a safety razor, and if one is careful, it could be used to remove stubble, but chances are that one is not clearly thinking about the problem at hand to suggest such a tool.
There aren't many options when you just have a few hundred KB.
Modern C++ has a lot of great stuff to help, but the sense of safety you get when you use Rust is something else entirely.
Why the hell shouldn't it be possible? C++ powers most of the stuff under the hood. The higher level languages like PHP are just sugar on top.
Did the author really benchmark if optimized PHP environment is not faster than his solution?
Languages are not panaceas. Rust and D are both hard languages, as is C++. Selecting one of these only makes sense if the application warrants it. Each have advantages and disadvantages. I don't really think any of them are suited to web development, but claiming that D or Rust would be a more productive web development language than C++ seems equally silly to seriously considering C++ as a web development language.
Because D is very obviously C++ but better. Rust isn't, though. But D, down to the very name, has lots of things that appeal to C++ users. It has advanced metaprogramming, is multiparadigm, it compiles down to machine code, and has very similar syntax to C++.
D has had other influences, but it is written by C++ compiler writers who think they can do better than C++. I say this as someone raised on C++ and who is now trying D. It is a very natural progression to make, if you're inclined to try something new.
Furthermore, Vibe.d is kind of a burgeoning "killer app" for D. D's package manager, for example, was originally made for Vibe.d. This isn't the only way in which Vibe.d has influenced D development. Vibe.d is one of the most popular D libraries. It's the only D library I know that has its own published book,
https://dlang.org/blog/2017/09/13/the-making-of-d-web-develo...
The reason that C++ sucks is that it is a FAUX object-oriented language. Many things that you CAN do with an object-oriented language are impossible with C++ (unless you like hackery... no, I don't like hackery).
The reason is purely about runtime speed. At the time that C++ was designed, processors were horribly slow (compared to today's). OOP runtimes were dreadful. So all of the work was put in at compile-time in order to speed up run-time.
Except for one thing. It meant that it was no longer OOP but pseudo-OOP. It kinda-quacked like a duck, kinda-looked like a duck, but really wasn't a duck at all.
For example, one aspect that was ripped from the hands of the developer was the ability to store the address to a function in a variable. Pretty damn useful. You can't do that in C++. There are HACKS to do it, but natively, the language can't.
It is this "can't" that makes the language so bad. Sure, you might think "I don't need to store an address to a function in a variable" but try to build GUI API's without that - it's a PITA. So much so, that Qt uses a preprocessor to handle things that C++ can't do.
Wow. Now we're having to write preprocessors to get over stuff the language is incapable of handling.
I've written a lot of C++ code. There are parts of C++ I like. But for the most part, it is a broken language from the start. It is highly flawed. No one spent ANY time thinking through the problems with ctors or dtors (yeah, they said they did, but they didn't).
It's a bad, broken, language
Now you might ask what are the reasons C++ is considered bad?
Probably easiest to compare C++ with C. C was a beautifully designed language.
The features of the C language were added with purpose. They were intended to solve a real problem and solve that problem they did. Simple arithmetic with promotion. Automatic register allocation with a portable (between compilers) ABI. A simple-but-handy preprocessor. And so on. C is also a lean language: a single person can feasibly write a C compiler in a relatively short time (tinycc is a C99-compliant C compiler written in just 65kLOC of C!). C set out to achieve a clear goal and it achieved its goal. Thanks to the cleanness of C lots of quality compilers came on the market quickly and even decent OSS solutions were available early on.
In contrast, C++ never had a clear goal. The features of C++ were added almost at random. Stroustrup's original idea was essentially "C is cool and OOP is cool so let's bolt OOP onto C". Retrospectively, OOP was massively overhyped and is the wrong tool for the job for most of the people most of the time. Half of the GoF design patterns just emulate idioms from functional programming. Real OOP languages like Smalltalk and IO express many useful things that C++ cannot. The feature that C needed most was perhaps parametric polymorphism (aka generics in Java and C#, first seen in ML in the late 1970s) but instead of that C++ got templates that weren't designed to solve any particular problem but rather to kind of solve several completely unrelated problems (e.g. generics and metaprogramming). Someone actually discovered by accident that C++ templates are Turing complete and they wrote and published a program that computed prime numbers at compile time. Wow. A remarkable observation that led to decades of template abuse where people used templates to solve problems much better solved by other pre-existing solutions such Lisp macros and ML polymorphism. Worse, this abuse led to even more language features being piled on top, like template partial specialization.
The massive incidental complexity in C++ made it almost impossible to write a working compiler. For example, it remains extremely difficult to write a parser for the C++ language. The syntax also has horrible aspects like List<Set<int>> being interpreted as logical shift right. None of the original C++ compilers were reliable. During my PhD in 2000-2004 I was still stumbling upon dozens of bugs in C++ compilers from GNU, Intel and SGI. Only after two decades did we start to see solid C++ compilers (by which time C++ was in decline in industry due to Java and C#).
C++ is said to be fast but the reality is that C++ is essentially only fast when you write C-like code and even then it is only fast for certain kinds of programs. Due to the "you don't pay for what you don't use" attitude, C++ is generally inefficient. RAII injects lots of unnecessary function calls at the end of scope, sometimes even expensive virtual calls. These calls often require data that would otherwise be dead so the data are kept alive, increasing register pressure and spilling and decreasing performance. The C++ exception mechanism is very inefficient (~6x slower than OCaml) because it unwinds the stack frame by frame calling destructors rather than long jumping. Allocation with new and delete is slow compared to a modern garbage collector so people are encouraged to use STL collections but these pre-allocate huge blocks of memory in comparison so you've lost the memory-efficiency of C and then you are advised to write your own STL allocator which is no better than using C in the first place. One of the main long-standing advantages of C over modern languages is the unpredictable latency incurred by garbage collectors. C++ offers the worst of both worlds by not having a garbage collector (making it impossible to leverage useful concepts like purely functional data s...
Now you might ask what are the reasons C++ is considered bad?
Probably easiest to compare C++ with C. C was a beautifully designed language.
The features of the C language were added with purpose. They were intended to solve a real problem and solve that problem they did. Simple arithmetic with promotion. Automatic register allocation with a portable (between compilers) ABI. A simple-but-handy preprocessor. And so on. C is also a lean language: a single person can feasibly write a C compiler in a relatively short time (tinycc is a C99-compliant C compiler written in just 65kLOC of C!). C set out to achieve a clear goal and it achieved its goal. Thanks to the cleanness of C lots of quality compilers came on the market quickly and even decent OSS solutions were available early on.
In contrast, C++ never had a clear goal. The features of C++ were added almost at random. Stroustrup's original idea was essentially "C is cool and OOP is cool so let's bolt OOP onto C". Retrospectively, OOP was massively overhyped and is the wrong tool for the job for most of the people most of the time. Half of the GoF design patterns just emulate idioms from functional programming. Real OOP languages like Smalltalk and IO express many useful things that C++ cannot. The feature that C needed most was perhaps parametric polymorphism (aka generics in Java and C#, first seen in ML in the late 1970s) but instead of that C++ got templates that weren't designed to solve any particular problem but rather to kind of solve several completely unrelated problems (e.g. generics and metaprogramming). Someone actually discovered by accident that C++ templates are Turing complete and they wrote and published a program that computed prime numbers at compile time. Wow. A remarkable observation that led to decades of template abuse where people used templates to solve problems much better solved by other pre-existing solutions such Lisp macros and ML polymorphism. Worse, this abuse led to even more language features being piled on top, like template partial specialization.
The massive incidental complexity in C++ made it almost impossible to write a working compiler. For example, it remains extremely difficult to write a parser for the C++ language. The syntax also has horrible aspects like List<Set<int>> being interpreted as logical shift right. None of the original C++ compilers were reliable. During my PhD in 2000-2004 I was still stumbling upon dozens of bugs in C++ compilers from GNU, Intel and SGI. Only after two decades did we start to see solid C++ compilers (by which time C++ was in decline in industry due to Java and C#).
C++ is said to be fast but the reality is that C++ is essentially only fast when you write C-like code and even then it is only fast for certain kinds of programs. Due to the "you don't pay for what you don't use" attitude, C++ is generally inefficient. RAII injects lots of unnecessary function calls at the end of scope, sometimes even expensive virtual calls. These calls often require data that would otherwise be dead so the data are kept alive, increasing register pressure and spilling and decreasing performance. The C++ exception mechanism is very inefficient (~6x slower than OCaml) because it unwinds the stack frame by frame calling destructors rather than long jumping. Allocation with new and delete is slow compared to a modern garbage collector so people are encouraged to use STL collections but these pre-allocate huge blocks of memory in comparison so you've lost the memory-efficiency of C and then you are advised to write your own STL allocator which is no better than using C in the first place. One of the main long-standing advantages of C over modern languages is the unpredictable latency incurred by garbage collectors. C++ offers the worst of both worlds by not having a garbage collector (making it impossible to leverage useful concepts like purely functional data s...
https://github.com/shi-yan/Swiftly
Now you might ask what are the reasons C++ is considered bad?
Probably easiest to compare C++ with C. C was a beautifully designed language.
The features of the C language were added with purpose. They were intended to solve a real problem and solve that problem they did. Simple arithmetic with promotion. Automatic register allocation with a portable (between compilers) ABI. A simple-but-handy preprocessor. And so on. C is also a lean language: a single person can feasibly write a C compiler in a relatively short time (tinycc is a C99-compliant C compiler written in just 65kLOC of C!). C set out to achieve a clear goal and it achieved its goal. Thanks to the cleanness of C lots of quality compilers came on the market quickly and even decent OSS solutions were available early on.
In contrast, C++ never had a clear goal. The features of C++ were added almost at random. Stroustrup's original idea was essentially "C is cool and OOP is cool so let's bolt OOP onto C". Retrospectively, OOP was massively overhyped and is the wrong tool for the job for most of the people most of the time. Half of the GoF design patterns just emulate idioms from functional programming. Real OOP languages like Smalltalk and IO express many useful things that C++ cannot. The feature that C needed most was perhaps parametric polymorphism (aka generics in Java and C#, first seen in ML in the late 1970s) but instead of that C++ got templates that weren't designed to solve any particular problem but rather to kind of solve several completely unrelated problems (e.g. generics and metaprogramming). Someone actually discovered by accident that C++ templates are Turing complete and they wrote and published a program that computed prime numbers at compile time. Wow. A remarkable observation that led to decades of template abuse where people used templates to solve problems much better solved by other pre-existing solutions such Lisp macros and ML polymorphism. Worse, this abuse led to even more language features being piled on top, like template partial specialization.
The massive incidental complexity in C++ made it almost impossible to write a working compiler. For example, it remains extremely difficult to write a parser for the C++ language. The syntax also has horrible aspects like List<Set<int>> being interpreted as logical shift right. None of the original C++ compilers were reliable. During my PhD in 2000-2004 I was still stumbling upon dozens of bugs in C++ compilers from GNU, Intel and SGI. Only after two decades did we start to see solid C++ compilers (by which time C++ was in decline in industry due to Java and C#).
C++ is said to be fast but the reality is that C++ is essentially only fast when you write C-like code and even then it is only fast for certain kinds of programs. Due to the "you don't pay for what you don't use" attitude, C++ is generally inefficient. RAII injects lots of unnecessary function calls at the end of scope, sometimes even expensive virtual calls. These calls often require data that would otherwise be dead so the data are kept alive, increasing register pressure and spilling and decreasing performance. The C++ exception mechanism is very inefficient (~6x slower than OCaml) because it unwinds the stack frame by frame calling destructors rather than long jumping. Allocation with new and delete is slow compared to a modern garbage collector so people are encouraged to use STL collections but these pre-allocate huge blocks of memory in comparison so you've lost the memory-efficiency of C and then you are advised to write your own STL allocator which is no better than using C in the first place. One of the main long-standing advantages of C over modern languages is the unpredictable latency incurred by garbage collectors. C++ offers the worst of both worlds by not having a ...
Go is rather performant and in contrast to C++ memory safe.
C++ is a language that can be used like a sawed-off shotgun propped against a developer's foot, and with a hair trigger. Granted, it does not _have_ to be used this way, but it can be.
A good developer can be "safe by default" and can use profile-directed optimization to speed up areas that are performance critical. A great developer can build proofs that such performance improvements maintain safety guarantees. For the average developer, following modern C++ development practices creates code on par with other languages in terms of both safety and performance.
For most languages, a lot can be done in terms of optimization, profiling, and security. Even in higher-level languages, an FFI is available to rewrite critical portions of code in a lower level language for performance improvements. Careful attention to detail can provide critical performance improvements in any language without compromising on safety. Getting there requires model checking or formal methods, but that is also becoming more of a part of modern development practices.
This is not specific to C++, but it is worse in C and C++ given the nature of these languages.
It also doesn't help that management even cares less about QA than those devs.
Rust is essentially a bet on the impossibility of working around that trade-off in C++. And they are right, it is impossible to close that gap completely. C++ simply doesn't have the language features to enforce all necessary ownership rules without a performance penalty.
But I see trouble on the horizon for Rust, because that gap is quickly shrinking to its formally irreducible minimum as more C++ libraries are adopting a "modern" style. What's left of that gap may be too small to fit an entire new programming language built around fixing this single issue.
Memory management in Rust is so dominant in terms of syntax and in terms of restrictions imposed on common idioms that it must be either embraced or rejected wholeheartedly.
This is just my personal opinion obviously, not any sort of truth or prediction.
I feel that way myself now, but figured that I was just too close to have a mainstream opinion about it :)
I suggest that with C++ there is kind of the option of embracing the former, without so much of the latter, to achieve a performance-safety combination that is closer to Rust's than current "modern C++" practices. That's sort of the premise of the SaferCPlusPlus library [1]. If you're a C++ programmer, the barrier to adoption is low. Though without a "borrow checker" or something equivalent, you wouldn't be able to match Rust's performance-safety combination in all cases.
[1] shameless plug: https://github.com/duneroadrunner/SaferCPlusPlus
edit: edited the link
Go is slower than C++.
https://m.imgur.com/r/ProgrammerHumor/INBvStO
While plain CGI is a slower, the advantage is that you don't have long running and potentially idle processes for low traffic periods, and process isolation is a little security boost.
I chose to have a slightly slower startup time, which hopefully remain constant in a load balanced cluster, to gain the advantages above.
I would even expect that you can write non-trivial CGI application whose startup time is smaller than the additional overhead from parsing of the FastCGI protocol.
I only saw one reason: performance. Did I miss some? Do people have other good use cases that justify paying the dev cost of using C++ for a web server? I'd guess with caching and a decent backend, it would be fairly hard to demonstrate a true need for performance that requires C++, but I'm sure there are a few demanding applications out there that need it.
Since a web page's throughput is usually network bottlenecked and not CPU bound, I'm curious (just for fun) what the max possible performance benefit of going C++ is, especially behind a CGI interface?
There's probably a small latency benefit at all times, and I'd guess there's a throughput benefit that is only visible if you're doing more than a few thousand requests per second..?
Preferably one would use some kind of network protocol with a native management console, but nowadays it is fashionable to have a mini webserver exposing a Web UI instead.
I did? I just read the article again, and I don't see any mention of IOT or small or embedded devices aside from Docker, can you point me to what you saw? The article is assuming Apache is running...
> Do people have other good use cases that justify paying the dev cost of using C++ for a web server?
What makes you say that? The modern routers I've used all run a full embedded Linux like BusyBox, and they have no need for compiled high performance panels. It'd be more expensive and less portable to write the admin panel in C++, and I can't really think of any strong benefits that would make it worth using C++. I would have assumed they run a scripting language. But I'm checking some of the OS projects now instead of assuming.
Poking around, I see that Tomato is a busybox distribution, all the Linux tools including httpd are C (not C++), and the admin panal pages are .asp (written in VBScript).
DD-wrt appears to have PHP admin panels.
Looks like Asuswrt-Merlin uses .asp.
M0n0wall is all php.
Let me know if you find one with admin panels in C++, I'm interested.
This isn't even counting the dev time difference
Can you quantify & explain what you mean by notable? I've written a lot of C++ and also a lot of scripted web services like node.js and flask (python). For most normal websites, I doubt that you could make significant and noticeable performance improvements to a decent scripted backend by switching to c++, from the user's point of view. A latency savings of a millisecond or two across the board I could buy, but making it obviously faster to a user, I'm skeptical, unless the site has non-traditional high performance requirements.
You can see that that was precisely my question, right? Did you mean to reply to the parent comment? The article says the reason to use C++ over rails or node or another scripting language is "performance", the parent comment to mine said that the performance difference would be "notable". I'm asking exactly what you're asking -- what is performance, what is notable?
On top of that, I did define performance loosely in my comment -- as something that is noticeably faster to the user. If a user running Chrome can feel the difference on a site, and the only difference is the language it was written in, then I could buy that C++ gives better "performance". I suspect it's rather difficult to write a custom C++ web server and make it load or run any faster, from the point of view of the person on the other end, than a generic rails/flask/nodejs web site, for most sites.
you know, there might be MORE THAN ONE user
so if server is done in, say, python, then user #11 will get slowdown. With C++, slowdown might start with user #50 (or 100, or ...)
For typical large OO codebase some kind of tracing GC is almost always better than various reference counting and tracking schemes. For the unpredictability the problem has to do with the fact that even simplest C++ statement might cause the compiler to generate several kilobytes of inlined code.
> various reference counting and tracking schemes.
Reference counting doesn't always have repeatable performance.
Maybe for a program image started from scratch on exactly the same non-real-time input. But then almost anything has repeatable performance for that, including ordinary mark-and-sweep garbage collection.
My other point was that for anything other you do not want to use C++.
Edit: and also "when used in certain ways" is exactly the problem with C++ I tried to point out. The language and it's interactions with real implementations is simply too complex for any kind of useful analysis.
No "would" about it C++ web sites are real and have been around for a long time. I'm thinking of sites running on Windows using "ISAPI".
[0] https://github.com/splunk/pion
Casablanca, but I'm not sure how active is the project nowadays.