In the end it's just personal preference but in the idea that code should be readable and maintainable first, while(true) is just a lot saner. Also since this is something you can write in pretty much any language (that has while loops) it's more universal
I use while loop all the time. It's just something I've always been doing since I started coding two years ago. Not very sure why though, maybe because it looks simpler.
I prefer while. As someone pointed out, for loops are usually associated with a loop index. In fact, my personal header file has a macro FOREVER that just evaluates to a while (true).
2nd theory: yes, it matters, stop rewriting loops, just use map/reduce/filter. it takes a lil while to get used to it, but it literally means you don't ever have to manually write loops again. not sure how much of an improvement it is in C, tho, because the amount of support for functional style might not be enough for this to be practical
@@civilizedgangster8024 Unless you actually looked up that that's the binary opcode for a jump instruction, I'm disappointed. - Which it isn't cause I just noticed that that's 18 bits wide
I had no idea about the for version of infinite loops lol. I think that while(true) is better because for loops are typically used for looping with an index and while loops are the unstructured alternative so it makes sense to do something as crazy as an infinite loop with while.
how about #define ever ;; for (ever) { } But I agree, it does not really matter, but since most of my infinite loops also contain actions to execute afterwards, I prefer the for-style: for (;;sleep(1)) { }
I use that #define in my head: I write “for (;;)” and read it “forever”. That's why I find the for loop more intuitive: one would never say “while true” in everyday language, whereas “forever” is quite common.
In the olden days, compilers weren't complex enough to make even simple optimizations. This is why, for example, the increment operator exists. All modern compilers treat "i += 1" and "++i" the same way, but for old compilers a different syntax was necessary to make the optimization. Now, as for the battle between for (;;) {} and while (true) {} - in the olden days the former would have spit out exactly what you intended, a straight loop with no comparison, while the latter would have rather dumbly checked to see if 1 doesnt equal zero every time. Because of this difference, it became standard for people to use for (;;) {}. However, for (;;) {} is (arguably) less readable than while (true) {}, so for people with modern compilers, where it spits out the exact same assembly, it has become more and more common to use the while form. Yet the old standard still persists, and perhaps, rightly so (or perhaps not, who cares?).
@@OGBhyve gcc 4.1.2 with -O0 optimizes the comparison away. It is probably one of the easiest optimizations to make, (and was thus probably one of the first things to be optimized away) but it is *an optimization*, which is the point. At the time the language was designed, such optimizations were not used, and the code you typed was much more intimately connected with the assembly.
@@jacobschmidt Not familiar with that one. Just tested on GCC 2.96. The assembly generated for both was the same using the jmp instruction and there wasn't a cmp instruction to be found. Interestingly, MSVC 19.27 does do a comparison for the while loop when using /O0. Once you use /O1 or higher though, it is optimized away.
I believe writing clear, understandable code is the main and common goal of programmers, instead of arguing about minor details and syntactic preferences, where the debate itself brings more anger and confusion than the actual "issue". Anyways, while(true) looks a lot better to me and I'm sticking with that.
I agree most of the time but that's not always true. On embedded systems for example you have the option to code for speed or size which is a trade off. The word hacker comes from this; hackers program something brilliant often difficult to understand but if you take time to understand it you'll learn a deeper understanding of programming.
@@alvinbee6194 I agree with this, programming is a very extensive area and you have to see it objectively in order to understand why things are. Today's "Coders" seem to think that everything revolves around what they do, much of this is because today these guys are programmers based on watching online courses and do not have the proper academic training. They program with a mindset that resources are limitless. But those of us who have experience developing embedded software work with very limited resources, both in capacity and speed, and we try to program while maintaining the readability of the code but with a greater focus on optimization.
@@alvinbee6194 Right, but embedded systems usually have guidelines, or rather rules for specific cases where it does make a difference; in which case you'd probably be best off by making the compiler do the grunt work, so that you can keep a readable source code without strange "hacks". An example of this is in any transportation system, train, aviation, etc. They have explicit guidelines and standards for how to write code certain ways, and avoid certain patterns, but they also have compilers that does away with most of the headaches, so you can focus on writing code and not sweat of the details. It's not always possible, though, but in a lot of cases it is.
Here are some other options: - while (1) - what about do while? - labels - who needs loops anyway, recursion all the way Also an extra argument for for(;;), if you popularize this style more people will be aware, that you can omit expressions from for loops.
Well recursion is not optimum when it's come to large software where lot of code is running and allocating stack space. So it's important. Depending on context.
Well said, as usual. One addition to your advice at the end: while shaking your head listening to arguments to this, add an eye roll. FWIW, I favor while(true), mainly because it was never obvious to me why the blank conditional expression in for(;;) should evaluate to true (other than that the standard says so).
My understanding is For Loops calculate the incremental after the statements, whereas While Loops can manipulate the increment before running statements
Use whatever makes sense based on the context. A good rule of thumb is to use while loops for truthy or falsy statements, like while (running), while (cursor > 1), while (!empty(array)) etc. think of it as what you'd put in an if/else condition. For loops are great for cases where you iterate over something specific, or need to keep track of indicies, as it glues the initialization, condition and update expressions together, rather than splitting them up: for (init; condition; update). While you can omit one or more expressions in the for loop, but it can be easy to miss when reading the code. At that point, a while loop may be more readable.
In theory, on some older or non-optimized compilers, while(true) might be slower than for(;;). But there really should be no case where for(;;) is slower than while(true).
Never seen that for version. i do not wanna use it or necessarily see it, because it makes me think of some depressed writing in the internet. Just having such a friend is enough
Run it through compiler explorer and see for yourself. 😉 It'll either spit out the exact same assembly as the other two forms, or it's not going to be very far off it.
It is the convention in all programming languages. That in itself is the sole reason for me to choose while (true). I always try to stay away from language specific practices (if there is no reason for it of course). That's why I hate modern c++ with all the unique and unintuitive semantics that you see no where else.
Adding fuel to the fire, while/do-while are bloat that are "necessary" to abstract the anti-pattern of looping without initial variable setup for readability/comprehension's sake. Whichever infinite loop style you choose, be consistent and don't shove it down people's throat.
do while is different from while in that a do expression will _always_ run at least once, whether the initial condition was falsy or not. This can be useful for cases where the code needs to do something before the loop condition can be evaluated. That's not to say that you should use do/while for every case where it makes sense; e.g. if you don't want side-effects and require variables to be initialized upfront, by all means don't use do.
Speaking to the concern of TRUE being redefined and breaking 'while(TRUE)', use 'while(1)'. If '1' ever gets redefined, you've got much bigger problems! 🙂
When using "while (true)", that "true" must be defined somewhere. So maybe "while(1>0)" is a better choice. But because of the condition in both cases, I would prefer "for(;;)", because it makes clear, that there is really no condition that must be checked. It is therefore a real for-ever loop.
i like for(;;) for mostly the same reasons why while(true) was left out of other languages, it's redundant and having more than one way to do something leads to non-useful variations. Also, one way to interpret the mentioned danger of 'meaning'(or the definition) changing that's more realistic is just that some day you may need to re-factor that while (true) code to actually be conditional or non-infinite, at which point it'll likely be most natural to switch over to for anyway. when maintaining large code-bases for a period of time you come to value uniformity(assuming it's not artificial or has other side-effects/costs). that's the primary reason the linux kernel leans towards using for (;;) any decent compiler should produce identical code, after that you're just catering to beginner programmers. Another way of stating that is you're lowering the bar on what you expect developers/contributors to be comfortable with, and lowering the bar just eases things short term at the expense of long term maintainability. also if you get in the habit of using for (;;) since it's effectively a superset of the functionality of while(true) and can always be used whenever either is an option, you will never waste time internally debating which to use/which is better also, another minor ease of use thing is just during debugging, it's a bit quicker/easier to modify the for loop to do useful things to help locate issues(add a loop counter, etc.)
> was left out of other languages, it's redundant and having more than one way to do something leads to non-useful variations That depends on how you wan't to read the code. In Rust, there are four types of loop expressions: for (iterator), while (predicates), while let (patterns) and loop (infinite). Each have their own meaning, whereas in C and C++ it's not as rigorous and can lead to confusion and bugs (you can test conditions with for and while loops, both can be made infinite, etc.) > some day you may need to re-factor that while (true) code to actually be conditional or non-infinite, at which point it'll likely be most natural to switch over to for anyway. That highly depends what your loop does. If your loops is meant to run until a predicate is false, a while loop is more readable than a for. For loops are great for iteration, rather than conditional looping. > when maintaining large code-bases for a period of time you come to value uniformit It's better to value readability and intent with context. While you _could_ exclusively use for loops for everything, using it for simple conditions (e.g. for (;condition;)) is less readable and more error-prone than while loops (e.g. while (condition)) with explicit initialization. > it's a bit quicker/easier to modify the for loop to do useful things to help locate issues That depends on what you're debugging, of course. I'd argue that it's much safer to explicitly define your debugging statements/variables outside so that they are easier to notice so you don't ship them in production code.
This warning only shows up in Visual C++ compiler afaik. However, this is actually a good argument against using for(;;), since the compiler helps you avoid infinite loops-which are usually a code smell or a bug, since you'll have to make sure your break out of the loop at some point to stop the execution inside the program. Examples of this is something like while(i >= 0) { --i }; which will be infinite if `i` is unsigned, or with macros: while(MACRO(i)) which will be infinite if the macro expands to a truthy value.
In the same way that you should try to limit the use of else in if-statements, you should always look for the positive (i.e. while) and avoid trying to catch the contrapositive. I actually prefer for-loops, especially for hitting items in a data structure, but while makes more sense in a lot of cases.
for(;;) is my preferred way because it shows that its a deliberate decision, not a "lets do this while(true) and change the condition later". It shows intent and that's important. It also reads nicely, like "for (ever)". instead of "while true". "do {} while (true)" is just wrong in my opinion. Generally, only use do-while if you need to, not by default.
The fastest way to generate assembly code for simple snippets of code like these is godbolt.org You can also use many different combinations of compilers and architectures, which is perfect for speculating about past and present performance of a piece of code.
I’ll just be in the safe side and use for loops although that I don’t believe that while loops are prone to error, and for readability I can just caption to explain that it’s a infinite loop
Awesome you hit it right on the head. You have to consider the architecture, the compiler and it's optimization. In older compilers it does matter and for some architecture it does matter. How do you tell by inspecting the assembly code or machine code ISA.
I think the while true way to do it is much more readable to because it is not ambiguous, It says what is does. It loops while the value of true is equal to true. but for ;; is less readable in that what does the ';;' mean. I personally had a lot of trouble finding out it's meaning when I started. But it's just what you prefer. I personally want my code to be more readable and be understood by beginners whom don't know what ';;' means. But do what you like, I don't care what way you implement your infinite loops, as long it works and is well formatted.
I'd love to hear its implications with interrupt driven programming, especially with C instead of C++. I worry that it may be using system resources, or switching to the process, when an infinite loop is used.
I use infinite for loops sometimes (`for (int i = 0; ; i++)`) when I need counter, like in example code you provided, but for other situations when I don't need to change anything I prefer `while` loop because it's known pattern and you can just look at it and say "hm, yes, it's infinite loop"
I like to use forever loops, because the intent is clear, but also because it amuses me, and I need any amusements I can get while writing code- #define EVER ;; for(EVER)
Hey Jacob, you should use tabs instead of spaces... just kidding! I prefere while(1) but it really doen't matter for me. Rust even made a specially loop to get round this issue, called loop {}
If it's only an infinite loop, I say while(true) for readability. But just to add some points to the for loop case, if there is some regular action you're performing at the end of every loop, the indefinite for-loop looks a lot more appealing and can usually make your code shorter (and perhaps remove the need for curly braces).
'while()' should only be present in code with its partner 'do' ( "do blah while(condition);" ) If you want to test a condition at the top of a loop, ALWAYS use 'for'. What could be clearer than: for( ;true; ) ??!! jk... gotta love these senseless "holy wars"... A presentation focussing on mastering "flow control" might be useful... One usually wants to exit an infinite loop at some time. Beginners (we all were at one time) can write incomprehensible code with numerous state flags (or arbitrary conditions) being evaluated to break/continue processing... One of my favourites has been a state machine with an enum naming discrete states and a for loop containing a switch (or two)... The last thing before the 'break' at the end of each 'case' is to set the state for the next iteration. This eliminates infinite loops because some processing somewhere will set the new state to 'eDone' that is tested by the bounding for() or while()...
Personally i just use while true because it's easier to type and read. I work on my own, so if something redefines "true" then I'll know my sanity needs to be checked. I mostly don't use C though, so I'm good. I'll never know the state of my sanity. :)
what if I make an infinite loop by recursively calling the main() function from within itself, but at the start of the function somehow modify the stack to clean up the repeating call, keeping the backtrace the same length
Don't put infinite loops in your code. Make it a "for" loop with a scope that exceeds what you know is reasonable. Or you could put in a " and --limit" which will do the same thing for a while loop. Better yet, use data structures that have a well designed "next function" so your loop looks like "while (next(...)){" and let the system make sure you don't get a runaway loop. I program almost exclusively in C for the past 20 years (over 500,000 lines in many projects) and I have no infinite loops.
Thanks for the perspective. A lot of infinite loops can and should be replaced with not-so-infinite alternatives. That said, I'm guessing you don't do a lot of embedded systems programming, where many device main loops are intended to run for(;;). 😉
I guess it would be the same. If you look at the assembly output in the video, the jmp instruction is used, which doesn't check for any conditions before jumping. My guess is that the goto version of the code will also look the same
When discussing software or firmware design, we have always referred to an infinite loop as a 'while-one-loop'. I have never heard anyone speak of a 'for-with-no-entries' block...
Am I going to be the next president of the universe? 5:32 Do you, Jacob, love me? 5:32 Will Elon Musk ever give up w33d? 5:32 Do you think this is funny? 5:32
I bet that people who use for loops also turn the toilet paper roll the wrong way round 🤪 but other than that I truly don't care what people use as long as they are consistent
I like to troll my colleagues by using goto. ;) I Pascal I would define a false boolean constant HellFreezesOver and then use repeat .... until HellFreezesOver.