[HN Gopher] Rust vs. C++ Formatting
       ___________________________________________________________________
        
       Rust vs. C++ Formatting
        
       Author : vitaut
       Score  : 69 points
       Date   : 2023-01-15 19:50 UTC (1 days ago)
        
 (HTM) web link (brevzin.github.io)
 (TXT) w3m dump (brevzin.github.io)
        
       | mr_00ff00 wrote:
       | Finally, after 40 years technology has advanced far enough for
       | C++ to have a print function instead of cout
        
         | scrubs wrote:
         | get with the program. Printf in its 86 varieties has been
         | around for years.
         | 
         | Second, I'm increasingly associating that brit 70s show
         | "keeping up appearances" with rust specifically that overly
         | blushed face of the woman protagonist.
        
         | [deleted]
        
         | [deleted]
        
         | stevenhuang wrote:
         | The format in C++20 is the 3rd party
         | https://fmt.dev/latest/index.html , which means even c++11
         | projects can use it.
        
         | RcouF1uZ4gsC wrote:
         | Actually, in defense of C++, there are not very many statically
         | typed, compiled languages that can implement a type-safe print
         | function that takes a variable number of arguments (that do not
         | all share a base class) using the language itself. For many
         | languages, print is special and the implementation is provided
         | as part of the language implementation.
         | 
         | ADDENDUM:
         | 
         | Even iostreams back in the 1980's was a huge deal at the time,
         | as it showed that it was possible to implement type-safe io in
         | a statically typed, compiled language using language features
         | just like any other library, instead of having it be special
         | purpose.
        
           | forrestthewoods wrote:
           | huh? Every new language has type safe print functions. Having
           | to specify the type with printf formatters is archaic and
           | awful.
        
             | kccqzy wrote:
             | Most new languages with type-safe print functions are
             | either dynamically typed (which makes this whole discussion
             | moot) or leverage some significant advance in PL theory in
             | order to make the print function type-safe. By advance, I
             | mean not known before the 1990s.
        
               | forrestthewoods wrote:
               | Sorry, I explicitly meant statically typed languages.
               | Rust, Nim, Zig, Odin, Jai, etc.
               | 
               | > For many languages, print is special and the
               | implementation is provided as part of the language
               | implementation.
               | 
               | Sure. Printing variables to strings is definitely worth
               | language-level features imho. It's a bad thing if a
               | language (C++) requires users to come up with extremely
               | complex libraries (fmt/std::format) because the language
               | lacks the features to make such a common operation simple
               | and reliable.
               | 
               | C style printf is a dumpster fire. C++ iostreams are
               | unuseably slow. Modern languages definitely solve this
               | particular problem much better!
        
           | joenot443 wrote:
           | Swift can do it, yes?
        
         | asguy wrote:
         | It always had printf:
         | https://cplusplus.com/reference/cstdio/printf/
         | 
         | Edit: It's almost like the whole world got a lot of work done
         | with the tools they already had.
        
           | Jensson wrote:
           | Which is a C function and not safe at all. It is easy to make
           | your own print function in C++ that is safe and easy to use,
           | but there is no such function in std.
        
             | adamdusty wrote:
             | Why are you worried about how safe printing to terminal is?
             | Genuinely curious, I don't work in software dev.
        
               | gary_0 wrote:
               | printf() was often used for logging in eg. web servers.
               | If there's no way of strictly checking the size/type of
               | what's being printed (HTTP headers, say) then there are
               | lots of tricky ways you can use it to write arbitrary
               | memory and pwn the server.
               | 
               | Type-unsafeness in general also just allows for hard-to-
               | find bugs, since only certain data at runtime will
               | introduce undefined behavior.
        
               | yakubin wrote:
               | In C you can use "%g" printf format string (which
               | indicates a value of type double), and then not pass a
               | double to it, but e.g. an int. Easy mistake to make, when
               | changing pre-existing code.
               | 
               | On x86 what will happen is the code will compile, but the
               | function is going to read its argument from a floating
               | point register instead of an integer register as it
               | should. This:
               | 
               | 1. Is a bug, since a completely unrelated garbage value
               | is going to be printed.
               | 
               | 2. Leaks the value of a register, which may be a security
               | issue.
               | 
               | There are still other common issues which can easily turn
               | into vulnerabilities, leaking private process memory,
               | when people pass untrusted strings as format strings with
               | the intention of printing them raw.
               | 
               | So you want a safe print to prevent trivial bugs in
               | general, and security vulnerabilities in particular.
        
               | maccard wrote:
               | You're not always printing to a terminal,
               | char buf[10];         const char* foo = "wrong?";
               | int res = snprintf(buf, 20, "What could possibly go %d",
               | foo);
               | 
               | Will compile and do... something...
        
               | jasode wrote:
               | _> Why are you worried about how safe printing to
               | terminal is?_
               | 
               | The "type-safe" means _" type-checked"_ by the compiler
               | for _correctness_ to help prevent bugs. It doesn 't mean
               | "safety-as-in-not-dangerous".
        
             | stevenhuang wrote:
             | There is now in C++20
             | https://en.cppreference.com/w/cpp/utility/format/format
             | 
             | Which is just the great https://fmt.dev/latest/index.html
             | that even c++11 projects can use.
        
           | tialaramex wrote:
           | It had _C 's_ printf, which means it isn't type safe, which
           | is consequently a terrible primitive for this work. Like, it
           | makes sense in C, which thinks _boolean_ is a fancy new
           | concept and thinks 0-terminated strings are a good idea, but
           | it 's not actually good.
           | 
           | std::println is more or less what you would obviously build
           | for a modern language and it's notable because C++ _could_
           | have provided something pretty similar even in C++ 98, and
           | something _eerily_ similar in C++ 11 but it chose not to.
        
             | hn_go_brrrrr wrote:
             | I think you'll find implementing a type-safe print function
             | in C++11 very challenging. What you could do in constexpr
             | was very limited, type deduction was less powerful, and it
             | didn't have fold expressions. I'd say this really only
             | became feasible since C++17.
        
               | Kranar wrote:
               | Boost had a type-safe printf function dating back to
               | October 10th, 2002:
               | 
               | https://www.boost.org/doc/libs/1_31_0/libs/format/
        
               | 1ris wrote:
               | And outstreams where not that bad, aswell. Sure, the
               | operator overloading looks a bit rough. But that's IMHO a
               | pragmatic choice if you want to offer customisation
               | points and didn't have variadic functions yet. They where
               | introduced only in c++11.
        
               | tialaramex wrote:
               | C++ did _have_ variadic functions because it inherited
               | them from C.
               | 
               | What it didn't inherit from C was a way to write variadic
               | functions with variadic types, so that had to be home
               | grown.
        
               | 1ris wrote:
               | Do you mean this feature [0]? I'm not aware of any
               | differences in c and c++ about this. Can you get a type
               | of a argument in C? How? At compile time, or at runtime?
               | Both sound very un-C-like to me. cppreference is usually
               | excellent documentation but it doesn't mention something
               | like this.
               | 
               | I don't considers this to be "proper" variadic arguments,
               | because a functions argument has to have a type. and
               | these, as far as I'm aware of don't have one. This is
               | about a powerfull as passing a void**. This is
               | essentially memcopying multiple differently typed into a
               | char* buffer and then passing that buffer. You can than
               | correctly copies them back you have pretty much the same
               | behaviour. Both methodss obviously lacks important
               | aspects of the language abstraction of a function
               | parameter and i don't what that feature can bring to the
               | table that the previous techniques don't.
               | 
               | [0] https://en.cppreference.com/w/cpp/utility/variadic
        
               | kevin_thibedeau wrote:
               | > Can you get a type of a argument in C?
               | 
               | You can get it indirectly using _Generic().
        
               | tialaramex wrote:
               | Sure, a hypothetical C++ 11 equivalent would e.g.
               | probably not be able to do the trick where we reject
               | bogus formats at compile time, which is something
               | programmers want and which Rust only gets to do by making
               | this a fancy macro whereas C++ 23 is doing it in the
               | actual library code.
        
               | saghm wrote:
               | Maybe the top comment in this thread wasn't so facetious
               | after all then; it did take almost 40 years for C++ to
               | advance enough to have a decent print function
        
           | 1ris wrote:
           | printf is a bad joke of a formatting function.
           | 
           | When i want to print a string i don't want to worry about the
           | security implications of that. With printf i have to. [0]
           | 
           | And i certainly don't want a turing complete contraption. [1]
           | Also looking at log4j.
           | 
           | And even if everything is correct, it's has to parse a string
           | at runtime. I consider that alone unaesthetic.
           | 
           | >Edit: It's almost like the whole world got a lot of work
           | done with the tools they already had.
           | 
           | The best metaphor i know for this attitude is "stacking
           | chairs to reach to moon". If you don't care about the limits
           | of the tech you will be stuck within it.
           | 
           | I'm time and time again amused how anti intellectual and
           | outright hostile to technological progress the programming
           | profession is. programmers, out of all of them.
           | 
           | [0] https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=printf
           | 
           | [1] https://news.ycombinator.com/item?id=25691598
        
             | asguy wrote:
             | > If you don't care about the limits of the tech you won't
             | be able exceed what you think is possible.
             | 
             | Did you propose/implement/release something better than
             | printf?
             | 
             | > I'm time and time again amused how anti intellectual and
             | outright hostile to technological progress the programming
             | profession is. programmers, out of all of them.
             | 
             | Perfect is the enemy of good. Some people talk about
             | getting work done, some people get the actual work done and
             | move on.
        
               | spoiler wrote:
               | > Perfect is the enemy of good. Some people talk about
               | getting work done, some people get the actual work done
               | and move on.
               | 
               | In my experience, people with this motto generally
               | produce code which frustrates the whole team.
               | 
               | Being a perfectionist is toxic in its own way, though.
               | 
               | There needs to be a balance. I think that balance is to
               | think and plan a few steps ahead (not too much, as it's
               | counter productive) before hitting the keyboard. I know
               | this sounds a bit like a "d'oh, of course" but it really
               | --and unfortunately--isn't something that people
               | practice; they just think they do.
        
               | 1ris wrote:
               | >Did you propose/implement/release something better than
               | printf?
               | 
               | This is what the article is about? Things much better
               | that printf are a dime a dozed and available since 20
               | years.
               | 
               | >Some people talk about getting work done,
               | 
               | Like this article does? While you busy arguing that you
               | could do the same thing, but much worse?
        
               | Gibbon1 wrote:
               | Lets consider #embed which is new for C23. It allows you
               | to import binary blobs of data into a C program at
               | compile time. Like say if you want to import am image or
               | sound file or a table.
               | 
               | How hard was that to implement? Seriously no reason it
               | couldn't have been part of C89. Why wasn't it? Because
               | the compiler writers and the C++ standards commit have no
               | personal use for it. It took 40 years of waiting a five
               | years to get it past the standards committee and just
               | barely.
               | 
               | Those guys also have no interest in printf type
               | functions. And improving printf would be a lot more work
               | than implementing #embed.
        
               | CountSessine wrote:
               | That's neat - Borland C had the same thing with the
               | `emit()` pseudo-function with their C89 compiler. I guess
               | Borland's compiler writers wanted it more than gcc's?
        
             | Someone wrote:
             | > And even if everything is correct, it's has to parse a
             | string at runtime. I consider that alone unaesthetic.
             | 
             | Technically, it doesn't have to do that. If a program
             | includes the header declaring _printf_ using the  <> header
             | defined in the standard and then calls _printf_ the
             | compiler is allowed to assume that the _printf_ that the
             | program will be linked to will behave according to the
             | standard, and need not compile a call to _printf_. It can
             | generate code that behaves identically.
             | 
             | A simple example is _gcc_ converting a _printf_ with a
             | constant string to a _puts_ call
             | (https://stackoverflow.com/questions/25816659/can-printf-
             | get-...)
        
           | arcticbull wrote:
           | > Edit: It's almost like the whole world got a lot of work
           | done with the tools they already had.
           | 
           | This feels a little defensive, but also pretty out of line
           | with the philosophy of the C++ standards committee. The
           | committee has been aggressively stapling every new leg they
           | could find to that dog for decades. They just chose not to
           | staple this particular leg on until now.
        
           | spoiler wrote:
           | You could build anything you desire with only a hammer if
           | you're creative enough
        
       | [deleted]
        
       | kybernetyk wrote:
       | [flagged]
        
       ___________________________________________________________________
       (page generated 2023-01-16 23:00 UTC)