RUST Discussion


  • Discourse touched me in a no-no place

    @Gaska said:

    It was meant to be bloody vague - my point isn't "you can use break or whatever in place of goto", but "there's always a better way to do something than goto". When making a list of features, it's easy to forget some particular one that you will then write a matching goto-using code where this feature would be perfect, and when I say that you can use this feature instead, you would be all blakeyranty about me not saying in my original post that this feature was allowed.

    This is the bit where I smack you with a rolled up newspaper for being wilfully obtuse.

    *SMACK*

    The argument I was making was that, as sane control flow patterns are identified that previously required a goto to implement, they get rolled into languages as more structured constructs. But it's a big step to go from this dynamic process of discovery to declaring that it is safe to declare goto as being entirely obsolescent.

    A sign that things aren't really right is when you've got some sort of boolean involved that states whether a particular place in the code was reached. If you're doing that, you're encoding control flow in your data flow, and that is a code smell…

    @Gaska said:

    My argument is that it isn't just much smaller, but literally empty.

    I still have that newspaper. ;-)

    @Gaska said:

    State machines are now being made using composition and hierarchical polymorphism.

    I'm not convinced that that's a necessary improvement. A key desire of any control-flow innovation is that it should make crystal clear what is going on, not hide it behind another layer of syntax.

    @Gaska said:

    Although TBH, parameterized breaks are clearer. Not all languages have then, however.

    This is an area where C++ is not leading, as it is relatively difficult to create new syntactic constructs in that language. Other languages allow much more power to innovate (typically at a cost in terms of performance, which is definitely acceptable to some).

    I think Java's labelled loops are better than PHP's numeric-labelled break, if only because the latter opens up the possibility of computing how far to break back, which gives me cold shivers…


  • ♿ (Parody)

    @dkf said:

    I think Java's labelled loops are better than PHP's numeric-labelled break, if only because the latter opens up the possibility of computing how far to break back, which gives me cold shivers…



  • @dkf said:

    This is an area where C++ is not leading, as it is relatively difficult to create new syntactic constructs in that language.

    Hmm, I suppose a macro around goto and/or longjmp() is the immediately obvious suggestion here... *evil grin*


  • I survived the hour long Uno hand

    What's the actual difference between
    break label;
    and
    goto label;

    ? Just the restrictions on when it can be used? Why not just have a convention that goto can only be used in a loop?



  • No no no, the goto one is vastly worse to the break one because goto is evil, see?



  • @Gaska said:

    Give me one example of when goto is a better choice than a loop, a conditional, break, continue, an inner function, a switch, or any other programming technique that can solve the problem leads to less readable code than goto.
    I definitely feel that error handling in C is a case where goto is the least-bad solution.

    @Gaska said:

    the lambda will be inlined
    While I'll agree that goto is acting as a workaround for a labeled break in that case, I think your lambda suggestion is still significantly less readable. IMO that's the sort of crappy workaround you'd use in a language that had neither labeled breaks nor gotos.

    (I also prefer goto to numbered breaks, e.g. Onyx's break 2, but not to actual labeled breaks.)

    @dkf said:

    This is an area where C++ is not leading, as it is relatively difficult to create new syntactic constructs in that language. Other languages allow much more power to innovate...
    ... what other languages?! One of what I view of C++'s few redeeming features is that I think it's much better than almost any other language at that. Lisps have it beat, Ruby has it beat, and... basically nothing else I know. It's not great, but plenty of languages give you almost no ability.


  • BINNED

    @dkf said:

    I think Java's labelled loops are better than PHP's numeric-labelled break, if only because the latter opens up the possibility of computing how far to break back, which gives me cold shivers…

    I feel this, possibly unneeded, urge to point out I was being sarcastic in my post.


  • Discourse touched me in a no-no place

    @EvanED said:

    basically nothing else I know.

    You need to get out more. 😀 🏃

    Seriously, learn more programming languages. You'll become better able to see the limitations in your tools, and a generally better programmer overall, even if you then decide that you're going back to using C++ anyway.



  • @dkf said:

    Seriously, learn more programming languages.
    I've used quite a few languages across a wide range of paradigms. (The one paradigm I'm really missing is a stack-based language like Forth.) Care to suggest any before accusing me of having limited experiences instead of just having a different opinions on a particular languages's... syntactic flexibility?

    (I guess I have a couple others I could add if you count language extensions; Template Haskell and Camlp4, though I haven't actually used either.)



  • @EvanED said:

    Care to suggest any before accusing me of having limited experiences instead of just having a different opinions on a particular languages's... syntactic flexibility?

    Hypertalk!



  • And because I'd probably get to this eventually, let's look at some examples of things that you can do in C++.

    The syntax for creating those abstractions isn't great (and in some cases is pretty awful), but I think C++ makes it possible to an extent that not many other languages match.



  • You can also write C++ while stabbing knitting needles through your dick Aztec-style... which is probably more pleasant than doing any of those three bullet points.



  • Clearly I have too much free time.

    extern "C" int printf(const char*,...);
    static int X=100,Y=100,Z=100;
    
    extern "C" {
        int dolots_goto(int q) {
            int result = 0;
            for(int i=0; i<X; i++) {
                for(int j=0;j<Y;j++) {
                    for(int k=0;k<Z;k++) {
                        result += (j-i)*(k-j);
                        if(k>q-j) {
                            goto skipped_rest_of_yz;
                        }
                    }
                    skipped_rest_of_yz: ;
                }
            }
            return result;
        }
    
        int dolots_lambda(int q) {
            int result = 0;
            for(int i=0; i<X; i++) {
                [&] {
                    for(int j=0;j<Y;j++) {
                        for(int k=0;k<Z;k++) {
                            result += (j-i)*(k-j);
                            if(k>q-j) {
                                return;
                            }
                        }
                    }
                }();
            }
            return result;
        }
    }
    
    
    int main() {
        int v;
        v = dolots_goto(30);
        printf("result = %i\n", v);
        v = dolots_lambda(30);
        printf("result = %i\n", v);
    }
    

    The results are interesting:

    C:\dev\local\loopgoto>g++ loopgoto.cpp -std=c++11 -O3
    C:\dev\local\loopgoto>a
    result = -14383700
    result = -2455200
    

    The assembly output for the functions dolots_goto() and dolots_lambda() are roughly the same length (you can thow a -s on the end of the g++ command), but seeing as they don't actually do the same thing, it doesn't really seem productive to compare them further...



  • @EvanED said:

    Pre-C++11 C++ doesn't support lambdas? You can make a syntax for expression lambdas out of core-language features.

    You can, but (A) Boost, and (B) the resultant 'feature' is so awkward to use that you'd probably end up wishing you hadn't.

    (And actually like C++. Well, parts of it, at least.) I agree with the general thrust of your comment but I dispute this bulletpoint!



  • Turns out gotos really are evil.

    extern "C" int printf(const char*,...);
    static int X=100,Y=100,Z=100;
    
    extern "C" {
        int dolots_goto(int q) {
            int result = 0;
            for(int i=0; i<X; i++) {
                for(int j=0;j<Y;j++) {
                    for(int k=0;k<Z;k++) {
                        result += (j-i)*(k-j);
                        if(k>q-j) {
                            goto skipped_rest_of_yz;
                        }
                    }
    //              skipped_rest_of_yz: ;
                }
                skipped_rest_of_yz: ;
            }
            return result;
        }
    
        int dolots_lambda(int q) {
            int result = 0;
            for(int i=0; i<X; i++) {
                [&] {
                    for(int j=0;j<Y;j++) {
                        for(int k=0;k<Z;k++) {
                            result += (j-i)*(k-j);
                            if(k>q-j) {
                                return;
                            }
                        }
                    }
                }();
            }
            return result;
        }
    }
    
    
    int main() {
        int v;
        v = dolots_goto(30);
        printf("result = %i\n", v);
        v = dolots_lambda(30);
        printf("result = %i\n", v);
    }
    

  • Discourse touched me in a no-no place

    @Gaska said:

    Give me one example of when goto is a better choice than a loop, a conditional, break, continue, an inner function, a switch, or any other programming technique that can solve the problem leads to less readable code than goto.

    Cleanup code on error in quite a few kernel sources, especially in drivers:

    http://lxr.free-electrons.com/source/arch/s390/kernel/time.c#L1390

    1390 static int __init etr_init_sysfs(void)
    1391 {
    1392         int rc;
    1393 
    1394         rc = subsys_system_register(&etr_subsys, NULL);
    1395         if (rc)
    1396                 goto out;
    1397         rc = device_create_file(etr_subsys.dev_root, &dev_attr_stepping_port);
    1398         if (rc)
    1399                 goto out_unreg_subsys;
    1400         rc = device_create_file(etr_subsys.dev_root, &dev_attr_stepping_mode);
    1401         if (rc)
    1402                 goto out_remove_stepping_port;
    1403         rc = etr_register_port(&etr_port0_dev);
    1404         if (rc)
    1405                 goto out_remove_stepping_mode;
    1406         rc = etr_register_port(&etr_port1_dev);
    1407         if (rc)
    1408                 goto out_remove_port0;
    1409         return 0;
    1410 
    1411 out_remove_port0:
    1412         etr_unregister_port(&etr_port0_dev);
    1413 out_remove_stepping_mode:
    1414         device_remove_file(etr_subsys.dev_root, &dev_attr_stepping_mode);
    1415 out_remove_stepping_port:
    1416         device_remove_file(etr_subsys.dev_root, &dev_attr_stepping_port);
    1417 out_unreg_subsys:
    1418         bus_unregister(&etr_subsys);
    1419 out:
    1420         return rc;
    1421 }
    

  • kills Dumbledore

    Needs more braces, otherwise you get the goto error bug

    if (failurecondition)
        goto error;
    if (failurecondition2)
        goto error;
    //if (failurecondition3)  /*commented out, not applicable any more*/
        goto error;
    ...
    

  • Discourse touched me in a no-no place

    I think in a situation like that, I'd like to use macros to make the setting of the error condition, the checking of it, and the escaping to an error exit path be a consolidated whole:

    static int __init etr_init_sysfs(void)
    {
            int rc;
    #define RESCUE(operation, rescueTarget) do{if((rc=(operation))!=0)goto rescueTarget;}while(0)
    
            RESCUE(subsys_system_register(&etr_subsys, NULL),  out);
            RESCUE(device_create_file(etr_subsys.dev_root, &dev_attr_stepping_port),  out_unreg_subsys);
            RESCUE(device_create_file(etr_subsys.dev_root, &dev_attr_stepping_mode),  out_remove_stepping_port);
            RESCUE(etr_register_port(&etr_port0_dev),  out_remove_stepping_mode);
            RESCUE(etr_register_port(&etr_port1_dev),  out_remove_port0);
            return 0;
    
        out_remove_port0:
            etr_unregister_port(&etr_port0_dev);
        out_remove_stepping_mode:
            device_remove_file(etr_subsys.dev_root, &dev_attr_stepping_mode);
        out_remove_stepping_port:
            device_remove_file(etr_subsys.dev_root, &dev_attr_stepping_port);
        out_unreg_subsys:
            bus_unregister(&etr_subsys);
        out:
            return rc;
    }
    

    Of course, I suspect you simply wouldn't write it like this in C++ in the first place — this feels like code that would map to something in a constructor with RAII dealing with the backout — but I'm not sure if that's a good thing or not in a kernel, where C++'s overheads are quite costly…


  • Banned

    @tar said:

    See, "parameterized breaks" are spelled goto in C++ :P

    Except nothing prevents you to goto from the inner loop to the initialization code half the function before, and break can be used exclusively to go immediately after the closing bracket.

    @tar said:

    Of course, I'd want to see the assembly language out for both versions of the function before a conceding that the lambda version is a valid replacement.

    http://www.filedropper.com/testasm
    Did testing with MinGW 4.8.1 with -std=c++11 and -S. The result is, at -Os the results are identical, at -O1, -O2 and -O3 some instructions are different between the two programs or in different order, with one or two more instuctions in lambda version. At -O0, lambda version is over 50% larger, but it doesn't count since I was speaking of optimizations.

    @dkf said:

    But it's a big step to go from this dynamic process of discovery to declaring that it is safe to declare goto as being entirely obsolescent.

    Big steps are sometimes necessary.

    @dkf said:

    I'm not convinced that that's a necessary improvement. A key desire of any control-flow innovation is that it should make crystal clear what is going on, not hide it behind another layer of syntax.

    The whole point of abstraction is to hide everything behind a layer of syntax - in order to make it clearer. current_state = blakeyrant tells me much more than goto blakeyrant somewhere in the middle of one of several infinite loops (because that's the only way I can imagine goto being used to shift between states - I might be wrong though, and would love to see an example of doing it another way).

    @Yamikuronue said:

    What's the actual difference between break label; and goto label;?

    That in case of goto, the label can be anywhere.

    @EvanED said:

    I definitely feel that error handling in C is a case where goto is the least-bad solution.

    C is very old language. Saying that goto is best thing you can do in C is like saying a black powder mortar is the best tool for assaulting enemy castle.

    @EvanED said:

    While I'll agree that goto is acting as a workaround for a labeled break in that case, I think your lambda suggestion is still significantly less readable.

    Every new syntax is unreadable. But if you get used to C++11 lambdas, it's obvious.

    @EvanED said:

    The syntax for creating those abstractions isn't great (and in some cases is pretty awful), but I think C++ makes it possible to an extent that not many other languages match.

    And then your codebase looks like shit. I cringe every time I have to write DECLARE_ENUM((MyNamespace)(MyEnum), (Foo)(Bar)).

    @tar said:

    The assembly output for the functions dolots_goto() and dolots_lambda() are roughly the same length (you can thow a -s on the end of the g++ command), but seeing as they don't actually do the same thing, it doesn't really seem productive to compare them further...

    Are you sure you don't get any signed integer overflow? Because technically, they are undefined behavior, and gcc -O3 loves trolling people over undefined behaviors.

    @dkf said:

    C++'s overheads (you've got failures, so you've got exceptions…)

    Most C++ game developers disable exceptions in their compilers for this exact reason. Returning error codes is still a thing there.


  • Discourse touched me in a no-no place

    @Gaska said:

    The whole point of abstraction is to hide everything behind a layer of syntax - in order to make it clearer. current_state = blakeyrant tells me much more than goto blakeyrant somewhere in the middle of one of several infinite loops (because that's the only way I can imagine goto being used to shift between states - I might be wrong though, and would love to see an example of doing it another way).

    But next_state blakeyrant may be more informative still in the overall context of the program. 😄

    It's a feature of control-flow innovations that things that appear to be completely obvious and trivial after the fact are really very difficult to conceive of beforehand. They change how people think about problems. Examples include things like coroutines, which make doing interruptible synchronous state machines much easier, since they enable you to use control flow idioms to describe them instead of having to spread them over a bunch of functions (procedures, methods, etc).

    I'm not very up to date on how they're done in C++ (there's boost::coroutine, but that looks horrific to me :) )


  • Banned

    @dkf said:

    It's a feature of control-flow innovationsprogramming languages that things that appear to be completely obvious and trivial after the fact are really very difficult to conceive of beforehand.

    FTFY

    @dkf said:

    I'm not very up to date on how they're done in C++

    They're not.


  • Discourse touched me in a no-no place

    @Gaska said:

    They're not.

    Except for the… thing… I mentioned immediately after.


  • Banned

    There are people who return from lookup functions via exceptions. There are people who mmap() memory to address 0. There are people who write GUI applications in Bash scripts. And there are people who use boost::coroutine and boost::spirit.


  • FoxDev

    .... and all of those people can be politely shown the door and told they can expect their last paycheck in the mail.


  • BINNED

    @dkf said:

    Examples include things like cgoroutines

    FTFY

    *ducks*


  • Discourse touched me in a no-no place

    @dkf said:

    I'm not sure if that's a good thing or not in a kernel, where C++'s overheads are quite costly…

    Allegedly. I'm not entirely convinced myself and have a gut feeling that "it started in C, it stays in C" is prevailing.

    Not that I have many fucks to give in that particular argument - having delved rather too deeply into the USB drivers for my liking in Linux some 7 years ago (hence knowing about this to begin with,) I have no desire to try and convince anyone of import of the benefits, or otherwise, of changing how they want to write their code and simply want to do as little as possible in there to get what I want doing, done.

    Then GTFO ASAP.



  • The point where I realized you weren't talking about RUST

    @tar said:

    EDIT: While I still have write access to the OP, this is now the Rust Coding Help thread. Please post <del>teh codez</del> <ins>solutions</ins> to any of my Rust development scenarios <s>homework</s> below.
    Or feel free to ask questions about Rust and one of our resident <del>experts</del> will get back to

    I guess you can code in RUST? Maybe it supports modding.

    I tried to write a quick & dirty implementation of a Tree in Rust. I would imagine it's fairly entertaining to anyone who actually knows what they're doing:

    [snip]
    

    Assumption made, not looking at the code.

    <small>Code was updated to use if let syntax...)</small>

    There's a function called Tree::new() which builds trees (calling into new_help() from time to time).

    You can build trees?

    Once you've built a tree you can call visit() on it and visit each node in the order they were created.

    Visit is like a ElderScrolls COC call right?

    Sorting (or in fact, anything useful at all) is not supported. Release early, release often!

    If I wanted to go to town on it,

    Ok, you built a town fast.

    I'd probably spend a bit more time working on the node! macro to make building literal trees a bit less syntax heavy. Having to call Tree::new() and then use a special macro inside it is pretty dumb, but whatever. It's mildly less annoying than Tree::new(box Node(100, box Node(50, box Nil, box Nil), box Nil, box, box, box, box, pox, box, eggs and spam).

    Actually that maybe a sign that I'm probably doing too much boxing and unboxing,

    Loot from boxes. Check!

    and there's some reference-stealing shenanigans which I managed to hide by copying an object (I think) with let q = *v; //weird.

    Ok, I know you can't copy an object. WTF is RUST?

    Also I couldn't get closures to work properly for some reason, and all the online docs seem to be referring to a version of Rust that no longer exists, and that didn't help much either...


  • Discourse touched me in a no-no place

    @PJH said:

    Not that I have many fucks to give in that particular argument - having delved rather too deeply into the USB drivers for my liking in Linux some 7 years ago (hence knowing about this to begin with,) I have no desire to try and convince anyone of import of the benefits, or otherwise, of changing how they want to write their code and simply want to do as little as possible in there to get what I want doing, done.

    That reminds me of the crime against Linux I committed more than 20 years ago (my, how time flies!) in order to be able to run binaries from a mounted FAT16 filesystem. The problem? The files in FAT16 are not kilobyte-aligned on the disk, or at least not guaranteed to be so, and that made the Linux memory manager of the time really upset.

    The hack I did to work around this — making all sectors in the filesystem except the first appear in virtual space to start 512 bytes later than they really did, together with some trickery in the sector calculations, because the hardware could load at 512 byte boundaries just fine — was never sent to anyone other than the person who commissioned me to do the work. It was a definite WTF, and clear to me that this was so even then. It worked quite well though; yes, there was a disk sector that appeared twice in the virtual map when my code decided to kick in, but it wasn't one that was normally read by anything.

    Did I mention that I still truly hate FAT16? (FAT12 was just as bad, but had the advantage of being just about OK for the only thing it was ever actually used for: floppy disks.)



  • @xaade said:

    The point where I realized you weren't talking about RUST

    At some point I tried googling something like "Rust Alpha Tutorial" and wound up on... that game site.
    ( :wtf: are all these nekkid dudes in fields about and :wtf: do they have to do with native development... )



  • @tar said:

    native development... Surviving the native environment. Check!

    <post not empty, stupid disco>

    Again, :wtf: is this RUST?

    Hmmm..... programming is a survival game?



  • @Gaska said:

    C is very old language. Saying that goto is best thing you can do in C is like saying a black powder mortar is the best tool for assaulting enemy castle.
    And yet plenty of people still use it. You are the one who set the rules (saying there is no situation in which there's something better than goto), not me. You can't say "what I really meant was 'there's no situation in a modern language'". Well, I mean you could, but "my" counterexample still applies to what you originally said.

    @Gaska said:

    I cringe every time I have to write DECLARE_ENUM((MyNamespace)(MyEnum), (Foo)(Bar)).
    Like I said, the syntax isn't the greatest.... BUT, it at least gives you an option, more than most languages.


  • Banned

    @EvanED said:

    And yet plenty of people still use it. You are the one who set the rules (saying there is no situation in which there's something better than goto), not me. You can't say "what I really meant was 'there's no situation in a modern language'". Well, I mean you could, but "my" counterexample still applies to what you originally said.

    Fix one loophole, make another... Okay, I admit that your counterexample is valid.



  • @delfinom said:

    Shit, I guess Linux and BSD kernels are bad.

    No, but their code is bad.



  • @CreatedToDislikeThis said:

    No, but their code is bad.

    Somebody is bitter



  • @Jaloopa said:

    Needs more braces, otherwise you get the goto error bug

    if (failurecondition)
        goto error;
    if (failurecondition2)
        goto error;
    //if (failurecondition3)  /*commented out, not applicable any more*/
        goto error;
    ...
    ```</blockquote>
    
    And that is why the single line ifs are permabanned in my codebases. (commit hooks and build scripts do a syntax/style check). Shorthand notation is generally a bad idea or anything that works on assumptions in general (i.e. nobody addsany logic in between). I absolutely hate languages where the last expression result in the function is automatically the return value.

  • :belt_onion:

    @delfinom said:

    And that is why the single line ifs are permabanned in my codebases. (commit hooks and build scripts do a syntax/style check).

    how does that help for this:
    [code]
    //if (failurecondition3) /commented out, not applicable any more/
    {
    goto error;
    }
    [/code]

    If the guy (or girl) was so full of fail that he couldn't properly comment out your example, what makes you think he (or she) could properly comment out ANY blocks of code.



  • @darkmatter said:

    how does that help for this:

    //if (failurecondition3) /*commented out, not applicable any more*/
    {
       goto error;
    }
    ```</blockquote>
    
    K&R bracing style for the win, again!
    

    //if(fail) {
    goto escape;
    }



  • Do any C/C++ compilers have something like a -Windent that will warn if code violates, say, Python-ish indentation rules? Or any other tools for that?

    Edit: Nifty... looks like some LLVM folks are/were playing around with this idea. (Inspired by goto fail even.) No activity for 3/4 of a year though... But I also see references to it around places. Maybe it's in Clang? I don't have an install handy.



  • @EvanED said:

    -Windent

    That's the advantage of {} languages over Python—the compiler has the information it needs to double-check your indentation is consistent, and warn you about it if it isn't, rather than just doing something retarded instead.



  • @tar said:

    That's the advantage of {} languages over Python—the compiler has the information it needs to double-check your indentation is consistent, and warn you about it if it isn't, rather than just doing something retarded instead.

    OTOH -- in Python, screwed-up block structure sticks out like a sore thumb to begin with, unlike {} languages, where it's possible for the indentation to totally lie to you about the block structure of the code.



  • I've written decent amounts of Python before, and honestly I have no problem with the lack of curly braces. Errors of the "wrong code block" type are pretty damned easy to detect in Python, frankly-- although I can see it becoming a problem if people get to "clever" with their syntax.



  • @tarunik said:

    OTOH -- in Python

    Oh god. Do you need help getting out.



  • The most irritating problem that Python's lack of block delimiters caused me was the need to use pass occasionally to indicate that there's no code here:

    class BaseClass:
        def empty_base_class_function_for_overriding():
            pass
    


  • @xaade said:

    Oh god. Do you need help getting out.

    Naw, I'd rather have the snake at my side. ;)



  • @darkmatter said:

    how does that help for this:
    [code]
    //if (failurecondition3) /commented out, not applicable any more/
    {
    goto error;
    }
    [/code]

    If the guy (or girl) was so full of fail that he couldn't properly comment out your example, what makes you think he (or she) could properly comment out ANY blocks of code.

    TBH, if someone fucks that one up, then well....special. The bracketless is easier to kludge.

    Then again...we hired a senior programmer lady...who thought #ifdefs were runtime.....

    so yea.


  • Banned

    Random news: Rust alpha 2 comes out today. One of several dozen new features is that @tar's closure-returning function doesn't need explicit lifetime anymore. Also, for &i in vec instead of for i in vec.iter() (if you omit the &, vec gets consumed, so be wary).



  • @Gaska said:

    Random news: Rust alpha 2 comes out today. One of several dozen new features is that @tar's closure-returning function doesn't need explicit lifetime anymore.

    Awesome. Can you return closures on the stack yet (that is, can function return type be an unboxed trait)?


  • Banned

    Nope, not yet. Return type must be concrete, and closures are of local anonymous type that can't be named. But someone's working on it - it'll not be ready for 1.0, though.


  • :belt_onion:

    @delfinom said:

    who thought #ifdefs were runtime.....

    ow 😦

    Back to your original commented out single line if conditional -
    The main problem I saw with the kludge was that it wasn't properly indented, which makes it a lot harder to notice.

    I used to do the single line after an if method, but I always formatted it proper indentation and always made sure to put a blank line after the conditional statement so there is a noticeable difference.
    eg.

    lines of code
    lines of code
    lines of code
    
    if (theBooleanThing)
         someFunctionThatDoesStuff();
    
    morelinesofcode
    morelinesofcode
    morelinesofcode
    ```
    
    Since a couple of years ago though, I stopped doing that and just started using braces 100% of the time, mostly for the types of reason in your posts above (and partly because if I always put the blank line after, what's the point in not using braces; it's not like I'm saving line space!)


  • When I do single-line ifs, I put everything on the same line. If I need more than one line, I use braces. It's foolproof.


Log in to reply