1. 2

    I’d like to try something like this out… is there a vim ‘theme’ that demonstrates the ‘color free editor setup’?

      1. 2

        It might be his vim-colors-plain theme:

        https://github.com/nerdypepper/vim-colors-plain

        1. 2
          1. 2
            1. 1

              to add to some of the others

              Though I use vim-colors-plain. I’ve really enjoyed it.

              1. 1

                I wrote this for myself: everything is yellow, strings are red, comments are grey.

                I remember when I started dipping into that idea – a veteran programmer ridiculed the idea of syntax highlighting. “I know what my language does, I don’t need training wheels for my editor!”

                “What a ridiculous idea!” I thought. “Of course it’s better and easier with colours. I’ll try without them for some time just to make sure he’s wrong.” Fast forward a few weeks… he wasn’t really wrong. I’m not convinced syntax highlighting really does anything for clarity and ease of working with code. Syntax is usually instantly recognizable from the code layout alone.

                What I’d really like to see is an editor that can highlight stuff that make semantic sense, or are meaningful in runtime. Make my slow code red and fast code green, like a highlighting code profiler, for example. Find the code not covered by unit tests and turn it red. Highlight the variable that was written to, but never read in the last 20 runs, stuff like that.

                I can recognize syntax of my “native” programming language just fine – it’s the subtle semantics that elude me.

                1. 0
                  :syntax off
                  

                  It disables syntax highlighting.

                  1. 2

                    Well, sure, but the example in the article doesn’t have all coloring disabled: https://files.nerdypepper.tech/bF.png

                    1. 3

                      By chance I’ve been doing almost exactly the same as the OP has with my Vim colours. I just can’t stand rainbow vomit in my editor.

                      I use it with an xterm using solarized colours.

                      As you can see, it’s not really release-ready.

                      (The copyright comment is that of the theme template I started with).

                      1. 1
                  1. 2

                    matrix has become my irc bouncer and client

                    1. 10

                      Not a personal attack, but Matrix users on IRC are pretty troublesome for people using standard IRC clients – especially when they send formatted code blocks, you see a “xyz has sent a long message”; similar message when they upload an image.

                      Please use a standard IRC client.

                      1. 3

                        Ok, I can see how that might be problematic. I typically don’t send formatted code blocks. But usually irc channels ask that you handle pastes via some pastebin. So how different is it really in that case?

                        1. 2

                          I remember at least twice matrix users in this situation:

                          <u1[m]> go check https://[...] for the full message
                             <u2> don't do that plz
                          <u1[m]> do what? about [topic]?
                             <u2> no, that "go check https://[...] for the full message"
                          <u1[m]> I just typed a long message
                             <u2> can't you disable this?
                          <u1[m]> I can try.
                             <u2> now what were you saying?
                          <u1[m]> go check https://[...] for the full message
                             <u2> go check https://127.0.0.1 for the full answer
                          <u1[m]> didn't it work? dammit!
                          *u1[m] has left the room*
                             *u1 has joined the room*
                            <u1> I was asking: are there good IRC bouncers around?
                          
                          1. 2

                            That seems like an argument for a UI cue in the IRC bridge (eg. a “your message has been pastebinned” notice), rather than an argument against auto-pastebinning.

                            1. 1

                              I was more commenting than really arguing.

                            2. 1

                              Ok, actually just the first 5 messages…

                          2. 3

                            Would you prefer that - like most (all?) ‘standard IRC clients’ with multi-line input - it just spams 40 lines into the channel one after another? Because that situation, which is generally considered undesirable in IRC etiquette, is what this approach is meant to solve.

                            Edit: Correction, not ‘all’. I believe qwebirc just strips the newlines and then sends half of a message, because the remainder exceeds the message length limit and it doesn’t split it up, so it gets cut off.

                            1. 1

                              Yes. With rate limiting, this isn’t a problem. Having to open a web browser to read text is ridiculous.

                              1. 2

                                The rate-limiting makes it more annoying to a lot of people, because it means that the lengthy text is going to be interspersed with conversation for potentially minutes, rather than spamming a single big block of text (that you can scroll past) only once.

                                Like, I’d be all for having an option in clients/bridges/etc. to disable auto-pasting on a per-channel basis when requested by the channel operator, but frankly I suspect you’re in a strong minority here. There’s a reason that “don’t paste into the channel, use a pastebin” has been etiquette for many many years.

                                If I’m not mistaken, it’s literally how Pastebin.com came to exist!

                                1. 1

                                  I think automatic pastebinning is great. The real annoying thing is their URL formatting that they “fixed” (broke) to support some objectively broken software

                        1. 2

                          Nice! How is easy is it to setup as compared to ZNC? I’ve had this exact pain point.

                          1. 4

                            It’s designed so that you can configure it entirely with command line flags, or put the same options in a simple key = value format config file. There’s no dynamic configuration like znc.

                            The caveat is that it’s one pounce process per server connection, so you either need to listen on different ports for different networks or use the calico daemon to dispatch connections from one port that is accessed via different domain names.

                            Edit: well, and it requires LibreSSL, which may or may not be easily installed on your system of choice.

                            1. 1

                              I like one process per connexion. It helps with isolating resources (virtual memory, computing resources even though it seems to use a ring buffer so no memory usage explosion ahead…).

                              I like the way you code, organize your repo and man page listing source content and being the README. Mind if I take some of your idioms and practices?

                              1. 2

                                Go ahead! I wouldn’t do things like that if I didn’t think everyone should be doing it.

                          1. 2

                            As a former znc(1) user, I was dissatisfied with the multi-client experience it offered. I wanted to connect from both my laptop and my phone and have full chat history on both. I wanted to connect from both my laptop and my phone and have full chat history on both. With znc(1), my options were either having both clients spammed with redundant history every time they connect, or having one client consume the buffer and the other get no history at all.

                            AFAIK ZNC can do that. Unless I misunderstand, it keeps history in sync. Is this what you tried, or did you configure ZNC to just resend last N messages from the buffer each time you connect?

                            1. 2

                              The best solution offered by that page is an external module, which requires extra maintenance to run smoothly. For something that to me should be a core bouncer feature, that is unreasonable.

                              1. 2

                                Well, sure but now you have a bouncer to maintain. :)

                                1. 1

                                  And no irc client to maintain ?

                                  + abduco is working great. Works alongwith or insteadof tmux too.

                            1. 4

                              I’ll be trying this out, the situation with IRC bouncers is quite horrible, so almost anything is an improvement. A while back I tried to find ZNC alternatives, and found these

                              The joke is that almost every second one hasn’t been updated in the last ten years, and their code quality probably also varies substantially.

                              1. 8

                                The joke is that almost every second one hasn’t been updated in the last ten years, and their code quality probably also varies substantially.

                                I don’t know, it seems to me like an IRC bouncer is something you write, and then you’re done. What updates were you hoping for?

                                1. 6

                                  In general I agree; I’m not planning to have to make many releases of pounce. However there have been some useful developments in IRC in the last 10 years, such as the server-time extension, that do improve the situation for bouncers.

                                  1. 1

                                    There’s a feature I would like in a bouncer which (I believe) does not exist, and therefore this might be used as a data point that there’s still room for updates or innovation in bouncers.

                                    On the other hand, my feature, and indeed OP’s feature here, might be feasibly implemented in a ZNC plugin. Which would be a data point against the need for another cilent.

                                    My feature request is: I would like to be able to make one client->bouncer connection and for the bouncer to provide a view over multiple IRC networks in some fashion, so for example, from my client’s POV, I might join the channel “#oftc#debian-uk”, and the bouncer routes that to an OFTC server connection, channel #debian-uk. As things stand, I have to make a half-dozen individual client→bouncer connections, one per IRC network.

                                    1. 3

                                      Quassel does this, the problem with this idea is that you need a custom protocol between the bouncer and the client. Having to switch from your favourite IRC client to replace it with your bouncer’s only supported client isn’t always fun.

                                      1. 2

                                        I’ve thought about this sort of thing too, having some network connections where I use only one channel. Unfortunately it breaks down pretty quickly (unless you start using a custom protocol as @xi points out). How do you route commands that aren’t directly tied to channels, such as WHOIS or private messages for that matter? What happens if your nick ends up different on one network from another? It seems like it would end up more hassle than just a bunch of separate connections.

                                    2. 3

                                      I’m not exactly an IRC power-user, but I’ve been running weechat-headless on my server together with its relay feature, it fulfills my need for persistent and cross-device history.

                                      1. 1

                                        I’ve tried it once, but I hate having to ssh to any server for chats. As an Emacs user I much prefer to have a “proper” UI (ie. what I’m used to) and use something like rcirc or ERC – and to have a persistent setup with these client, a functioning bouncer is necessary.

                                        But what you mention is probably interesting, because that might be a reason that there hasn’t been much development on the bouncer front, since the intersection between those who think that’s ok and use IRC is not really getting smaller (percent-wise).

                                        1. 3

                                          I don’t actually ssh into it to use IRC, I use a “relay” web client. In the future you should be able to use weechat itself as a relay client, if you prefer its UI.

                                          1. 1

                                            Ah, I forgot about that. But it doesn’t help me, I don’t want to use Weechat, but want a real bouncer.

                                            1. 1

                                              Thanks for linking to Glowing Bear! I use weechat off and on, and that looks pretty slick for a wee-chat front-end

                                        2. 2

                                          I’ve been enjoying using Quassel, but it’s more of a fully fledged client rather than a CLI like weechat, but the “core” idea they have is very good. I just wish there was a bit more development on it to polish out the kinks.

                                          1. 5

                                            A worrying thing about Quassel is that communication with the “core” uses some Qt object serialization format which iirc isn’t necessarily stable and isn’t exactly designed for a network protocol

                                            1. 9

                                              We actually fixed that recently in 0.12.5/0.13.0.

                                              It’s still the exact same protocol, but we use custom serialisation/deserialisation to ensure it’s a stable protocol, and is safe to be used over the network.

                                              You’re right that it used to be undocumented and unstable, but we’ve spent a lot of work to keep everything compatible — a current 0.13.1 core or client can communicate with any client or core since 0.5.2, which was released in 2009 :)

                                              1. 1

                                                I have never really had an issue with the connection. It has had a few hiccups every now and then, but I have never bothered to spend time debugging it as it could be anything from my server throwing a fit, PostgreSQL doing a thing, certificate renewals via Let’s Encrypt or just some network buggery going on. All problems I have had have all disappeared in seconds as well, further making me not bother to deal with it :P

                                                Might be an issue for some, but I have never had much of a problem.

                                              2. 4

                                                What are those kinks you feel need to be polished? I’d love to hear about them, so we can actually start working on improving them :)

                                                1. 3

                                                  Cool to see you around here as well! I hang around on the IRC for when I need to get some help :)

                                                  My biggest peeve is honestly the documentation and the convoluted setup of the core. My core is probably a bit outdated because I really don’t want to deal with the upgrade as I would have to figure out way too much stuff again. Here’s a few things that could be better about it though:

                                                  • Setting up the database is documented on the website, but I don’t see why it couldn’t just have been a script?
                                                  • Why is there a commandline switch to select the backend when you also have to provide a config file? Couldn’t it be specified there so the service setup would be simpler?
                                                  • User administration is a bit of a drag to deal with. Adding a user is simple enough (commandline switches like that is a bit of a pain, but I can manage), but managing them requires dealing with the database directly (deleting for example).
                                                  • It would be nice if more settings were synced between the clients, like the chat monitors and the input widget for example. Having to configure that every time is a bit of a pain. Also, it would be nice if the stylesheet would be synchronized between the clients.
                                                  • Also, push notifications while disconnected would be nice, but I realize this isn’t completely straight forward to do.

                                                  And a few words of praise!

                                                  • The documentation on the website has improved greatly since I used it last. There are many things there that weren’t around when I tinkered with it last time. Good job on that :)
                                                  • The client <-> core solution works very well in general. I feel this solution is way better than any other IRC client/bouncer combos I have ever used. It’s painfree to hop between clients.
                                                  • Everyone on the IRC channel is very helpful and whenever I have asked about things I have gotten a decent answer, and even had some of the issues I brought up fixed in the next version; like being able to reload the core for SSL cert renewals.
                                                  1. 2

                                                    Why is there a commandline switch to select the backend when you also have to provide a config file? Couldn’t it be specified there so the service setup would be simpler?

                                                    The command line switch automatically migrates between databases, while the config (or the new ENV variables) don’t automatically migrate, but only use that database.

                                                    Setting up the database is documented on the website, but I don’t see why it couldn’t just have been a script?

                                                    That’s actually planned, but we haven’t had time for that so far.

                                                    User administration is a bit of a drag to deal with. Adding a user is simple enough (commandline switches like that is a bit of a pain, but I can manage), but managing them requires dealing with the database directly (deleting for example).

                                                    That’s long been planned, but as you all know, we don’t have enough volunteers, and not enough time.

                                                    Also, push notifications while disconnected would be nice, but I realize this isn’t completely straight forward to do.

                                                    That’s actually my #1 priority right now (due to Quasseldroid), and it’s almost done! So you should see that within of 2020 :)

                                                    1. 3

                                                      Don’t get me wrong! I know you are all working hard on it and I see the progress all the time :)

                                                      When I said this:

                                                      I just wish there was a bit more development on it to polish out the kinks.

                                                      I was pretty much referring to what you say here:

                                                      but as you all know, we don’t have enough volunteers, and not enough time.

                                                      It’s really getting there :)

                                            1. 3

                                              I’m not an IRC expert, but I assume that I can connect from for example multiple machines running irssi and get all my messages simultaniously? You mention that it only supports TLS, but is that the connection between my client irssi and pounce, between pounce and the upstream server or both?

                                              1. 3

                                                Yes. You’ll want to have each irssi set a different username to indicate to pounce that they should both be getting their own copies of messages (see “Client Configuration” in the manual page).

                                                It is TLS-only in all directions.

                                              1. 2

                                                How do you render mdoc in gitea? I host my stuff on gitea and would like to show my docs like that as well.

                                                I currently convert them with mandoc to html when I build the project’s website with Hakyll

                                                1. 6

                                                  I have this in app.ini:

                                                  [markup.mandoc]
                                                  ENABLED = true
                                                  FILE_EXTENSIONS = .1,.2,.3,.4,.5,.6,.7,.8,.9
                                                  RENDER_COMMAND = /usr/local/libexec/gitea-mandoc
                                                  

                                                  where gitea-mandoc is a script that pipes mandoc through ttpre (just because gitea seems to do weird things to mandoc’s HTML output)

                                                  1. 1

                                                    Interesting, thank you!

                                                    mandoc’s html output is a bit weird to be honest.

                                                    1. 2

                                                      It mimics the troff typesetter’s way of separating paragraphs.

                                                      More recents versions uses that encapsulate the paragraphs. https://undeadly.org/cgi?action=article;sid=20190108193936

                                                      1. 1

                                                        Thank you very much for the link. I will check the new versions out!

                                                1. 10

                                                  This template:

                                                  1. Doesn’t let the user specify a C compiler,
                                                  2. Overrides CFLAGS from the system defaults/environment,
                                                  3. Overrides LDFLAGS from the system defaults/environment.

                                                  Project-specific CFLAGS and LDFLAGS should be set with += and the C compiler should be invoked with $(CC).

                                                  Additionally, I find generating a .depend file much cleaner than littering .d files:

                                                  depend: $(SRCS)
                                                  	$(CC) $(CFLAGS) -MM $(SRCS) > .depend
                                                  
                                                  -include .depend
                                                  
                                                  1. 3

                                                    Damn…I trounced the current high score (32704, I got 61768), but was expecting it to announce “game over” or something and exited the session without recording it. Oh well.

                                                    1. 4

                                                      Shit, sorry. I skipped implementing a game over check because it’s not entirely trivial.

                                                      1. 1

                                                        I did the same thing the first try, you could just leave a message at the bottom with instructions.

                                                    1. 7

                                                      Out of curiosity, is the web dead and we now write in groff?

                                                      1. 9

                                                        It’s mdoc, and one can dream.

                                                        1. 3

                                                          Why don’t you remove the top line with “FreeBSD Miscellaneous Information Manual”?

                                                          1. 1

                                                            Ah very well then, I forgive you.

                                                          2. 5

                                                            Just this guy.

                                                          1. 1

                                                            So when might I want a config-less editor? Genuine question.

                                                            1. 3

                                                              The article spends two paragraphs on this…

                                                              1. 6

                                                                The thing is that the article is predicated on the assumption that the editor you use has to be on the system where you’re editing the file. If there are constraints preventing you from setting the system up as you want then you just have to use what’s on the system. If that’s vi, then you use vi. If it’s another editor then you use that. End of story.

                                                                But if there are no constraints preventing you from running an sshd on the system, then you can use the emacs on your laptop, with your entire config, to access its file system using tramp and you don’t have to feel like you’re editing with one hand tied behind your back.

                                                                Maybe I should have phrased my question, given the choice, when would I want to choose to use a config-less editor?

                                                                1. 3

                                                                  Hello bon, here are my answers to your questions, I hope they are helpful.

                                                                  If there are constraints preventing you from setting the system up as you want then you just have to use what’s on the system. If that’s vi, then you use vi. If it’s another editor then you use that. End of story.

                                                                  Constraints are certainly one reason why I use vi on remote systems (I don’t always have sudo access :)), but sometimes I also just don’t want to take the time and put in the effort of installing my personal configuration of Emacs. Knowing how to use vi certainly releases some of the “pressure” of transferring my config directory: I just go “meh”, use vi, and I’m happy.

                                                                  But if there are no constraints preventing you from running an sshd on the system, then you can use the emacs on your laptop, with your entire config, to access its file system using tramp and you don’t have to feel like you’re editing with one hand tied behind your back.

                                                                  I don’t like Tramp in Emacs for two reasons. The main reason is that Tramp assumes that I know which file I want to edit, but very often when I’m on a remote system, it’s because it’s a server that’s misbehaving and I’m looking around for the issue. I want to be shelled into the machine and use all the Unix tools that I’m used to to find the problem: find, grep, htop, lsof, etc. I don’t know yet which file I want to edit, I’m still just fishing around for it.

                                                                  Once I find some candidates, I want to inspect them, determine if they’re what I’m looking for, and perhaps edit them. If I’m using the editor on the remote machine, that’s done really quickly. With Tramp, I need to switch from the ssh terminal to my Emacs window and try and remember the syntax for opening a remote file—that’s my other reason for not liking Tramp, I always forget its syntax—before I know if that file was interesting or not. That cuts into my flow, and so I don’t like to use Tramp.

                                                                  1. 2

                                                                    With Tramp, I need to switch from the ssh terminal to my Emacs window and try and remember the syntax for opening a remote file—that’s my other reason for not liking Tramp, I always forget its syntax—before I know if that file was interesting or not. That cuts into my flow, and so I don’t like to use Tramp.

                                                                    What do you mean with “syntax”? It’s just a regular C-x C-f and then /ssh:[ssh alias]/ [RET] and Tramp is turned on. Ivy even let’s me just type /ssh: and choose a host. You can even use eshell, and just type cd /[host]: and it’s the same as above. My issue is rather that it’s often too slow for a quick edit (as you mention), since Tramp has a bit of an overhead, due to all the data being transfered in base 62.

                                                                    1. 2

                                                                      If the remote system is running sshd, you can also use sshfs to mount the remote filesystem on your development machine. Probably not worth it to edit a single file, but it does make it easy to use any editor you like, along with any other tools you have on your development machine which aren’t on the target (Can do some exploration to find the file to edit, but that will depend whether exploration consists of looking inside various files and directories or also involves running executables on the remote machine). It’s also handy for things like using a visual diff tool to compare a remote file or directory with a local file or directory.

                                                                      1. 2

                                                                        The main reason is that Tramp assumes that I know which file I want to edit, but very often when I’m on a remote system, it’s because it’s a server that’s misbehaving and I’m looking around for the issue. I want to be shelled into the machine and use all the Unix tools that I’m used to to find the problem: find, grep, htop, lsof, etc. I don’t know yet which file I want to edit, I’m still just fishing around for it.

                                                                        As @zge mentions (and I think is important enough to reïterate), this is actually possible with Tramp: you can shell out with M-!, and run eshell, and everything just works as you would want. There’s no need for an ssh session in a terminal emulator at all, because emacs can handle it.

                                                                        As a practical matter (again, as @zge mentions), the performance is not necessarily as great as it could be. Still, it’s pretty powerful & it’s very often useful to me.

                                                                1. 4

                                                                  The idea is good but… It’s almost like the whole point of spreadsheets are to have a powerful way of manipulating data that doesn’t require much programming skills but still can do a whole lot of value adding.

                                                                  Of course you can do all the summations using a range of command line tools… But does it really but pressing ALT and =?

                                                                  I remain a bit doubtful for the approach :)

                                                                  1. 3

                                                                    For doing calculations my approach is to import the CSV/TSV into SQLite and query it there. It’s remarkably faster than importing into a spreadsheet program and doesn’t have arbitrary row count limitations.

                                                                    1. 3

                                                                      I didn’t know that was possible… Seems like a nice feature to know about. For future reference 1 is a link to the documentation about importing and exporting CSV files. For TSV files, see 2

                                                                      1. 2

                                                                        Years and years ago, I was cooking up a Django project that would read in downloadable CSV bank statements from my online bank.

                                                                        The purpose was this, but as the statement downloads can’t be automated and banks have been improving their reporting features, the project dwindled off.

                                                                        Being able to query by SQL or Django admin is a superpower, though.

                                                                        This Vim TSV business might be better suited for eg. how translators sometimes use CSV/TSV as an interchange format.

                                                                    1. 3

                                                                      I use neovim’s :Man command and K binding a lot, along with ctags integration.

                                                                      1. 12

                                                                        I don’t like tools that make using awk or cut harder.

                                                                        The output could be improved without using the parenthesis around the bytes, or having a flag .

                                                                        1. 5

                                                                          Tools should have optional JSON output so I can use jq queries instead of awk or cut :P

                                                                          1. 4

                                                                            I really like jq too :)

                                                                            1. 2

                                                                              https://github.com/Juniper/libxo

                                                                              This is integrated in most FreeBSD utilities.

                                                                              1. 3

                                                                                We should all switch to Powershell, where values have types and structure, instead of switching to a different text format.

                                                                            1. 1

                                                                              No mention of the standard assert.h? Don’t implement your own version of a standard function just because.

                                                                              1. 1

                                                                                For the leading-break, this is just a way to put a break for the previous case. In fact, my auto-formatter just moves it to the normal place for the previous case. It’s another way to remember to always break your cases I guess.

                                                                                1. 1

                                                                                  Yes, but it formats nicer for single-line cases and it is much easier to spot a missing break.

                                                                                  1. 1

                                                                                    What I’m saying is (for my formatter at least) is it won’t do that as a single line.

                                                                                    But I get it, it shifts your thinking from “I should break this case to prevent fall through to next” and shifts to “I’ll put a break before to prevent fall through from previous.”

                                                                                1. 3

                                                                                  One that people keep forgetting in initialisers is compound literals.

                                                                                  void foo(struct bar*){ … }

                                                                                  foo(&(struct bar){.baz = 0xdeadbeef});

                                                                                  1. 1

                                                                                    Can you really use & there? iirc C won’t let you pass &0xDEADBEEF, for example.

                                                                                    1. 2

                                                                                      Can you really use & there?

                                                                                      Try it out and see…if your compiler implements C99 it should work.

                                                                                      iirc C won’t let you pass &0xDEADBEEF, for example.

                                                                                      Not with that exact syntax, but you can do e.g. int* foo = (int[]){ 12, };.

                                                                                  1. 6

                                                                                    First example under-utilizes “nice” initializer syntax, in my opinion – could be written as

                                                                                    struct {
                                                                                            struct pollfd fds[2];
                                                                                    } loop = {
                                                                                           .fds = {
                                                                                              { .fd = STDIN_FILENO, .events = POLLIN, },
                                                                                              { .fd = STDOUT_FILENO, .events = POLLOUT, },
                                                                                            },
                                                                                    };
                                                                                    

                                                                                    A related designated-initializer syntax for arrays is particularly useful for arrays indexed by enums:

                                                                                    void handle_foo(void);
                                                                                    void handle_bar(void);
                                                                                    enum { Foo, Bar, };
                                                                                    void (*handlers[])(void) = {
                                                                                      [Foo] = handle_foo,
                                                                                      [Bar] = handle_bar,
                                                                                    };
                                                                                    
                                                                                    1. 4

                                                                                      Yeah the example is a bit contrived to demonstrate that designators can be chained together rather than having to nest more braces.

                                                                                    1. 17

                                                                                      Perhaps nitpicky, but I wouldn’t suggest recommending VLAs in a document like this. The consensus seems to be that it’s probably never wise to use them. They were also made optional in C11 (meaning compilers no longer have to support them and you have to test for __STDC_NO_VLA__ to check support). It’s basically syntactic sugar for the same thing alloca() does, which has all the same problems as VLAs:

                                                                                      The basic argument against them goes something like this: if the variable size argument(s) for your VLAs could end up being very large at runtime, they could overflow stack space and cause a crash. If your answer to this proposed crash (for a given VLA usage) is that your VLA size arguments are already constrained to stack-reasonable sizes, then it would be more efficient, compatible, and simple to simply declare a fixed-length stack array of the maximum possible size (since stack allocations just adjust a stack frame pointer). If you really do need the possibility of very large sizes and don’t want to possibly crash, the only sane approach is going to be to use heap allocatiors like malloc() and friends.

                                                                                      1. 7

                                                                                        I agree with you, and I don’t find this nitpicky at all. Use of VLAs is lately discouraged in the kernel, and there’s an active effort to remove them[1]. They’re not secure, and have slower performance, so a document about pleasant C should in my opinion discourage them, or not mention them at all, but not do the opposite.

                                                                                        1. 8

                                                                                          I don’t really mean to be encouraging use of specific C features here, just pointing out some things that I find pleasant to write. Perhaps a CAVEATS section is needed.

                                                                                          1. 3

                                                                                            Probably a good idea.

                                                                                            1. 2

                                                                                              Fair enough, sorry for hijacking your otherwise very nice page:)

                                                                                          2. 4

                                                                                            Neither malloc nor alloca are capable of the behaviour I pointed out that I found useful, unfortunately.

                                                                                            1. 2

                                                                                              How about:

                                                                                              T (*dyn)[len][h][w] = malloc(len * h * w * sizeof(T));
                                                                                              fread(dyn, h * w, len, stdin);
                                                                                              

                                                                                              one difference is that you now have to write (*dyn)[i][j][k] instead of arr[i][j][k]. Is there any issue that I’m not familiar with that can be caused by this approach?

                                                                                              1. 2

                                                                                                I thought multiplying values inside of malloc sizing was bad form due to overflow risks?

                                                                                                1. 1

                                                                                                  It would have to be done here one way or another, since calloc only does 1D arrays, sure you can do:

                                                                                                  size_t dyn_len = len * h * w * sizeof(T)
                                                                                                  T (*dyn)[len][h][w] = malloc(dyn_len);
                                                                                                  ...
                                                                                                  

                                                                                                  or have a function that does it:

                                                                                                  void *new_3d_array(size_t len, size_t h, size_t w, size_t type_size) {
                                                                                                      return malloc(len * h * w * type_size);
                                                                                                  }
                                                                                                  T (*dyn)[len][h][w] = new_3d_array(len, h, w, sizeof(T));
                                                                                                  

                                                                                                  or….

                                                                                                  #define SIZEOF_3D_ARRAY(X, Y, Z, TYPE) ((X) * (Y) * (Z) * sizeof((TYPE)))
                                                                                                  T (*dyn)[len][h][w] = malloc(SIZEOF_3D_ARRAY(len, h, w, T));
                                                                                                  

                                                                                                  If you often have to work with 3D arrays then you should definitely put an extra layer there that multiplies for you, but I didn’t do that here, because the example in the page was about convenience, and I wanted to show mallocing that can be used in exactly the same way with fread.

                                                                                                  Edit:

                                                                                                  Here’s a non performant version but with the overflow handling:

                                                                                                  void * new_3d_array(size_t len, size_t h, size_t w, size_t sizeof_type) {
                                                                                                          size_t hw = h * w;
                                                                                                          if (h != 0 &&  hw / h != w)
                                                                                                                  return NULL;
                                                                                                  
                                                                                                          size_t hwlen = hw * len;
                                                                                                          if (hw != 0 && hwlen / hw != len)
                                                                                                                  return NULL;
                                                                                                  
                                                                                                          size_t sothwlen = hwlen * sizeof_type;
                                                                                                          if (hwlen != 0 && sothwlen / hwlen != sizeof_type)
                                                                                                                  return NULL;
                                                                                                  
                                                                                                          return malloc(sothwlen);
                                                                                                  }
                                                                                                  
                                                                                                  func(size_t len, size_t h, size_t w) {
                                                                                                          T (*dyn)[len][h][w] = new_3d_array(len, h, w, sizeof(T));
                                                                                                          assert(dyn != NULL);
                                                                                                          fread(dyn, h * w, len, stdin);  // Nothing stops h * w from overflowing..
                                                                                                  }
                                                                                                  
                                                                                            2. 3

                                                                                              VLAs could be more fair if there would be a way to map them to a custom heap allocator, there’s nothing in the spec itself that dictates the allocation to be intertwined with your stack frame and obvious reasons why you would want to avoid just that. The whole principle is to get access to dynamic allocation tied to the scope of ‘auto’, what pool it is taken from is secondary - but with sizeof() being possibly dynamic, get something that isn’t malloc heap or compiler managed stack.

                                                                                            1. 1

                                                                                              Is there a better tag to use for documentation and/or markup languages?