1. 12

    Glossing over why sudo would mysteriously not work, this writes a bunch of noise out to the monitor:

    > sudo cat /dev/urandom > /dev/fb0
    -bash: /dev/fb0: Permission denied
    

    That command does not work because the redirection is performed by the shell which does not have the permission to write to /dev/fb0. The redirection of the output is not performed by sudo.

    How to do it here

    1. 7

      You can use tee as well:

      cat /dev/urandom | sudo tee /dev/fb0
      

      It’s quite funny that person who don’t know how shell and sudo (nb: use doas or su instead) tells us a lengthy story about writing to framebuffers in Linux

      1. 11

        The frame buffer is arguably a lot simpler than a *nix shell

        1. 7

          nb: use […] su instead

          You better don’t, it’s vulnerable to the ages-old TIOCSTI trick::

          #include <sys/ioctl.h>
          int main() {
              char* c = "exit\nid\n";
              for (; *c; ++c)
                  ioctl(0,TIOCSTI,*c);
              return 0;
          }
          

          (in .bashrc or so)

          This can be deterred by using su -P, but it’s marked as experimental (according to the manpage), and I haven’t seen anyone using it.

          1. 3

            TIOCSTI

            more info here, as I haven’t heard of it previously https://ruderich.org/simon/notes/su-sudo-from-root-tty-hijacking

        2. 1

          This probably works for the author if they’re in the video group:

          $ ll /dev/fb0
          crw-rw---- 1 root video 29, 0  5 apr 15:37 /dev/fb0
          

          EDIT: I’m stupid, didn’t see that part of the article.

        1. 16

          Meh, what’s a factor 10 when you’re still under a request per second? Does this actually matter?

          I’m curious whether any attempt was made to contact the Bing team before the change & post.

          1. 3

            Seems very unnecessarily frequent. If you had multiple search engines checking in this frequently it’d add up quickly

          1. 1

            On laptops, I use knuckles for modifier keys. On other keyboards, I just use my palm for the control key. Save caps lock for the escape key.

            1. 1

              I like having a tap on caps mapped to esc, and a press mapped to ctrl.

              Actual ctrl key I map to ctrl+opt+cmd and press with the palm for custom combos.

              1. 1

                That sounds interesting, how did you acomplished that?

            1. 1

              The main problem with front end development was never the browser, but rather the endless layers/kilobytes of abstraction meant to make everything automatic.

              1. 1

                As soon as something other than a print statement is imported, you can be pretty sure that monads won’t be explained simply.

                1. 2

                  A monad is a type m for which the following functions may be implemented:

                  (>>=) :: forall a b. m a -> (a -> m b) -> m b
                  return :: a -> m a
                  

                  Subject to the following rules:

                  -- Rule 1
                  return a >>= k  =  k a
                  -- Rule 2
                  m >>= return  =  m
                  -- Rule 3
                  m >>= (\x -> k x >>= h)  =  (m >>= k) >>= h
                  

                  That’s it. That is what a monad is (there are equivalent definitions that some people prefer over this one, but all of them give the same result). Monads get some special treatment in Haskell (do notation requires a monad), but other than that there’s nothing magical about them. Monads aren’t magical things. “Monad” is a name for a common pattern: a type whose definition permits the functions defined above.

                1. 18

                  It’s been 9 hours and nobody has mentioned C++!

                  I’m not suggesting you jump off the C++ cliff. Don’t use the STL. Don’t use RAII. Don’t follow “everything has value semantics and a = b does massive allocations and copies”. Don’t use the STL. Don’t use smart pointers. Don’t use exceptions - you can disable them at compile time. Maybe use the STL if you can’t be bothered to implement things yourself, but measure your build times before and after.

                  Start with C, and introduce C++ features when they let you write the same C code but more concisely/safely. Use operator overloading for mathsy types. Add an array class that doesn’t own its data, just acts as a wrapper around T* and size_t (and give it bounds checking). Make a string class that wraps char buf[ N ]; and snprintf (_snprintf on Windows does not behave exactly like posix snprintf FYI). Use the SCOPE_EXIT trick for resource cleanup. Use casts that explode if you smash values by accident.

                  Some examples of code I have that I think is neat and shouldn’t upset C programmers, starting with a better printf:

                  stuct v3 { float x, y, z; };
                  void format( FormatBuffer * fb, const v3 & v, const FormatOpts & opts ) {
                          format( fb, "v3(" );
                          format( fb, v.x, opts );
                          format( fb, ", " );
                          format( fb, v.y, opts );
                          format( fb, ", " );
                          format( fb, v.z, opts );
                          format( fb, ")" );
                  }
                  ggprint( "{.2}\n", v3( 1.2345, 2.3456, 3.4567 ) ); // "v3(1.23, 2.35, 3.46)"
                  

                  a better string class (no allocations):

                  str< 256 > buf( "{.2}", v3( 1.2345, 2.3456, 3.4567 ) );
                  buf += v3( 1, 2, 3 );
                  buf += 123; // "v3(1.23, 2.35, 3.46)v3(1.0000, 2.0000, 3.0000)123"
                  

                  a wrapper around Lua’s string matching code (no allocations!):

                  for( array< array< const char > > matches : gmatch( "test1 test2 test3 test4", "(test)(%d)" ) ) {
                          // matches.n = 2
                          // matches[ 0 ] = { elems = "test...", n = 4 }
                          // matches[ 1 ] = { elems = "1 te...", n = 1 }
                          ggprint( "{}_{}\n", matches[ 0 ], matches[ 1 ] ); // "test_X"
                          // trying to access matches[ 2 ] asserts
                  }
                  
                  1. 7

                    Don’t use RAII.

                    Isn’t RAII a hugely important technique for avoiding code problems?

                    1. 2

                      Until it causes different problems, yes ^^;

                      1. 1

                        Like what?

                        1. 2

                          It’s hard to give specific examples of the problems in action but 1) you can pigeonhole yourself into writing code that’s ugly/inefficient, 2) it encourages managing resources in the leaves of your code which can be inefficient and difficult to follow 3) it’s viral - any structs containing RAII types become RAII types themselves, and 4) once classes start having meaningful constructors and destructors it forces a lot of complexity everywhere else. Your allocators have to start calling constructors and destructors, you have to be careful with memcpys and memsets, and not having to worry about that 100% of the time is a big win.

                          I didn’t mean you should never use it, but I think it’s rarely actually a win.

                          1. 11

                            I’m not following you at all. From your submission history you seem to do mostly graphics programming, and I can buy that there may not be much use for destructors when you avoid dynamic allocation inside loops.

                            Statements like “allocators have to start calling constructors and destructors” and “you have to be careful with memcpys and memsets” reinforce that you’re using C++ in some highly niche way. I don’t write allocators often enough that the amount of effort going into them is a data point for the language. And yes you certainly don’t want to be using memcpy in the presence of destructors.

                            I went looking around the internet for critiques of RAII (because in 20 years of C++ programming I’ve never encountered criticism of RAII before), and found very few:

                            http://coliveira.net/software/raii-is-overrated (2011)

                            https://en.sfml-dev.org/forums/index.php?topic=9359.0 (2012) https://en.sfml-dev.org/forums/index.php?topic=19788.0 (2016)

                            None of these is very compelling at all.. So I’m still flummoxed. RAII is one of two reasons I use C++. My code samples there show that I don’t even use the class keyword when given the choice. But you’ll prise destructors from my cold dead hands.

                            1. 2

                              From your submission history you seem to do mostly graphics programming, and I can buy that there may not be much use for destructors when you avoid dynamic allocation inside loops.

                              You’re right with that, but even in random glue code I find that RAII can be annoying sometimes. It’s hard to explain without having specific code examples, and I don’t run into it in my home code so I don’t have anything to share. I also expect that std::move helps with some of them, but solving problems with language features with more language features seems iffy to me and we don’t use C++11 at work.

                              you’re using C++ in some highly niche way.

                              I’ve been writing C for longer than C++, so I mostly write C and add C++ where I think it makes sense. So I guess you’re right there too.

                              1. 1

                                I’ve been writing C for longer than C++, so I mostly write C and add C++ where I think it makes sense.

                                Same here, so I totally feel you.

                                I don’t use C++11 either[1]. So I don’t think that’s an issue here.

                                [1] On a tangent, my policy lately has been to move to a standard only when it’s the default for the version of the compiler shipped with the newest version of Linux and OS X (LTS in the case of Ubuntu). I often get questions from users on older versions of compilers, so this seems a reasonably conservative line in the sand. For small projects like mine, losing a single person who might have tried them out is a big loss. Ubuntu 16.04 and OS X Sierra (both released in 2016) neither enable C++11 by default. So I’m still on C++03. In a year or three I’ll migrate Mu to C++11 and start using auto and range loops.

                    2. 4

                      As you say, to get by as “readable” you have to avoid a lot…

                      If you need a language that is fast as can be and type safe, D is much nicer and more readable than C++.

                      It’s like C++ but you can ask the compiler what it knows about any symbol and act on that knowledge at compile time.

                      Template meta programming in C++ is a complete nightmare… You can even ask the guy who invented template meta-programming and wrote The Book on it.

                      He went off and joined D instead since template meta-programming is simple, readable and straightforward in D.

                      1. 2

                        “Don’t use the STL. Don’t use RAII. Don’t follow “everything has value semantics and a = b does massive allocations and copies”. Don’t use the STL. Don’t use smart pointers. … Maybe use the STL if you can’t be bothered to implement things yourself, but measure your build times before and after.”

                        Yes, definitely avoid exceptions if possible :)

                        1. RAII is one of the best things about C++.
                          This is amazing:
                        database_connection db;
                        if (db.open("127.0.0.1", port)) {
                          ...
                        }
                        
                        // Don't worry about closing the connection no matter how we return from this function it will close
                        

                        RAII should be exactly the same performance as the same code in C. The only time it should differ is if the C code avoided calling the “destructor” function before some of the return statements. You might have been confusing RAII with garbage collection or shared_ptr etc.?

                        1. Compile times are good enough these days to use STL on all but the largest projects. Use STL until you find a place where it is slow.
                        2. C++ users need to learn about reference vs pointer vs array, and move semantics, and then basically just wrap all pointers in unique_ptr or shared_ptr (And learn the difference).
                        3. I would really try to avoid writing your own string class. Add some axillary functions to convert between your types to and from strings, sure. It is fun and isn’t too hard to create a string library, but in commercial stuff, there is a lot to be said of being able to bringing people into an organisation and having them be able to hack on the code in the first hour because they have used std::string/map/list/vector before.

                        A better printf, use either of these:

                        With streams you can do this type safely:

                        my_log<<"x="<<x<<", y="<<y<<std::endl;
                        

                        With var args templates in C++11 you can do this also with type safety:

                        my_log_function("x=", x, ", y=", y);
                        
                        1. 4
                          1. IMO this is just as good:
                          if( !db.open() ) return;
                          SCOPE_EXIT( db.close() );
                          
                          1. I added iostream/string/vector/map to every file in my project (80k LOC) with gcc -include and my debug build went from 2.7 to 4.7 seconds. Less bad than I was expecting but still not great.

                          2. unique_ptr is good but I find shared_ptr is a symptom of doing resource management in leaf code and losing track of/not caring what their lifetimes/owners are.

                          3. Not such a big deal if it takes 2 hours vs 1 IMO.

                          Format specifiers in streams are very very bad. They’re unreadable and they’re kept around as state on the stream to screw up your prints everywhere else when you forget to reset them.

                          Writing my_log_function like that is good and better than C’s printf because you can add your own types to it, but I prefer the printf format + args style. If you’re feeling ambitious you can actually write a monster print that combines both styles, see autoprintf.

                          Edit: if you do actually implement printing with templates it’s a big win to always disable optimisations to keep compile times down. If you want to do it cross-platform you need something like this.

                          1. 2

                            SCOPE_EXIT is definitely better than normal C goto or while/break.

                            Yes shared_ptr can be a sign you are doing the wrong thing, especially if every single pointer in your application is a shared_ptr. In my code I find myself mostly using std::array, stack objects + references and occasionally unique_ptr which I am basically using as an “optional” return instead of returning a raw “null or object*” depending on if something was created or not.

                            1. Yes, 2 hours is not a big deal even in the first week the developer has 40 of them :) I just mean it is nice that most C++ programmers have experience with the STL or have at least heard of it and know the basic concepts. Creating a string class or the other containers is ok, but you have to work hard to make it sane, predictable, easy to work with. The string library is not perfect but it is better than string libraries I wrote 20 years ago :)

                            Yes format specifiers with state are the worst. You could possibly do something like:

                            my_log_function("x=", FloatFmt(2, x), ", y=", FloatFmt(2, y));
                            

                            Or:

                            my_log_fmt fmt;
                            fmt.set_float_precision(2);
                            my_log_function(fmt, "x=", x, ", y=", y);
                            my_log_function(fmt, "z=", z, ", w=", w);
                            

                            I think I prefer the second one.

                            Thanks for the optimisation pragma tips!

                        2. 1

                          While I do mostly agree. It could be argued that the resulting code is readable but not writable or maintainable unless the next coder is already a capable C(or worse, C++) programmer anyway.

                          I myself ignore these concerns and write Objective-C++ on occasions when I think the performance boost is worth it.

                        1. 2

                          Chrome won just like IE won. Maybe it’ll last longer. But proposing standards, implementing them, and pushing them before they are actually standard is no different from what we used to hate MS for.

                          (For the record, I prefer Safari because battery life and accessibility are more important to me than ..webrtc?)

                          1. 10

                            I think that “indexes” should start at 1 and “offsets” should start at 0. That is, I think a simple name change could fix the whole argument.

                            1. 2

                              [EDIT: This comment is largely wrong. Collections are 1-based, Streams are 0-based. It’d been so long that I’d forgotten. The point in general stands, but the code as-presented below will not work as expected; even when doing a range copy on a SequenceableCollection, it works 1-based with inclusive upper bounds. Doing a PositionableStream on the underlying collection will work as presented here. Sorry about that.]

                              That’s exactly what Smalltalk does.

                              c := #(a b c d e f).  "Declare a five-element array."
                              c at: 1. "a"
                              c at: 5. "f"
                              c at: 6. "throws an error"
                              c copyFrom: 0 to: 1. "#(a) EDIT: Nope, wrong!"
                              c copyFrom: 0 to: 5. "#(a b c d e f) EDIT: nope, wrong!"
                              

                              This made instant and intuitive sense to me when I learned it as a kid in a way that 0-based indexing definitely did not, so I’m definitely on board with it. But I’d also note that in Smalltalk, as in many other modern languages, I barely ever even type the array index in the first place; doing things like first, last, allButFirst: 2, etc. are much more common. So I can’t honestly say it made a huge difference either way. (When I picked up Smalltalk’s successor, Self, I programmed in it for several days before I realized that its indices did in fact start with 0. And I only realized that because I thought I found a bug in the debugger.)

                              1. 2

                                If you see everything as an offset from the beginning of an array, you can stop using the word index, and the confusion should stop.

                                1. 0

                                  If you see everything as an offset from the beginning of an array, you’re thinking in terms of pointers and RAM blocks instead of thinking in terms of arrays. That abstraction slip will cause you problems.

                              1. 1

                                I agree with his opinions on all but the search example, a big magnifying glass is just as easy, if not easier to see than the smaller “Search” blurb. The icon color in the case he chose could’ve contrasted more with the the background however.

                                1. 2

                                  Part of the point was that the icon is completely unparseable to a screen reader. Some users have limited sight, for which better visibility is relevant. Some users have no sight.

                                  1. 5

                                    That’s why HTML has alt text

                                    1. 3

                                      I would suggest trying this in a screen reader (ChromeVox and Apple’s VoiceOver are both free), with your monitor turned off. Most web designers have no intention of doing that, so if they think about it at all they’re guessing how users will hear their UI, and then users are having to guess what the designer was thinking.

                                      Using labels is a simple rule that is maximally explicit about what fields do what. Testing designs in screen readers would also work.

                                      Alt text in this situation turns out not to be ideal, since the image is merely “near” the field in the structural layout, and not associated with it in a way that’s programmatically detectable. But the way to know is to try it, not to guess.

                                    2. 2

                                      Search is kind of a special case, as there is a semantic type=“search” for input tags

                                      1. 1

                                        Can you create a label that says “Search Query” for the search input, and hide it using “overflow: hidden” or something, and use alt text for the magnifying glass submit button that also says “Search”?

                                        1. 5

                                          You can use ARIA to add a lot of the hints needed. I’ve not seen a lot of front end developers make use of this.

                                    1. 1

                                      Sometimes compilers aren’t very good.

                                      How much time would you have to invest in learning Assembly until you start to find inefficiencies in compiler performance?

                                      Also, keep in mind that the abstractions you write for the compiler to work with could be a horrible solution to solving a particular problem.

                                      1. 1

                                        It’s usually not too complicated to spot, problem is the compiler generates an awful lot of assembly and you have to look in the right place(most of the output is optimal already).

                                      1. [Comment removed by author]

                                        1. 2

                                          It can be done in C++. It can still dangle, but that is another problem.

                                          1. 2

                                            Clang has the __nullable and __nonnull annotations, don’t know if the optimizer takes them into account however.

                                          1. 5

                                            What kind of mad man wants to store his music library in MySQL?

                                              1. 1

                                                I mean, I use both telegram and whatsapp and I have to say I prefer whatsapp.

                                                I really don’t understand why telegram doesn’t use encryption by default. That’s a bit silly.

                                                1. 1

                                                  It does, just not end-to-end.

                                                1. 2

                                                  Does he mean open access to an API that can work with iOS?

                                                  1. [Comment removed by author]

                                                    1. 4

                                                      So they’re essentially going to steal the idea? They should at least acquire f.lux…

                                                      1. [Comment removed by author]

                                                        1. 2

                                                          Their website does say they have a patent pending, no link to the actual content of it though.

                                                    2. 2

                                                      Previously you’d be able to install the f.lux app using sideloading via Xcode (see https://justgetflux.com/sideload/#sideloading-flux-on-ios-with-xcode-7) vs. the previous requirement of a jailbroken phone. That ability was short-lived because it violated the iOS developer agreement. They’ve been having conversations with Apple for over 5 years asking for those APIs to be documented.

                                                      Even though Apple will now include this feature natively, it seems that the APIs f.lux needs will remain undocumented, and therefore unusable in a 3rd-party app.