[HN Gopher] Goodbye C++, Hello C
       ___________________________________________________________________
        
       Goodbye C++, Hello C
        
       Author : khoobid_shoma
       Score  : 229 points
       Date   : 2021-06-25 22:56 UTC (1 days ago)
        
 (HTM) web link (momentsingraphics.de)
 (TXT) w3m dump (momentsingraphics.de)
        
       | mauricedenassau wrote:
       | While I can understand the feeling of "bloat" in C++, I can't
       | help but be put off each time I have to implement something even
       | remotely serious in C. I have to reinvent the wheel everytime
       | while in C++ I can have access to high quality implementation in
       | the STL.
        
       | adamdusty wrote:
       | The author lists GLFW, stb_image, and ImGui as dependencies for
       | their renderer written in C. Those are the same exact
       | dependencies you would use to write a renderer in C++. Maybe you
       | would add glm because you don't want write matrix math
       | operations, but the author will have to do that in C anyway. I
       | don't see how dependencies are an advantage for C.
        
         | acmj wrote:
         | You can go down the route to say C++ is largely a superset of
         | C. You can always write C++ in the C way, so you don't see
         | simplicity is an advantage of C.
        
           | bruce343434 wrote:
           | > You can always write C++ in the C way
           | 
           | Nope. They have grown too far apart. My C11 codebase simply
           | does not compile when `mv *.c *.cpp && g++ main.cpp`.
        
             | kaba0 wrote:
             | That's why grandparent wrote "largely"
        
               | bruce343434 wrote:
               | Their second statement is still simply wrong. C has some
               | ways of doing things which are simply unacceptable in
               | C++. In C, you don't cast mallocs. You can initialize
               | structs like `={0}` or `={prop=val}`. There's more, but
               | the point is: if you are writing C++, you can't write it
               | in a "C way". It won't compile at some point.
        
               | kaba0 wrote:
               | I interpreted the "C way" as in avoiding RAI, classes,
               | references, etc. Just writing functions with structs and
               | pointers. Not as "syntactic C"
        
       | everyone wrote:
       | I just freakin' _hate_ .h files... Writing pretty much the same
       | thing but twice and in two different places for every function.
       | Why?!? I would love C++ if not for them.
        
         | pjmlp wrote:
         | Then use modules, VC++ 20219 has the best support, GCC 11 has
         | similar support, it is mostly clang that still had some catch-
         | up to do.
        
           | efficax wrote:
           | For modules in GCC you currently have to build the branch
           | yourself. Not the best experience
        
           | jart wrote:
           | Or use traditional C. The x86_64 System V ABI is well defined
           | enough that I'm honestly not sure why we need prototypes. All
           | we need is a compiler that authorizes us to use an ILP64 data
           | model. Then we'll be able to write C the way it was intended
           | to be written without the quadratic header complexity. C++
           | showed us where that path leads and I truly hope modules
           | happen but it's about as likely as my hopes of restoring the
           | good parts of K&R C.
        
       | gargalatas wrote:
       | why someone would compare python wih c++?
        
       | tayistay wrote:
       | The article makes me wonder: how much headroom do compilers of
       | newer slow-to-compile languages such as Rust or Swift have for
       | improving compile times?
        
         | yoz-y wrote:
         | Swift can reduce the "max time to compile a complex expression"
         | indefinitely to force programmers to write simpler-to-compile
         | code. /s
        
         | adrianN wrote:
         | Nicholas Nethercote has a series of blog post on speeding up
         | the Rust compiler. [1] There are (were?) also efforts going to
         | to reduce the amount of LLVM work by shifting some of that work
         | further up in the stack.
         | 
         | [1]
         | https://blog.mozilla.org/nnethercote/author/nnethercotemozil...
        
         | the_duke wrote:
         | In addition to the mentioned micro optimizations, I'll add some
         | possibilities from the Rust angle.
         | 
         | Rust has really impressive incremental compilation built in
         | already.
         | 
         | The first compile is annoyingly slow, but additional ones will
         | be surprisingly fast, often finishing in a second or two , even
         | in larger code bases. Especially if you split up your own code
         | into multiple crates.
         | 
         | This could further be significantly improved by a demonized
         | compiler that keeps everything in memory.
         | 
         | Additionally there could be a way to share compilation
         | artifacts via the package registry, also making first time
         | compiles fast.
         | 
         | There is also an effort to use Cranelift as a codegen backend,
         | which can be faster than llvm for debug builds, and has the
         | potential for JIT compiling functions on first use, which would
         | make debug builds a lot faster again as well.
         | 
         | Zig also has some really cool plans in this domain.
         | 
         | There is lots of headroom to make compiling these static
         | languages faster, but compilers would often need to be
         | (re)written from scratch with these compilation strategies in
         | mind.
        
       | jart wrote:
       | If you want a good case study in repositories that build quickly
       | then check out cosmopolitan libc. Typing `make -j16` it compiles
       | 15,383 .o objects, 69 .a static libraries, and 548 executables,
       | 297 of which are test executables, which are also run by the make
       | command, and all that takes just 40 sec.
        
         | qayxc wrote:
         | Minor nit-pick: wouldn't that rather be _make -j`nproc`_? Not
         | everyone has an 8-core CPU with SMT or a 16+-core CPU
         | respectively.
        
           | jart wrote:
           | I measured that on an Intel(R) Core(TM) i9-9900. I understand
           | that not everyone has the privilege of being able to afford a
           | $1,000 computer. However those people usually aren't coders.
           | It'd be great if I had one of those 64 core "specialist"
           | workstations that people like googlers use to be able to
           | compile projects like TensorFlow in a reasonable amount of
           | time. My project would probably build in seconds. But alas I
           | don't, so I need to forgo eigen and template metaprogramming.
        
       | maleldil wrote:
       | > Where C++ gives you many slightly different takes on the same
       | concept (e.g. unique_ptr, shared_ptr and raw pointers), C gives
       | you one way to go and that one has a conveniently compact
       | notation (such as float _).
       | 
       | You use unique_ptr and shared_ptr because float_ is unsafe. If
       | you don't care about the safety that smart pointers provide, you
       | can use float* in C++ too.
       | 
       | > ticking with the example of matrix math, it is baffling how C
       | code is often more compact and readable than C++ code. A matrix
       | declaration would be float matrix[4][4]; [...] Of course, you
       | could take the same approach in C++ but then you are not really
       | using C++. The example from above in C could be simply: float*
       | top = matrix;
       | 
       | But that's not that same thing, is it? I fail to see how you're
       | actually getting the top 3 rows there; you're just assigning a
       | pointer. Again, you're making your code less safe and expressive
       | by using no abstraction at all.
       | 
       | And please, how is `matrix_add(matrix_mul(A, B), c)` more compact
       | and readable than `A*B + c`? And this is being kind to the C
       | version.
       | 
       | If the problem is with C++'s compilation times, then it's
       | perfectly reasonable; this is one of the major problems of the
       | language. But using unsafe constructs and then saying that
       | they're better than C++'s safer alternatives is just comparing
       | apples to oranges.
        
         | bruce343434 wrote:
         | Markdown ate some of your asterisks
        
         | giomasce wrote:
         | The problem is not even just safety. You can write safe C, if
         | you are careful (and you need to be careful also for C++, smart
         | pointers do not just magically make everything right). The
         | point is that OP makes the point that C requires to write less
         | code, and this doesn't even seem true: you have to remember,
         | each time some non-trivial object goes out of scope, to call
         | its destructor/deallocator, which results in a lot of code
         | (which can at times hard to read, especially if you have not
         | completely linear control flow). Looking at just the
         | declaration is a small part of the issue.
        
           | Ygg2 wrote:
           | > You can write safe C, if you are careful
           | 
           | You can also live forever, if you have right combination of
           | genetics and environment.
        
             | z0ltan wrote:
             | You analogy makes no sense. By your measure, nothing is
             | safe.
        
             | ksaj wrote:
             | Like when someone says "Lisp is homoiconic," and that
             | automagically creates a thread of people tripping over
             | themselves to make the same points they do every time
             | "Lisp" and "homoiconic" appear in the same sentence.
             | 
             | There should be a list of these language snowball
             | avalanches somewhere. They work every time.
        
               | Ygg2 wrote:
               | I assume Lisp homoiconicity is closer to fact than "You
               | can write safe code in C".
               | 
               | I mean it is possible. In the same way all molecules of
               | air could bunch up in one corner of the room suffocating
               | you. It's a possibility.
        
           | UncleMeat wrote:
           | I don't believe that it is possible to write safe C (or C++),
           | even if you are both very careful and also among the most
           | skilled C developers out there. Every sizable project in C
           | has had critical vulnerabilities. It is not possible to train
           | engineers on a team of any meaningful size to consistently
           | write bug free code and catch bugs in code review.
           | Sanitizers, fuzzing, and static analysis all help but are
           | insufficient in the face of the utterly impossible task of
           | writing safe C programs, let alone _evolving_ safe C
           | programs.
           | 
           | Look at all the very smart people that tried and completely
           | failed to write libraries that do such basic things as
           | copying strings.
        
           | MaxBarraclough wrote:
           | > You can write safe C, if you are careful
           | 
           | In practice this pretty much cannot be done unless you use a
           | formal verification framework, which almost no one does. Even
           | the most well-resourced projects written in C tend to have
           | trouble with low-level bugs. Same goes for C++. Both the
           | Linux kernel and Chromium have plenty of these issues.
        
             | giomasce wrote:
             | My comment seems to have sparked a lot of reaction about
             | safety, but that wasn't the main point. The main point (and
             | the one OP talks about) was about conciseness, and I can't
             | really see how C can be considered a concise language.
        
               | MaxBarraclough wrote:
               | Agreed. C is more concise than assembly, but it's highly
               | verbose compared to most modern languages. C++ can
               | sometimes be a good deal more concise.
        
           | skohan wrote:
           | It depends. One approach to avoiding tricky memory management
           | issues is to avoid memory management altogether. In the kind
           | of applications where C is a good choice, you might consider
           | strategies like allocating all the memory you need to work
           | with besides small structs which fit on the stack when the
           | program starts and then never deallocate. If you're worried
           | about performance this is often a very good strategy.
        
             | Jweb_Guru wrote:
             | We are talking about a renderer. Renderers definitely need
             | to deallocate or otherwise manage memory :)
        
               | skohan wrote:
               | Why would a renderer need to deallocate memory? And
               | _when_ would a renderer need to deallocate memory?
        
               | Jweb_Guru wrote:
               | Renderers need to deallocate memory all the time. For
               | example, they often need to store per-frame data that
               | gets dropped when the frame is over, debug strings, track
               | temporary access to texture/buffer data, manage command
               | buffers, etc. They also have to track resources for lots
               | of data types external to the program (such as GPU data)
               | which often forces them to work with external allocators,
               | as well as having to synchronize stuff like resource
               | destruction using GPU-CPU fences. Moreover, most
               | resources are either immutable or can be accessed
               | optimally when they are immutable, so you often end up
               | benefiting significantly from being able to destroy and
               | reclaim the memory of stuff you're no longer using rather
               | than trying to update in place.
               | 
               | Even if you try to only allocate one buffer (for example)
               | to split up and use for all your logical vertex buffers,
               | you still have to manage memory within that buffer, which
               | ends up leading to pretty much the same kinds of complex
               | reasoning you need for ordinary dynamic allocation.
               | Failure to do this properly results in resource leaks on
               | both the GPU and CPU side which can be really nasty.
               | 
               | Of course, this all depends on the complexity of your
               | renderer. For simple usecases you might be able to get
               | away with no deallocation until exit. But they'd have to
               | be _really_ simple.
        
               | habibur wrote:
               | > Renderers need to deallocate memory all the time. For
               | example, they often need to store per-frame data that
               | gets dropped when the frame is over
               | 
               | Zero the buff and reuse this same frame as the new frame.
        
               | skohan wrote:
               | > For example, they often need to store per-frame data
               | that gets dropped when the frame is over, debug strings,
               | track temporary access to texture/buffer data, command
               | buffers, etc.
               | 
               | Exactly. You can just bulk allocate all the memory for
               | the frame at the beginning and drop the entire thing
               | after the frame is finished. This is a very easy case for
               | manual memory management where you have one allocation
               | and one deallocation per frame.
               | 
               | Or you can do one better, and keep an arena for each
               | framebuffer, and then just recycle them and never
               | deallocate at all. If you really need some level of
               | dynamism in terms of memory usage, you can just double
               | the size of the arena every time you fill it, and you
               | still don't need to deallocate, since chances are you
               | will need that space again for some frame in the future.
        
               | Jweb_Guru wrote:
               | I love arena allocation (which, incidentally, _does_
               | entail dynamic resource destruction if you use it per-
               | frame, and which is pretty easy to get wrong if you 're
               | just storing raw pointers everywhere--so good bye nice
               | use after free properties), but you absolutely cannot
               | just use arena allocation for everything. GPU resources
               | in particular need to wait on fences and therefore _can
               | 't_ have a neatly defined lifetime like what you're
               | proposing unless you block your whole program waiting for
               | these fences, while other GPU resources are (like I said)
               | immutable and need to live for multiple frames. Where
               | exactly do you store this data? How do you access it? How
               | do you free it when it's done? How do you perform slow
               | tasks like recomputing pipelines and shaders in the
               | background without being able to dynamically track the
               | lifetimes of the old/new backing GPU allocations? More
               | generally, how do you track resources other than the
               | framebuffer/surface, which are usually managed very
               | dynamically and often appear and disappear between
               | frames?
               | 
               | I think maybe it would be helpful if you would go look at
               | the actual implementation of a nontrivial renderer and
               | try to find one that doesn't allocate. Because the
               | strategies you're describing don't match my experience
               | working on renderers, at all.
        
               | skohan wrote:
               | I am speaking from experience, I have written a lot of
               | renderers.
               | 
               | > GPU resources in particular need to wait on fences and
               | therefore can't have a neatly defined lifetime like what
               | you're proposing unless you block your whole program
               | waiting for these fences, while other GPU resources are
               | (like I said) immutable and need to live for multiple
               | frames.
               | 
               | I don't quite understand why fences are a problem here.
               | As long as you know what frame a resource corresponds to,
               | you just to have to guarantee that the entire frame is
               | finished before reusing. You don't need to know what's
               | happening at a granular detail within the frame.
               | 
               | As far as static resources, that's easy: another arena
               | for static resources which grows as needed and is shared
               | between frames. Most of that data is living on the GPU
               | anyway, so you just need to keep a list of the resource
               | handles somewhere, and you're going to want a budget for
               | it anyway, so there's no reason not to make it of finite
               | size.
               | 
               | > More generally, how do you track resources other than
               | the framebuffer, which are usually managed very
               | dynamically and often appear and disappear between
               | frames?
               | 
               | See the whole issue is trying to solve the issue "more
               | generally". In many cases, you can know exactly the
               | resources you will need (or at least the upper limit)
               | when you start rendering a given scene. If you need to do
               | any memory management at all, you can do it at neatly
               | defined boundaries when you load/unload a scene.
               | 
               | The only time when you need some kind of super dynamic
               | renderer is when you are talking about an open world or
               | something where you are streaming assets.
               | 
               | Most of the serious renderers are written in C++ using
               | custom allocators, which are just some kind of arena
               | allocator under the hood anyway.
        
               | Jweb_Guru wrote:
               | Sorry, but if you think you can just get away with
               | _never_ deallocating any static GPU resources (as you 're
               | implying by "just use an arena"!), one of two things is
               | going on:
               | 
               | (1) You are manually managing an allocator on top of the
               | GPU resources in the arena (reintroducing the usual use
               | after free problems). (2) You have written a highly
               | specialized renderer that cannot be reused across
               | programs, as it requires all GPU resources used in any
               | scene to fit into memory at once (and for their exact
               | quantity to be known).
               | 
               | Once you acknowledge that asking for dynamic GPU resource
               | allocation, the rest of what I asked about follows; for
               | instance, you can't reuse whatever portion of the
               | already-allocated resources were freed at the end of the
               | frame unless you can track used resources across frames;
               | you can then either trace the open command buffers each
               | frame or whatever (tracing all the live resources) or use
               | something like reference counting and free once the fence
               | is done (tracing all the dead resources). Hopefully you
               | will acknowledge neither of these is the same as arena
               | allocation.
               | 
               | "dynamic GPU resource application isn't needed for a
               | useful renderer" certainly sounds good, but again does
               | not jive with my experience with renderers (admittedly,
               | most of this involves rendering an open world with
               | streaming assets, but most examples I've seen that aren't
               | super tightly constrained examples require resource reuse
               | of some sort).
        
               | skohan wrote:
               | I think you are not thinking through all the
               | possibilities here, but you would be surprised how far
               | you can get with this approach
        
           | gwmnxnp_516a wrote:
           | It is possible to write safe-C, but C is far more error prone
           | than C++. C has more implicit type conversions than C++,
           | which may results in bugs and undefined behaviours. C lacks
           | RAII (Resource-Acquisition Is Initialization) that is useful
           | for memory and resource management. C will actually require
           | more code than C++ since, the C standard library lacks
           | generic data structures such as vectors, hash maps, linked
           | lists and so on. The implementation of those data structures
           | requires lots of preprocessor macro hacks.
           | 
           | It is possible to write safe C, only if one uses static
           | analysis tools and undefined behaviour sanitizers. In the
           | case presented by the article, as it is related to game,
           | safety does not matter much, unlike device drivers, operating
           | systems or embedded systems where C bugs can introduce
           | security vulnerabilities.
           | 
           | Regarding the compile-time complaint, it is possible to
           | reduce the compile-time by using forward declarations;
           | forward template declarations; template forced instantiation
           | and isolating large parts of a project in a static library
           | using CMake.
        
             | Koshkin wrote:
             | > _C is far more error prone than C++_
             | 
             | I don't know about that... C++ (both the language and the
             | library) is orders of magnitude more complex, and the
             | opportunities to make mistakes have grown almost
             | proportionally. (Two characteristic examples recently
             | discussed here on HN: auto references and iterator
             | invalidation.)
        
               | kaba0 wrote:
               | There are two problems here, one being complexity, the
               | other being abstraction power. The two correlates. C is
               | an easy language without much complexity, but with
               | laughably little abstraction power. Text-based macros are
               | the worst thing ever, and other than that, the language
               | can't even express reusable data structures, only with
               | convention.
               | 
               | C++ on the other hand has good expressivity that can
               | better deal with complexity of programs (eg. just simply
               | having string, vector, etc) at the expense of some added
               | language complexity. But unfortunately most of that is
               | due to backward compatibility.
               | 
               | My opinion is that program complexity is inherent for
               | anything interesting, so the C++ tradeoff is worthwhile.
               | Also, by sticking to a good subset of C++, one can
               | minimize the "bad" complexity of the language, imho.
        
               | gwmnxnp_516a wrote:
               | But C lacks even strings, lots of C bugs and
               | vulnerabilities are related to memory management, memory
               | ownership and string handling. Even the C subset of C++
               | is better than C since it at least has more explicit type
               | conversions that forces the developer to state his or her
               | intent. One example of the C string problem is the
               | strcpy(buffer, char* string) that copies a string to a
               | buffer. If an external actor discovers how to manipulate
               | the string size, he or she can take advantage of this
               | buffer overflow vulnerability and even execute arbitrary
               | code remotely if it is used in a server. If the
               | application with this problem is a file, one create a
               | specially crafted file to take advantage of this design
               | flaw.
               | 
               | However using C in the case of the original poster does
               | not matter much as the application is game-related not
               | subject to untrusted input.
        
         | jimbob45 wrote:
         | I agree he used a trash example. I would offer include
         | guards/pragma once as a slightly better example.
        
         | badsectoracula wrote:
         | FWIW i've seen a lot of 3D codebases in C++ that avoid operator
         | overloading and instead use something like
         | `A.multiply(B).add(c)` to make more explicit what is going on.
         | Some even break that into multiple calls instead of using a
         | single expression.
        
           | qalmakka wrote:
           | The confusion created by operator overloading is easily
           | solved by tooling. The compiler always knows what a given
           | operator resolves to, and environments like Visual Studio
           | Code with the right plugins can handily highlight what you
           | are actually calling.
           | 
           | Also I think that like everything in C++ it's a matter of not
           | abusing a given feature. It's still useful to have the
           | ability to overload operators because it makes the intent
           | behind certain operations much clearer. There's nothing worse
           | than not being able to address an ArrayList in Java with the
           | subscript operator.
           | 
           | Nowadays I don't use operator overloading in C++ a lot, it's
           | mostly `=`, `==`, `<=>`, `bool`, `*`, `->`.
        
           | maccard wrote:
           | That's still better than matrix_add(c, matrix_mul(b, a))
           | though - you can't do A.mul(B).add(C) in C
        
           | framerate wrote:
           | You'll find a lot of SIMD code using the multiple calls
           | approach as for far too long C++ compilers did daft things
           | like transfer the SIMD registers back to the stack or refuse
           | to inline when the expression got slightly interesting.
        
           | jolux wrote:
           | I fail to understand how that's more explicit to be perfectly
           | honest. If it's hard to resolve where overloads are coming
           | from then that's a problem but otherwise it just seems more
           | verbose for no benefit. Addition and multiplication are the
           | operations in use here, why shouldn't we use their operators
           | to represent them?
        
             | humanrebar wrote:
             | I like operator overloading, but it is susceptible to
             | argument dependent lookup while member methods are not. The
             | syntax is literally more explicit about what logic is being
             | called.
        
             | gravypod wrote:
             | In situations where the output's shape changes based on the
             | operation this can be helpful.                   auto
             | accumulate = ...;         auto a = ...         auto b = ...
             | auto result = a*b;         for (int row = 0; row < a.rows)
             | {             accumulate += result[row]         }
             | 
             | This expression might be entirely valid when a and b are
             | both 2x2 but then becomes incorrect when there's a
             | different shape in b.
        
               | CyberDildonics wrote:
               | Do you mean type instead of shape? I also don't know what
               | you mean by incorrect. C will also create casts when
               | using two different number types in a math operation.
        
               | gravypod wrote:
               | For matrix and quaternions multiplication does not output
               | the same type as the input.
               | 
               | For example:                   int a = 1;
               | a + a = 2; (int)         a * 2 = 2; (int)
               | auto ma = matrix<2, 4>();         auto mb = matrix<4,
               | 1>();               ma * a  is matrix<2, 4>         ma *
               | ma is not possible         ma * mb is matrix<2, 1>
               | 
               | Compilers used to be very bad at telling you what was
               | going on here if you, for example, changed `<2, 4>` to
               | `<3, 4>` or something. g++ now handles it pretty well:
               | https://hastebin.com/idemopikag
        
               | CyberDildonics wrote:
               | Your original comment was about something being
               | incorrect, now you are talking about error messages, but
               | I don't think either has to do with operator overloading.
        
             | duped wrote:
             | There is more than one definition of a matrix or vector
             | product and whichever one is most obvious can be
             | contextual.
        
         | userbinator wrote:
         | "safety" is really overrated. The paranoia-fueled security
         | industry has turned programming into some sort of weird
         | authoritarian dystopia.
        
           | z0ltan wrote:
           | You've done it now. Get ready for the vengeance of the RDF
           | (Rust Defence Force).
        
           | wyager wrote:
           | Is this a joke? Do you really think _managed pointers_ are an
           | example of authoritarian dystopianism?
        
             | greesil wrote:
             | unique_ptr is a conspiracy, man. You see, the people who
             | make money off of mallocs (those corrupt DRAM
             | manufacturers) want it to stay that way. Just follow the
             | money.
        
             | aksss wrote:
             | Thread safety is like bicycle helmet laws, discuss..
        
               | cjfd wrote:
               | Well, kind of. I would argue that most code does not need
               | to be thread safe because it is not intended to run in a
               | multi-threaded environment. I once worked on a
               | application where it was 'standard' to run everything in
               | a thread pool so basically everything could run
               | simultaneous to everything else. Problem was that there
               | also was lots of state to manage. So then one ends up
               | giving every class one or more locks. Also, this
               | particular application was not the high-performance part
               | of the application. Obvious solution is to run most of
               | the application in a single thread message loop and get
               | rid of all of the locks. This appears to be heresy
               | nowadays though. The high profile C++-ers tell us that
               | everything has to be thread safe.
        
               | Jweb_Guru wrote:
               | > Well, kind of. I would argue that most code does not
               | need to be thread safe because it is not intended to run
               | in a multi-threaded environment.
               | 
               | In that case you are actually thread safe, though! Just
               | use a language that lets you specify which data can't be
               | sent across threads (Rust isn't the only example, Erlang
               | enforces this entirely dynamically) and use thread locals
               | instead of statics (in a single threaded environment
               | they're effectively the same thing), and tada, you have
               | thread safety that continues to work even if people
               | decide to run your stuff on many different cores.
        
               | beached_whale wrote:
               | One would, but without a barrier the head hit before
               | slowing waiting for the group the ground to get out of
               | the critical section :)
        
             | Santosh83 wrote:
             | He is talking (I believe) about the general trend of
             | nudging, cajoling more and more coders into using managed,
             | very high level, safe languages and runtimes, and in
             | general discouraging peeking under the hood, at the
             | hardware level, as something raw, wild or unsafe. Yes you
             | can still do it on a RPi, but perhaps in another decade or
             | so, you might not be allowed to program in 'unsafe'
             | languages on all other mainstream platforms, unless you
             | register for a driver/system developer license or
             | something, or not even that.
             | 
             | The tinkerer/hacker ethos is disappearing slowly from PCs.
             | It never caught on in the mobile world. It may perhaps only
             | survive as a remnant in specialised chips and boards
             | designed for learning.
        
               | maccard wrote:
               | to be clear, you're claiming that language constructs for
               | avoiding massively prevalant use-after-free bugs
               | (unique_ptr) will lead us all to lose control of our
               | devices?
               | 
               | Nobody's suggesting we replace all the C in the world
               | with signed javascript from Google, we're literally
               | talking about compile time checks for pointers here.
        
               | jolux wrote:
               | > the general trend of nudging, cajoling more and more
               | coders into using managed, very high level, safe
               | languages and runtimes
               | 
               | This is a good thing: these languages and runtimes are
               | indeed much safer, and also much more productive than C.
               | You can even still get the same amount of low-level
               | control with Rust.
               | 
               | > in general discouraging peeking under the hood, at the
               | hardware level, as something raw, wild or unsafe.
               | 
               | C _is_ unsafe though. Decades of experience writing
               | software has shown us that even expert C programmers
               | write memory bugs with regularity.
               | 
               | > Yes you can still do it on a RPi
               | 
               | Or any other PC really.
               | 
               | > but perhaps in another decade or so, you might not be
               | allowed to program in 'unsafe' languages on all other
               | mainstream platforms, unless you register for a
               | driver/system developer license or something, or not even
               | that.
               | 
               | Lunacy. What is the evidence for this?
               | 
               | > The tinkerer/hacker ethos is disappearing slowly from
               | PCs.
               | 
               | It was only ever there in the first place with a tiny
               | minority of users, and that minority seems as committed
               | to their craft as they've ever been.
        
               | userbinator wrote:
               | _Lunacy. What is the evidence for this?_
               | 
               | Look at all the locked-down walled-garden platforms
               | proliferating, and this famously prescient story:
               | https://www.gnu.org/philosophy/right-to-read.en.html
               | 
               | 20 years ago, many people thought RMS was a completely
               | insane lunatic. Yet now he seems more like a prophet.
               | 
               | It's not hard to see where things are going if you read
               | between the lines. Increasingly, "safety and security" is
               | being used to exert control over the population and
               | destroy freedom. Letting your children play outside
               | unsupervised is "unsafe". Non-self-driving cars are
               | "unsafe". Eating certain food is "unsafe". Having a
               | rooted mobile device is "unsafe". Not using an approved
               | browser by a company that starts with G is "unsafe". ...
               | Programming in C is "unsafe".
               | 
               | "Freedom is not worth having if it does not include the
               | freedom to make mistakes."
        
               | mwcampbell wrote:
               | > "Freedom is not worth having if it does not include the
               | freedom to make mistakes."
               | 
               | That's only true to a point. Many mistakes are costly,
               | and those costs are often born by other people. So it's
               | reasonable to have protection against mistakes, for the
               | benefit of both the person who would make them and the
               | other people that they would affect.
               | 
               | When it comes to computer security in particular, an
               | easily compromised personal computer can be devastating
               | to the livelihood of the person whose computer was
               | compromised through no fault of their own (remember, most
               | people don't know anything about computer security, _and
               | they shouldn 't have to_), and can also harm others, e.g.
               | if the computer becomes part of a botnet. If that
               | computer is part of an organization, then the mistake
               | made by a programmer can affect the ability of that
               | organization to provide important, even essential,
               | services. _This_ is what 's driving the increased focus
               | on safety in this context.
               | 
               | I realize we're drowning in cynicism these days, and it's
               | tempting to think that it's all an evil conspiracy to
               | take away our freedom so a few people can make more money
               | or have more power. Such a narrative resonates with
               | something primal in us that's reinforced by the sort of
               | simplistic good versus evil stories that make up so much
               | of our entertainment. Reality is messier, more nuanced,
               | and not as neatly connected as our puny pattern-seeking
               | brains would prefer.
        
               | pjmlp wrote:
               | 20 years ago many people earned a living selling
               | commercial compilers, and the PC was the exception to
               | vertical integration.
               | 
               | Plenty of people knew what RMS was talking about.
               | 
               | But GPL was very bad for business, said those there were
               | against it, so the new world of shareware and public
               | domain is here again.
        
               | woodruffw wrote:
               | > Look at all the locked-down walled-garden platforms
               | proliferating
               | 
               | I don't think I'm getting the connection here --- Rust
               | was incubated at Mozilla and is now managed by its own
               | open-source foundation. There's nothing particularly
               | closed or "walled garden" about it.
               | 
               | By contrast, Apple's ecosystem is the canonical example
               | of a walled garden. But it's overwhelmingly programmed in
               | unsafe languages (C, C++, and Objective-C). So what
               | gives?
               | 
               | > It's not hard to see where things are going if you read
               | between the lines. Increasingly, "safety and security" is
               | being used to exert control over the population and
               | destroy freedom
               | 
               | This is an eye-poppingly confusing confabulation: in what
               | world am I any less free because the programs I write and
               | use have fewer trivial vulnerabilities in them? What
               | freedom, exactly, have I lost by _choosing_ to crash
               | less?
               | 
               | You bring up the GNU project; their background is
               | explicitly rooted in Lisp: one of the _very first_ safe,
               | managed languages. The unsafety and comparative messiness
               | of C is one of their standard bugbears. That hasn't
               | stopped their message of political and software freedom,
               | as you've pointed out.
        
               | pjmlp wrote:
               | Actually GNU project is one of the culprits for C
               | spreading into a world of that was already moving into
               | C++ and other safer languages.
               | 
               | > When you want to use a language that gets compiled and
               | runs at high speed, the best language to use is C. C++ is
               | ok too, but please don't make heavy use of templates. So
               | is Java, if you compile it.
               | 
               | https://www.gnu.org/prep/standards/html_node/Source-
               | Language...
               | 
               | 20 years ago, it was more like
               | 
               | > When you want to use a language that gets compiled and
               | runs at high speed, the best language to use is C. Using
               | another language is like using a non-standard feature: it
               | will cause trouble for users. Even if GCC supports the
               | other language, users may find it inconvenient to have to
               | install the compiler for that other language in order to
               | build your program. For example, if you write your
               | program in C++, people will have to install the GNU C++
               | compiler in order to compile your program. > > C has one
               | other advantage over C++ and other compiled languages:
               | more people know C, so more people will find it easy to
               | read and modify the program if it is written in C.
               | 
               | http://gnu.ist.utl.pt/prep/standards/html_node/Source-
               | Langua...
               | 
               | Thank GNU for C.
        
               | woodruffw wrote:
               | > Actually GNU project is one of the culprits for C
               | spreading into a world of that was already moving into
               | C++ and other safer languages.
               | 
               | Both of these things can be true! GNU has advocated for C
               | for some pretty asinine reasons. At the same time,
               | they've ported all kinds of Lisp idiosyncrasies into
               | their style guide.
        
               | loup-vaillant wrote:
               | With the possible exception of Rust, safety always had
               | performance implications. Forcing people to write their
               | program in C# or Swift or Java causes many programs to be
               | slower than they really need to be, forcing us to either
               | wait on them, or buy a faster palmtop.
               | 
               | (Now most devs don't care about performance, so they
               | don't see that as a problem. As a user however I can tell
               | you, I _hate_ when my phone lags for seemingly no good
               | reason.)
        
               | woodruffw wrote:
               | > With the possible exception of Rust, safety always had
               | performance implications.
               | 
               | This is common piece of received wisdom, but I don't
               | think it's held up well over the last decade: both Java
               | and C# have extremely well-optimized runtimes that
               | perform admirably after an initial startup period, and (I
               | believe) Swift compiles to native code with many of the
               | same optimization advantages that Rust has (e.g., simpler
               | alias analysis).
               | 
               | At the same time, C++ has seen a proliferation of
               | patterns that are _slightly_ safer, but perform miserably
               | at scale: smart pointers (unnecessary lock contention),
               | lambdas (code bloat, more I$ pressure), templates (I$),
               | &c. C avoids most of these, but C written by "clever"
               | programmers has similar pitfalls.
        
               | skohan wrote:
               | > these languages and runtimes are indeed much safer, and
               | also much more productive than C. You can even still get
               | the same amount of low-level control with Rust.
               | 
               | Rust is not a C analog. The whole value proposition of C
               | is simplicity, and Rust is anything but simple.
               | 
               | >> but perhaps in another decade or so, you might not be
               | allowed to program in 'unsafe' languages on all other
               | mainstream platforms, unless you register for a
               | driver/system developer license or something, or not even
               | that.
               | 
               | > Lunacy. What is the evidence for this?
               | 
               | Look at a platform like Apple. Every release makes it
               | harder to run arbitrary code.
               | 
               | >> The tinkerer/hacker ethos is disappearing slowly from
               | PCs.
               | 
               | >It was only ever there in the first place with a tiny
               | minority of users, and that minority seems as committed
               | to their craft as they've ever been.
               | 
               | What do you mean? In early PC's, the way you ran software
               | was to copy code from a magazine and compile and run it
               | on your workstation. Being a PC user _at all_ meant being
               | a tinkerer /hacker a few decades ago.
        
               | bfrog wrote:
               | Rust is arguably simpler than C++ to comprehend, and
               | sure, more complex than simple C.
               | 
               | But the complexity argument is overblown.
        
               | skohan wrote:
               | I didn't say anything about C++.
               | 
               | Rust is a very complex language. You can argue about
               | whether it's more or less complex than C++, but it's
               | certainly on that end of the spectrum. C is way on the
               | other end.
               | 
               | That's not a value judgement of Rust, just an
               | observation.
        
               | woodruffw wrote:
               | > C is way on the other end.
               | 
               | Rust is complex, but I think it's honest in its
               | complexity: it straddles programmers with lifetime
               | management in exchange for better optimizations (alias
               | analysis is a pain in C!) and memory safety.
               | 
               | This is in contrast to C: it's very easy to write C that
               | compiles, but very difficult to fully evaluate its
               | correctness. Part of that is the _extraordinary_
               | complexity of the C abstract machine, combined with its
               | leakiness: writing correct C requires you to understand
               | both your ISA's memory model and the set of constraints
               | inconsistently layered on it by C. That's a kind of
               | pernicious complexity that Rust doesn't have.
        
               | jolux wrote:
               | > Rust is not a C analog. The whole value proposition of
               | C is simplicity, and Rust is anything but simple.
               | 
               | I would say the value proposition is control and
               | performance, and more pragmatically ubiquity. If the
               | value proposition were simplicity, why aren't C
               | programmers writing Lisp instead? If it's simplicity and
               | control, why aren't they writing assembly? At this point,
               | C is little more than a bad abstraction that people are
               | nostalgic for.
               | 
               | > Look at a platform like Apple. Every release makes it
               | harder to run arbitrary code.
               | 
               | No, it doesn't. It has not gotten harder to run arbitrary
               | code. It has gotten harder for developers to distribute
               | unsigned applications. I've been using Macs for 10 years
               | and my setup process throughout that whole time has been:
               | xcode-select --install, install Homebrew, get on with my
               | life. The OS never interferes with my programming beyond
               | that.
        
               | catblast01 wrote:
               | > In early PC's, the way you ran software was to copy
               | code from a magazine and compile and run it on your
               | workstation. Being a PC user at all meant being a
               | tinkerer/hacker a few decades ago.
               | 
               | Bullshit. Except for the brief period of time when the
               | Altair was the only thing going on in the Micro space...
               | the Apple II, Atari 800, IBM PC and TRS-80 amongst others
               | were marketed in the late 70s/early 80s with off the
               | shelf, ready to run software. While copying code out of a
               | magazine was something you could do, it wasn't even the
               | common case then.
               | 
               | > Every release makes it harder to run arbitrary code.
               | 
               | I have not experienced this. Yes Mac OS makes it harder
               | to run random stuff downloaded from the internet, but
               | Llvm, clang, cmake, python from the command line works
               | the same as they always have (you are fetishizing code
               | that is entered yourself after all).
        
               | skohan wrote:
               | The new windows does not even run on hardware which
               | doesn't have TMP. You really don't see signs that
               | computers are getting more closed?
        
               | pjmlp wrote:
               | PC was an accident caused by IBM's failure to put Compaq
               | into line.
               | 
               | All other platforms were hardly any different from Apple,
               | in fact Apple is just like they always have been
        
               | forgotmypw17 wrote:
               | >What is the evidence for this?
               | 
               | There are entire CLASSES of computing devices which you
               | cannot put arbitrary code on without severe obstacles...
        
               | kaba0 wrote:
               | How exactly is it relevant to the topic? What does it
               | have to do with ditching C?
        
               | patrick451 wrote:
               | Safety above all is is the path towards slavery.
               | 
               | This is true in both politics and software.
        
               | kitd wrote:
               | _This is a good thing: these languages and runtimes are
               | indeed much safer, and also much more productive than C.
               | You can even still get the same amount of low-level
               | control with Rust._
               | 
               | How do you bootstrap languages like Rust? Another 'safe'
               | language? What about that one?
               | 
               | Someone somewhere has to be working at the asm level.
        
               | dthul wrote:
               | Bootstrapping and language safety are orthogonal. C is
               | unsafe and still you can't bootstrap it if you don't
               | already have a compiler which can compile your C
               | compiler. According to that logic even assembly is not
               | low level enough because you need an assembler to make a
               | runnable program out of it.
        
               | pjmlp wrote:
               | Source code available,
               | 
               | http://www.projectoberon.com/
        
               | nemothekid wrote:
               | Safety is complete orthogonal to being a bare-metal
               | language (See Rust). You can have a completely locked
               | down platform with an unsafe language (See iOS).
               | 
               | I'd argue that anyone who thinks language safety is some
               | authoritarian handcuff doesn't really understand low-
               | level programming to begin with.
        
               | skohan wrote:
               | I actually think safety should be guaranteed at an
               | OS/hardware level and not at a software level. If it's
               | guaranteed that my process can only make a mess inside
               | it's own memory allocations, let the software be as
               | unsafe as it wants.
        
               | Thiez wrote:
               | Then you'll be happy to learn that what you propose has
               | been the case for consumer computers since protected mode
               | was added to Intel 80286 processors in 1982.
               | 
               | I think few people in this discussion are worrying about
               | programs directly affecting other programs through memory
               | unsafety, exactly because this doesn't really happen for
               | software that isn't a driver or inside the OS kernel. The
               | problem with memory unsafety is that it often allows
               | exploits that corrupt or steal user data, or gain
               | unauthorized access to a system. That's not a problem
               | when you are the only user of your software and you only
               | have access to your own data, but once you have other
               | peoples data or run on other peoples system I think you
               | should at least consider the advantages of using a
               | safe(r) language.
        
               | skohan wrote:
               | But I don't understand how data stealing can happen if
               | each process is effectively sandboxed. If my process
               | can't read or write to memory outside of what it
               | allocated, how can I corrupt or steal user data?
        
               | Thiez wrote:
               | Well it depends on your definition of sandboxed. Does
               | your program have permission to perform I/O, either by
               | reading/writing to a filesystem or sending/receiving data
               | on a network?
               | 
               | Most "interesting" programs can perform I/O. Then you run
               | into ambient authority and confused deputies.
        
               | skohan wrote:
               | Yeah I guess it seems like a decent model for "safe"
               | software would be sandboxed memory, and fine-grained file
               | permissions. Arbitrary network traffic is a bit less
               | dangerous - I mean someone could steal CPU cycles to
               | process data and send it over network, but a safe
               | language is not going to save you from that either.
               | 
               | Most programs do not need arbitrary access to the file
               | system, and it should be the OS's job to whitelist which
               | files a program has access to. Again, a safe language is
               | not going to save you from bad behavior on the filesystem
               | either. It really only solves the memory problem.
        
               | Thiez wrote:
               | > Most programs do not need arbitrary access to the file
               | system, and it should be the OS's job to whitelist which
               | files a program has access to. Again, a safe language is
               | not going to save you from bad behavior on the filesystem
               | either. It really only solves the memory problem.
               | 
               | Except that it is often a memory-safety problem that
               | enables an attacker to make a program misbehave, through
               | things like buffer overflows. A memory-safe program is
               | much harder to exploit.
        
               | skohan wrote:
               | Are we talking in circles here? My original point was
               | that memory safety should be ensured by the OS/hardware.
               | That way no matter how badly my program misbehaves, it
               | will not be able to access memory outside of the sandbox.
               | In other words, the CPU should not be able to address
               | memory which has not been allocated to the current
               | process. A buffer overflow should be a panic.
               | 
               | Even with a safe language, there's vulnerabilities like
               | supply chain attacks which allow malicious code to use an
               | escape hatch to access memory outside of the process.
               | I.e. I could be programming in Rust, but one of the
               | crates I depend on could silently add an unsafe block
               | which does nefarious things. OS/hardware level sandboxing
               | could prevent many such classes of exploits.
        
               | kaba0 wrote:
               | > That way no matter how badly my program misbehaves, it
               | will not be able to access memory outside of the sandbox
               | 
               | The problem is not about memory outside of the sandbox,
               | but inside. Please read about return-oriented
               | programming, for example, where a buffer overflow bug of
               | a process can be exploited to hijack said process to do
               | work it was not meant to do normally. If this error
               | happened for example in sudo, it can very well be used to
               | gain privileges and do real harm -- and this whole
               | problem domain is almost entirely solved by using a
               | "safe" language.
        
               | kaba0 wrote:
               | In case of a browser, a buffer overflow can be exploited
               | to upload user files for example -- which are very much
               | readable without trouble on most linux distros.
        
           | gravypod wrote:
           | "I know my software just works" is really hubris. The fly-by-
           | the-seat-of-our-pants game industry has cranked up
           | programmers egos and made them ignore a wide range of tools
           | and practices that have been proven time and time again to
           | improve developer velocity and reduce defects.
        
             | userbinator wrote:
             | "proven" sounds like cargo-culting dogma. The same was said
             | of OOP in the 90s, and look what that caused. Hence my
             | distrust of the snake-oil.
             | 
             | Also, my real-world experience with wading through the
             | abstraction insanity often seen in C++ (and justified
             | because it's "safer") to find and fix bugs, and even more
             | so with the sheer baroqueness of Enterprise Java (arguably
             | an "even safer language"), shows that "reduce defects" is
             | more like a dream. Maybe the number is reduced but when one
             | is found, it tends to be harder to fix.
             | 
             | Put another way, I'd rather fix relatively simple C (which
             | also tends to be simpler code in general) than the monsters
             | created by "modern C++" because they thought the "added
             | safety" would mean they could go crazy with the complexity
             | without adding bugs. Perhaps there is some sort of risk
             | compensation going on.
             | 
             | The saying "C makes it easy to shoot yourself in the foot;
             | C++ makes it easy to blow the whole leg off" comes to mind.
        
               | christophilus wrote:
               | I think that if we focused on building small, simple
               | programs that do one thing well and compose, C would be
               | OK. It's when we build out behemoths that you really have
               | a hard time reasoning about your code. At that point,
               | vulnerabilities are almost guaranteed. This is true in
               | any language, but more so in unsafe ones.
               | 
               | Maybe the suckless guys are on to something.
        
               | kaba0 wrote:
               | The complexity that _must_ arise (otherwise the problem
               | we are looking at is not interesting enough) will happen
               | either way. Composing small tools will give you an ugly
               | as hell glue code over them -- just imagine a modern
               | browser. Would it really be better to do curl and
               | interpretJS and buildDOM and all these things? Just
               | imagine writing the glue code for that in what, bash?
               | 
               | We pretty much have exactly that, but better with
               | programming languages composing libs, functions and other
               | abstractions. That's exactly the same thing but at a
               | different (better) level.
        
               | gravypod wrote:
               | There's a bug difference between extremely complex c++
               | templates and std::unique_ptr, std::string_view, and
               | constexpr. Also, I've heard many game devs still saying
               | unit tests either take too long to write or they aren't
               | helpful.
        
               | pjmlp wrote:
               | For the corpse it makes little difference how it got hit.
        
               | aliswe wrote:
               | its amazing to read such a contrarian viewpoint, i dont
               | agree but its somehow fresh to read
        
               | maccard wrote:
               | > Put another way, I'd rather fix relatively simple C
               | (which also tends to be simpler code in general) than the
               | monsters created by "modern C++" because they thought the
               | "added safety" would mean they could go crazy with the
               | complexity without adding bugs.
               | 
               | It's completely possible to write C++ code without it
               | being a mess of a template mostrosity and massively
               | overloaded function names. People who write C++ like that
               | would write C filled with macros, void pointers and all
               | the other footguns that C encourages you to use instead.
               | 
               | I've been working with the sentry-native SDK recently [0]
               | which is a C api. It's full of macros, unclear ownership
               | of pointers (in their callback, _you_ must manually free
               | the random pointer, using the right free method for their
               | type, which isn't type checked), custom functions for
               | working with their types (sentry_free,
               | sentry_free_envelope), opaque data types (everythign is a
               | sentry_value_t created by a custom function - to access
               | the data you have to call the right function not just
               | access the member, and this is a runtime check).
               | 
               | See [1] (their C api example). With function overloading
               | and class methods it would be much more readable.
               | 
               | [0] https://github.com/getsentry/sentry-native [1]
               | https://github.com/getsentry/sentry-
               | native/blob/master/examp...
        
             | everyone wrote:
             | I'm a game dev and imo web-devs are the 'seat-of-our-pants'
             | guys. In games we tend to use compiled and statically typed
             | languages. They're pretty strict in what they allow and
             | many errors are picked up by the IDE and/or prevent your
             | code from even compiling.
             | 
             | Whereas javascript.. Your code could be doing almost
             | _anything_ yet it will run just fine. Also, cus its not
             | compiled the IDE for javascript is much much less helpful
             | (eg. theres no  "find all references") and much more
             | permissive.
        
               | vvanders wrote:
               | I think it depends on a lot on the studio and culture. I
               | don't think I saw a single unit tests before I left
               | gamedev(a few smoketests to make sure the game didn't
               | crash but that was about it).
               | 
               | I also rebuilt our audio streaming system over the course
               | of 48 hours to use the texture streaming subsystem when
               | we exceeded the 64 file handle limit on an certain
               | platform. We needed to hit a date for a TGS demo and I
               | can guarantee you that we had things which were even more
               | YOLO for a fairly decently sized team/game.
        
               | christophilus wrote:
               | To be honest, the game industry is a good counterpoint to
               | TDD zealotry. You can go quite far with adequate results
               | without a single unit test.
        
               | gravypod wrote:
               | Some of the most buggy software I interface with are
               | games. They crash and break in strange ways. I often
               | wonder what it would be like if someone tested some edge
               | cases or enabled a fuzzer for some functions. Like "what
               | happens if I kill a freed entity", or "what happens if my
               | character is 50% in a wall", etc.
               | 
               | Some of these bugs are experience ruining: think Fallout
               | 76.
        
             | oreally wrote:
             | And on the flip side tech gets Leetcode interviews,
             | shoehorned microservices when you dont need it, slow web
             | browsers.
             | 
             | The game industry iterates far faster and the result are
             | programs that can handle far more features than the average
             | tech methodology. It's the classic quantity leads to
             | quality pottery grading experiment. Have you ever
             | considered that these 'best practices' pile on so much
             | unneeded crap that an experienced developer doesn't need?
        
               | kaba0 wrote:
               | I would not necessarily say that game development has
               | better quality than web browsers. And the latter are
               | anything but slow -- they are engineering marvels no
               | matter what you think of them. It's just that websites
               | like to utilize it shittily.
        
               | oreally wrote:
               | There's a lot of games out there, way more than there are
               | web browsers. For a start try comparing games with
               | manpower/dev support levels similar to a web browser like
               | chrome. If we take a AAA open world game, the game
               | somehow gets more features done compared to chrome.
               | There's something that can be learnt there.
               | 
               | Also last I heard there was a startup aiming to solve
               | slow browsers by running chrome in a server and streaming
               | a video of the window somewhere. If that's not a setback
               | I don't know what is.
        
               | kaba0 wrote:
               | > There's a lot of games out there, way more than there
               | are web browsers.
               | 
               | Maybe this should tell you something about the relative
               | complexity of the two problems. And frankly, features in
               | a game are non-comparable to browser features.
        
           | leetcrew wrote:
           | there's a lot of overlap between safety and correctness.
        
           | taneq wrote:
           | Yeah man bring back peek() and poke() haha live life on the
           | edge!
        
           | TwoBit wrote:
           | You forgot to add /s to the end of your comment.
        
           | duped wrote:
           | I for one appreciate fewer programs segfaulting due to
           | unexpected input, the security is just a bonus
        
         | Koshkin wrote:
         | > _you can use float* in C++ too_
         | 
         | But then why bother with C++ at all, right?
         | 
         | > _more compact and readable_
         | 
         | This: overloading of operators (and function) is one of the
         | biggest draws of C++ (along with RAII and templates).
        
         | socialdemocrat wrote:
         | People get blinded by features. At the end of the day, what
         | influence your ability to write safe code is the human brain.
         | You have to be able to reason about and understand the code
         | effectively to discover and fix problems.
         | 
         | Ironically C++ by adding a ton of features to make the language
         | "safer" basically achieves the opposite. Complexity obscures
         | how your code works and thus aids in hiding critical bugs.
         | 
         | I have had so many cases with obscure bugs the 15 years I used
         | C++ that simply would be impossible to reproduce in C.
         | 
         | Does it mean I advocate C for safer coding? Not at all, but I
         | think the advantage of C++ is grossly overstated.
         | 
         | Languages such as Go are better examples for writing safe code.
         | Why? Because they quite strong type safety and good memory
         | semantics while not adding too high complexity to the language.
         | Everything is far more explicit than in C++ which has too much
         | "magic" and implicit behavior.
        
           | [deleted]
        
           | kaba0 wrote:
           | C++ can introduce bugs by obscuring the flow of code, but it
           | can also alleviate many instances by having proper
           | abstraction power. It's about balance.
           | 
           | I would say both C and Go falls into the "most lines are
           | readable, but the whole is not" camp, due to not enough
           | abstraction. For smaller programs one can hold in memory it
           | may be good, but it doesn't scale.
        
         | dasb wrote:
         | Can someone tell me what it means that "float is unsafe"? I'd
         | never heard about that.
        
           | nly wrote:
           | The * has been erased by HN's markup.
        
           | maccard wrote:
           | It's actually float* - which is a pointer to a float (hn's
           | formatting can eat these sometimes)
           | 
           | example:                   float* f = GetF();         // In a
           | C world, you rely on the documentation to tell you how long f
           | is valid for.          SomeFunc(*f);              // We
           | _know_ this is safe.         std::unique_ptr<float> f =
           | GetF();         SomeFunc(*f.get());
        
           | bionade24 wrote:
           | The statement was made about a float pointer. Still float
           | precision is a problem beginners run into, too. So maybe
           | it'll will help one reading it somewhen.
           | 
           | float a = 0.1f * 0.1f; assert((a - 0.01f) < 0.0001); <--
           | Works assert(a == 0.01f); <-- Will fail
        
           | [deleted]
        
       | suby wrote:
       | >So what is the bare minimum? To use the GPU, I need a graphics
       | API. Vulkan is the one that is most widely supported so that is a
       | natural choice
       | 
       | Vulkan can't possibly be the most widely supported graphics API
       | can it? I have to imagine that targeting older hardware is better
       | with OpenGL because it's been around forever, but I don't
       | actually know and a quick google search doesn't turn up much.
        
         | pjmlp wrote:
         | It isn't, it is also not available on game consoles (Swift
         | supports it, but also has GL 4.6 and NVN), or any Android
         | device lower than 10.
         | 
         | Even with 10 or later, if not using Google or Samsung flagship
         | devices, you will bump into driver issues.
        
         | nly wrote:
         | There are lots of Windows machines around with subpar or buggy
         | OpenGL implementations.
         | 
         | I used to develop a Qt/QML app for Windows it was impractical
         | to leave hardware acceleration enabled. In then end, using
         | Mesa/llvmpipe everywhere was just more reliable.
        
         | AussieWog93 wrote:
         | You're right.
         | 
         | I did some graphics work in my last job. OpenGL2 is supported
         | by just about every device made in the last 15 years, on every
         | major operating system, including software OpenGL in VMs.
         | 
         | Vulkan is not officially supported on OSX (although there is an
         | unofficial port that is quite good, from what I understand) and
         | only runs on modern hardware.
        
           | badsectoracula wrote:
           | And by "modern" we really mean released the last few years.
           | For example it doesn't run on my 2013 laptop (has a 660M GPU,
           | Nvidia supports Vulkan only from 7xx series) or my (late)
           | 2016 GPD Win (technically there is Vulkan 1.0 support under
           | Linux but not under Windows and AFAIK even the Linux driver
           | has issues).
        
           | bsder wrote:
           | The MoltenVK guys originally got their start creating a
           | commercial offering of OpenGL on top of Metal so that you
           | could skip the Apple OpenGL system.
           | 
           | Yeah, that's how crap Apple support for OpenGL is.
        
           | ninepoints wrote:
           | > Vulkan is not officially supported on OSX
           | 
           | And neither is OpenGL
        
             | Wowfunhappy wrote:
             | Deprecated, not unsupported.
             | 
             | And, like, Apple ported OpenGL to Apple Silicon macs. I
             | suspect it's going to stick around, it's just never, ever
             | going to get updated.
        
       | 1024core wrote:
       | I've always been impressed by Go's compile times. The first few
       | times I thought I'd made a mistake, and it was doing nothing (the
       | prompt came back so quickly). Now I know better :-)
        
         | christophilus wrote:
         | This is my favorite OCaml and Go feature, and one that I wish
         | all other languages would adopt.
        
       | qalmakka wrote:
       | Yesterday I finished a complex library in C++20, which I wrote
       | "Rust style" by following the ISO C++ guidelines. I used 0 `new`,
       | no smart pointers, all by-value returns, move semantics and STL
       | containers. It literally took a month to write, but it worked as
       | expected at the second attempt (first failed due to forgetting a
       | `}` in a format string). I did not see a single segmentation
       | fault and it works fine on both Linux and Windows. Rust and
       | modern C++ give you the expressivity to describe what you want to
       | accomplish to the compiler.
       | 
       | You can use the type system to erase certain classes of error
       | entirely, without ever having to worry about something pointing
       | to bad memory or whatever. If you follow certain rules, C++ can
       | be _almost_ as safe as Rust.
       | 
       | I love C personally, and I've been coding in it for more than a
       | decade now. It is simple, easy to learn, but it gives you
       | literally zero ways to create abstractions. That could be a good
       | thing, until you realize that almost all complex C codebases
       | reimplement (badly) half of the STL due to libc providing no
       | containers of sort. Linked lists are terrible for performance,
       | yet C programs are pestered with them due to how simple they are
       | to implement. And I won't get started with C strings, which are
       | just a historical BadIdea(tm).
       | 
       | Most C codebases tend naturally to evolve into a mishmash of
       | reinventing the wheel and ugly macro magic. After all it's either
       | that or to risk committing preventable mistakes all over.
       | 
       | That's not without saying that C++ is that better - every three
       | years a new release comes out and fixes certain issues so vastly
       | that it completely changes how you are supposed to write code
       | (see string_view, or concepts). That's not without saying that
       | the language is also full of old cruft no one should ever think
       | about using.
        
         | Zababa wrote:
         | How are the compile times? That's a really big point in the
         | article and you don't mention them at all.
        
         | MuffinFlavored wrote:
         | > And I won't get started with C strings, which are just a
         | historical BadIdea(tm).
         | 
         | What's the better alternative to null-prefixed strings you are
         | referring to, length prefixed?
        
         | andreidd wrote:
         | Is the library open source? If so, would you share a link?
        
           | qalmakka wrote:
           | Sorry but the source is closed sadly, so I can't share it. I
           | would like to write a blog post someday about some of the
           | patterns I've used though, I think they could be useful to
           | someone.
        
         | Santosh83 wrote:
         | Would you mind sharing a link to the ISO C++ guidelines you
         | mention?
        
           | detaro wrote:
           | presumably
           | https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines
        
             | qalmakka wrote:
             | That's correct. Also see https://github.com/microsoft/GSL,
             | which is a header-only C++ library that implements the
             | Guidelines Support Library as specified by ISO C++. It's
             | extremely useful (especially to get std::span<T> if you
             | don't have C++20 support) because it provides several
             | constructs to explicitly clarify the _intent_of your code,
             | like `gsl::not_null<T _> `, `gsl::narrow_cast<T>()` or
             | `gsl::owner<T_>`. `gsl::finally()` is also pretty useful.
        
       | phendrenad2 wrote:
       | Often the C vs C++ debate comes down to a religious war where the
       | C side is arguing that their hammer is best for pounding in nails
       | and the C++ side is arguing that their screwdriver is best for
       | screwing in screws. I don't believe they're suited for the same
       | purposes at all.
       | 
       | If you're writing code where you need to interface with the
       | hardware directly (embedded), or manipulate things in kernel-
       | space efficiently (OpenGL, audio, games), then C makes a lot of
       | sense (and if you try to write C++, you'll end up using C anyway,
       | and your attempts to shoehorn in C++ features will be
       | ineffective).
       | 
       | If you're writing a high-performance C++ version of a Python web
       | service, C++'s nicer memory management and string handling will
       | be very VERY useful, not to mention object types for
       | serializing/deserializing data.
        
         | kaba0 wrote:
         | I don't think this argument holds up. You can create very good
         | abstractions over the lower level libs, like OpenGL. There is
         | no need to call it "naked" like in C.
        
       | refactor_master wrote:
       | Meanwhile, a data science project in python runs right up until
       | it doesn't, and the only help you have is heuristics for why your
       | data maybe was bad.
       | 
       | I almost sort of envy compilation at times.
        
       | _wldu wrote:
       | I used C++ for a good while (systems programming). I like it and
       | still use it for some things. But when I started using Go, I used
       | C++ less and less. Go was simple like C and almost as fast.
       | 
       | There is a time and a place for all languages, but if I could
       | only have one, I'd probably pick C++. It can do almost anything
       | in whatever programming style you prefer. It really is the most
       | generic language I've ever used. That's both its strength and
       | weakness.
       | 
       | Also, the fact that C++ is standardized (ISO) and not controlled
       | by a company (Google, Microsoft, Apple) I feel it offers greater
       | freedom. No vendor lock-in.
        
       | ncmncm wrote:
       | Just sad.
       | 
       | If the language is not doing a great deal of your work for you,
       | then you are not using it right. Doing it right, things flow fast
       | and work right the first time. So, you don't care that it takes
       | 30 seconds to compile, because you coded all afternoon and then
       | compiled and it worked right away, with no debugging needed.
       | After that, coding C feels like a big PITA where you have to tell
       | the compiler everything over and over again, and need to compile
       | every few minutes just not to get too far into the weeds.
       | 
       | Any big system has some objecty bits, but O-O is a technique, not
       | a religion. Same for anything-oriented: functional, data-
       | oriented, what-have-you. Master the tools, don't be mastered by
       | them.
        
         | syockit wrote:
         | The compiler cannot catch logic or design errors. If you made a
         | mistake when designing the algorithm and implemented it as it
         | is, you'd need to debug anyway. Sometimes it's something as
         | simple as missing a minus symbol somewhere in your equations.
         | 
         | Working with Eigen was especially painful. All the template
         | magic it uses means what would have taken 1 second to compile
         | if used BLAS/LAPACK, now takes 10-20 seconds.
        
           | jcelerier wrote:
           | > The compiler cannot catch logic or design errors. If you
           | made a mistake when designing the algorithm and implemented
           | it as it is, you'd need to debug anyway
           | 
           | But that's the thing, it can.
           | 
           | - you can specify compile-time preconditions and use the type
           | system to ensure value are in range (which catches a ton of
           | errors) - you can use constexpr to enforce no UB (UB in
           | constexpr evaluation is a compile error)
           | 
           | For instance, it's trivial to make a type-checked db id in
           | c++ which will give you a hard error if you use the id
           | pertaining to a given type, to another type. That's much
           | harder to do in C (without implementing a custom code
           | generator at least that would basically reimplement
           | templates) and has saved me lots of very costly hours of
           | debugging when I see the amount of time I got compile errors
           | I got from that.
        
             | patrick451 wrote:
             | How does the type system catch this bug
             | 
             | double negate(double x){ return x; }
             | 
             | ?
        
               | jcelerier wrote:
               | I'm sure that in 1986, before standardizing ANSI C,
               | someone victoriously typed the same thing in front of his
               | tty in a discussion about using types in declarations and
               | not just doing it a la K&R with just the function name
               | being called cowboy-style.
               | 
               | Just because a system does not catches _all_ bugs does
               | not make it useless - for me, even if C++ 's type system
               | had caught only one bug it'd be worth it (and in most of
               | my code, which is mainly about fairly specific domain
               | objects, the compiler saves me from myself pretty much
               | daily).
               | 
               | In any case, I'd likely have this somewhere
               | constexpr double negate(double x) {             return
               | -x;         }                // example implementation
               | for the sake of the comment, there are much more
               | exhaustive libs out there         constexpr bool
               | sample(auto func) {             bool ok = true;
               | double x = -1000.;             while(x < 1000.)
               | {               ok &= func(x);                x += 1.;
               | }             return ok;         }
               | static_assert(sample([] (double x) { return negate(x) ==
               | -x; }));
               | 
               | this way I'd get a compile error if my cat walks on my
               | keyboard and inadvertently removes the - (also a
               | relatively common occurence)
        
               | patrick451 wrote:
               | You're effectively just changing where you write your
               | unit tests. So it's hard to agree that the type system is
               | saving your from anything, when it's really just writing
               | tests.
        
               | jcelerier wrote:
               | But no one said that type systems disqualifies from
               | writing tests (and C++'s improvements over C aren't only
               | about the type system).
               | 
               | It removes, however, the need for a lot of tests that are
               | needed when using weaker type systems, mainly because you
               | can make invalid data unrepresentable.
               | 
               | To give a few examples:
               | 
               | 1/ in C++ you can write a type positive_int such that
               | invalid values (negative ints) are not representable at
               | all - either the operation a - b gives a correct,
               | positive result (3 - 2 == 1), or you get an error that
               | you can process if for instance you do 2 - 3. You can
               | also write things in a way that the user only has to
               | provide things in a declarative way.
               | 
               | 2/ I'm working on an API for defining dataflow nodes for
               | multimedia applications which tries to leave zero margin
               | for error : the user simply has to define the inputs and
               | outputs like this, as types, which the C++ type machinery
               | is able to digest and show to the user :
               | 
               | https://github.com/jcelerier/score-simple-
               | api-2/blob/main/Si...
               | 
               | In contrast, in C, one has to cast things left and right
               | because the only tool you have is void* : see for
               | instance
               | 
               | https://cycling74.com/sdk/max-
               | sdk-7.3.3/html/chapter_msgatta...
               | 
               | or
               | 
               | https://cycling74.com/sdk/max-
               | sdk-7.3.3/html/chapter_msp_adv...
               | 
               | in both cases we are defining a dynamic dataflow node
               | with various inputs / outputs (for instance an audio
               | input and output, plus a control), which is then
               | displayed in an user interface (thus things have to be
               | reflected in some way). But in the C version, the onus is
               | on the programmer to :
               | 
               | - cast the inputs / outputs to the correct types
               | according to the object's specification when using them -
               | cast the values contained in the inputs / outputs to the
               | correct types - access the correct inputs / outputs in
               | the arrays
               | 
               | there is just so much more opportunity for error, which
               | entirely disappears in C++
               | 
               | 3/ Another example that you can see in my code: the
               | make_uuid function. Takes a UUID in string form and
               | converts it to binary uint8_t[16] at compile time ; also
               | checks that the UUID is a valid one.
               | 
               | Every time I use this function, this is a test that I do
               | not have to write - I _know_ that all UUIDs in my system
               | are valid, because I use an  "uuid" type which can only
               | be created this way by the user.
        
               | pjmlp wrote:
               | By using contracts, unfortunately they were postponed to
               | C++23.
        
               | adrianN wrote:
               | Naturally you first implement your algorithm together
               | with a correctness proof inside the turing-complete type
               | system. After that writing the real implementation can be
               | left as an exercise for the compiler :)
        
           | patrick451 wrote:
           | Clearly, if you missed a minus sign somewhere, your type
           | system is not powerful enough (>:<)
        
       | b0tzzzzzzman wrote:
       | Why are all the things I post dead?
        
       | thrower123 wrote:
       | It seems like most of the issues with C++ are solved by not using
       | the parts that suck. You can still write C++ as C-with-
       | classes/RAII/operator overloads, and leave all the smart pointers
       | and template meta-programming and boost (do people still use
       | boost?) magic at the door.
        
       | thechao wrote:
       | I like to think of a compiler as a virtual machine whose
       | instructions are the tokens in your code, and whose output is
       | object code. Taken that way, you can _for sure_ optimize the
       | input program (your C++) to execute faster on the interpreter
       | (the compiler). Understanding how the language (any language with
       | such features) is implemented lets you stray away from the slow
       | parts.
       | 
       | For instance, in C, every function has a unique, global name.
       | That means the implementation in the compiler can be a hash-table
       | from string to implementation. C++ allows function overloading;
       | now, our 'hash table' is a much more complicated thing: first, we
       | must consider every function in the overload set no matter what;
       | second, we must pick which function is "best" -- usually through
       | some complicated unification scheme. In all, this means that C
       | function lookup is O(1) (probabilistic), whereas C++ function
       | lookup is O(n) _at best_ , but with unification it might be
       | O(n^2) or O(n^3). I've seen slow compiling code with _hundreds_
       | of identically named functions.
       | 
       | Templates are slow for two reasons: (1) they get shared via
       | header files, so they get reparsed over-and-over-and-over; and,
       | (2) they're implemented with a stringy interpreter whose job is
       | to instantiate copies of the code. This is distinctly slower than
       | macro expansion; generally, macro instantiation is of _code_ and
       | so occurs in source files -- only requiring a single parse; and,
       | also, there 's just string-replacement, not an interpreter.
       | 
       | But ... here's the thing. You can make your C++ code compile fast
       | by simply _not using slow paths_ through the compiler.
        
         | woodruffw wrote:
         | > For instance, in C, every function has a unique, global name.
         | That means the implementation in the compiler can be a hash-
         | table from string to implementation.
         | 
         | If only we were so lucky ;). Symbols are not unique across the
         | translation unit boundary, which is why we have C's mess of
         | fake namespace hacks. Even `static` doesn't save the linker
         | from doing extra work --- check out the locally bound symbols
         | in one of your ELFs sometime! You'll probably find some
         | duplicates.
        
         | WalterBright wrote:
         | > I've seen slow compiling code with hundreds of identically
         | named functions.
         | 
         | I sometimes think I've seen everything programmers do, and then
         | something like this pops up.
         | 
         | > You can make your C++ code compile fast by simply not using
         | slow paths through the compiler.
         | 
         | D is fast to compile because it sidesteps or redesigns features
         | that make for slow compilation.
        
           | fm77 wrote:
           | Walter, I am sorry, completely off-topic... but I have to ask
           | - and you don't have to answer ;-) ...is that you?
           | 
           | https://archive.org/details/byte-
           | magazine-1988-09/page/n148/...
        
             | Zababa wrote:
             | There's a (french) wikipedia page about Zortech
             | https://fr.wikipedia.org/wiki/Zortech
        
           | thechao wrote:
           | If I told you the first attempt was several _million_
           | identically named functions, split across several hundred
           | files, and the compile and link times were ~72 hours on a
           | distributed build would you be happier?
           | 
           | A single templated function & a few n*100kloc macros later,
           | and I got the compile time down to ~1s on a crappy laptop.
           | 
           | Macros are 'fast paths' through compilers -- they copy
           | structures in memory, rather than going through the entire
           | disk->lex->parse chain.
        
           | moonchild wrote:
           | D is horribly slow to compile template-heavy code for exactly
           | the same reasons as c++. And it encourages lots of
           | monomorphization in e.g. ranges. The enhanced introspection
           | and reflection (and CTFE) capabilities coupled with mixins
           | also encourage code that is very slow to compile.
        
             | WalterBright wrote:
             | Not really. For example, D templates are never parsed more
             | than once.
             | 
             | The trouble is, people use templates more and more until
             | they hit compile speed problems. I'd argue that this limit
             | is much higher in D, but the end result is similar.
        
               | munificent wrote:
               | Just like nature abhors a vacuum, my experience is that
               | regardless of how fast your compiler is, user programs
               | will grow to until they reach a point where they are
               | annoyingly slow to compile.
        
               | mpweiher wrote:
               | Solution: drastically lower your annoyance threshold.
               | You'll be more grumpy but much more productive.
               | 
               | I get antsy when my test suite takes more than a second
               | or so.
        
             | mhh__ wrote:
             | As opposed to encouraging manually written code which is
             | also not free to compile but has the added benefit of
             | potentially introducing bugs?
        
               | moonchild wrote:
               | As opposed to encouraging polymorphic code (a la haskell,
               | java), which is fast to compile and provides better type
               | safety.
               | 
               | (Yes, I know neither javac nor ghci are particularly
               | fast, but that doesn't detract from the general point.)
        
         | zozbot234 wrote:
         | > You can make your C++ code compile fast by simply _not using
         | slow paths_ through the compiler.
         | 
         | Rust is also working on making this easier, BTW. There's still
         | quite a bit of excess monomorphization going on when using
         | generic code, but better support for const: in generics should
         | ultimately obviate this.
        
       | jcelerier wrote:
       | I wonder what kind of hardware OP runs on, and which compiler is
       | used.
       | 
       | Here on my laptop (Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz), on
       | linux, compiling an eigen example takes 0.7 seconds
       | clang++ -fuse-ld=lld eigen.cpp -I/usr/include/eigen3/  0,66s user
       | 0,07s system 100% cpu 0,728 total
       | 
       | if I put the eigen header in a PCH this drops to 0.1 seconds
       | clang++ -fuse-ld=lld eigen.cpp -I/usr/include/eigen3/ -include-
       | pch   0,08s user 0,02s system 104% cpu 0,099 total
       | 
       | I have a hard time seeing how 300 lines of code (vs the 10 lines
       | of the example) would multiply compile times by 300 - here's the
       | example I used                   #include <iostream>
       | #include <Eigen/Dense>               using Eigen::MatrixXd;
       | int main()         {           MatrixXd m(2,2);           m(0,0)
       | = 3;           m(1,0) = 2.5;           m(0,1) = -1;
       | m(1,1) = m(1,0) + m(0,1);           std::cout << m << std::endl;
       | }
       | 
       | I develop a GUI software with boost, Qt, and a fair amount of TMP
       | and my average turn-around time from a change in the average file
       | to the program running is between in and 2 seconds. Maybe it
       | could get down to 0.1~ seconds if using C, but there would be so
       | many less checks and guards !
        
         | tomn wrote:
         | Unfortunately our example isn't representative, and avoids a
         | lot of things that make eigen slow to work with. Parsing the
         | header file will take a constant time, but template expansion
         | etc. can take a long time if you have more code.
         | 
         | Try adding a bunch of matrix operations (particularly chained
         | ones resulting in massive expression templates), fixed size
         | matrices of various sizes, and compile with optimisation and
         | SIMD enabled, and you'll see different results. I really like
         | eigen and use it a lot, but it can definitely result in long
         | compile times.
        
         | dthul wrote:
         | Does it get significantly slower if you use Eigen's fixed size
         | matrices? I have a C++ project which uses Eigen and some other
         | templates (but nothing crazy) and it is quite slow to compile.
         | Not complaining though because I don't compile often.
        
         | yoz-y wrote:
         | Haven't used Eigen for quite a while, but I do remember it
         | being rather slow to compile once it proliferates. Those
         | templates are clever but also quite taxing.
        
           | pjmlp wrote:
           | Even so, using another math library would have been the
           | solution then.
        
             | tomn wrote:
             | The bits of eigen that make it slow to compile are the same
             | bits that make it both easy to use and fast. I'm sure there
             | are improvements that could be made, but ultimately eigen
             | is big and slow to compile for a reason.
        
       | socialdemocrat wrote:
       | I can relate a lot to this as an old school C++ developer (not
       | anymore). I also remember switching a project over to pure C some
       | years ago and found it a lot more pleasant to work with. But I
       | combined it with Lua so I could use Lua for high level constructs
       | C is not so good at.
       | 
       | Anyway I suspect that in a few years Zig will be the choice in
       | scenarios like this. It gives you fast compilation times and low
       | level access like C while being a lot safer, but without adding
       | C++ level complexity.
       | 
       | That is an important sweet spot to hit.
        
       | winrid wrote:
       | If you really like the simplicity of C I highly recommend Nim:
       | 
       | * Compiles to C, so you stand on the shoulders of giants wrt
       | compilers.
       | 
       | * Very low overhead GC that doesn't "stop the world".
       | 
       | I was working on a project recently where I had to just write a
       | bunch of stuff to disk, and I tried Node, and then Java, and they
       | were about the same, and I figured - yep, makes sense, it's IO
       | bound.
       | 
       | Nim got twice the throughput w/ an order of magnitude less memory
       | usage! Because the serialization I suppose was the bottleneck and
       | msgpack4nim is pretty fast.
        
         | moonchild wrote:
         | If serialization performance is an issue, then you may want to
         | consider zero-overhead serialization tools like capn proto.
        
           | winrid wrote:
           | Yeah I know about Cap'n proto etc. Was just saying the tiny
           | language can compete :)
           | 
           | Language comparisons are almost always BS...
        
         | jart wrote:
         | Use mmap and you won't need to write anything to disk; the
         | operating system will do it for you. That's C's killer feature
         | while also being the last thing on earth languages like Node
         | and Java would ever permit developers to do.
        
           | shakow wrote:
           | > while also being the last thing on earth languages like
           | Node and Java would ever permit developers to do.
           | 
           | You sure about that?
           | 
           | https://www.npmjs.com/package/mmap-io
           | 
           | https://docs.oracle.com/en/java/javase/11/docs/api/java.base.
           | ..
           | 
           | mmap is a system call, not some C-exclusive fancy feature. If
           | your language can print something on the screen, there is no
           | reason it can't mmap a file.
           | 
           | And if the serialization was the bottleneck, mmap would not
           | have changed anything anyway.
        
           | winrid wrote:
           | Good idea, will keep that in mind for next time.
        
       | nmeofthestate wrote:
       | >linking a big C++ project with lots of dependencies and some
       | template magic can easily take several minutes.
       | 
       |  _dreams wistfully of C++ build that only takes several minutes_
        
       ___________________________________________________________________
       (page generated 2021-06-26 23:03 UTC)