|
Jabor posted:Mainly because feeling the need to jump out of a highly-nested loop while remaining in the same function usually indicates that the function is too busy and should be broken down into smaller, more digestible parts anyway. Alternatively, it could mean that you're doing error-prone manual cleanup of resources instead of doing it properly. I disagree, in many cases nested loops make sense right where they are and don't need their own function. For example scanning over rows and columns of some 2d array. Hubis posted:I'd use a bool flag and "if (bBailout) break;" checks at the end of each loop, myself, but it depends on the code. This sounds a lot like doing anything to avoid a goto.
|
# ? Mar 8, 2016 02:52 |
|
|
# ? May 19, 2024 07:05 |
|
HappyHippo posted:I disagree, in many cases nested loops make sense right where they are and don't need their own function. For example scanning over rows and columns of some 2d array. for tight loops that are algorithmically coupled already, I'd agree. For larger code or loops where there's some non-trivial side-effects that need to be managed, I like the flag because it puts each each layer in charge of its own execution -- it makes it harder for someone to add something to an outer-loop and not understand why it's not getting called because some inner loop is hitting a goto. The "harmfulness" of a goto is proportional to the complexity of the surrounding code.
|
# ? Mar 8, 2016 03:19 |
|
Hubis posted:for tight loops that are algorithmically coupled already, I'd agree. For larger code or loops where there's some non-trivial side-effects that need to be managed, I like the flag because it puts each each layer in charge of its own execution -- it makes it harder for someone to add something to an outer-loop and not understand why it's not getting called because some inner loop is hitting a goto. Fair enough, so long as the flag has a relevant name.
|
# ? Mar 8, 2016 03:34 |
|
HappyHippo posted:I disagree, in many cases nested loops make sense right where they are and don't need their own function. For example scanning over rows and columns of some 2d array. Actually, "scan through this 2d array until you find something" is exactly the sort of thing that can be abstracted into a small function. You don't actually give a poo poo about the mechanics of iterating through the array, you only care about the test you're doing on each element and what you're going to do once you find what you're after.
|
# ? Mar 8, 2016 03:49 |
|
Jabor posted:Actually, "scan through this 2d array until you find something" is exactly the sort of thing that can be abstracted into a small function. You don't actually give a poo poo about the mechanics of iterating through the array, you only care about the test you're doing on each element and what you're going to do once you find what you're after. How is this any different than extracting every loop into its own function? There's no significant difference between looping over one variable or over two. Pulling it out to its own function is unnecessary.
|
# ? Mar 8, 2016 04:15 |
|
Jabor posted:Actually, "scan through this 2d array until you find something" is exactly the sort of thing that can be abstracted into a small function. You don't actually give a poo poo about the mechanics of iterating through the array, you only care about the test you're doing on each element and what you're going to do once you find what you're after. Moving things to other functions that are used exactly one time is also something that sort of confuses me. It's like reading a book but the author scrambled the pages for some reason, and they're telling you it's actually incredibly good this way. Sure a decent IDE can jump to definitions, but they can also collapse code regions too. Sex Bumbo fucked around with this message at 04:26 on Mar 8, 2016 |
# ? Mar 8, 2016 04:16 |
|
Sex Bumbo posted:Moving things to other functions that are used exactly one time is also something that sort of confuses me. It's like reading a book but the author scrambled the pages for some reason, and they're telling you it's actually incredibly good this way. Ideally, the function name should be obvious enough that there's no need to actually look at the definition if you're trying to figure out what the code is doing anyway. So it's more like reading a book, and instead of "He grabbed the handle, and turned. Pushing slightly, the large wood and metal slab moved forward on its hinge, allowing access to the space behind it" the guy wrote "And then he opened the door".
|
# ? Mar 8, 2016 04:39 |
|
HappyHippo posted:How is this any different than extracting every loop into its own function? There's no significant difference between looping over one variable or over two. Pulling it out to its own function is unnecessary. Actually, just scanning over a single array to find a value is also something you want to extract into its own function. (the function is called std::find_if) Similarly, you're not actually searching through a two-dimensional array once. You're doing it dozens of times. You don't care about the mechanics of the search, you only really care about what your search condition is this time.
|
# ? Mar 8, 2016 04:42 |
|
Jabor posted:Actually, just scanning over a single array to find a value is also something you want to extract into its own function. I don't know what you're talking about any more. Are you talking about extracting generic looping operations into functions like find_if (a good idea, although one that is more the domain of the standard library), or are you talking about extracting specific loops within procedures into their own functions (unnecessary)? Because your initial post sounded like the former: Jabor posted:Mainly because feeling the need to jump out of a highly-nested loop while remaining in the same function usually indicates that the function is too busy and should be broken down into smaller, more digestible parts anyway. Alternatively, it could mean that you're doing error-prone manual cleanup of resources instead of doing it properly.
|
# ? Mar 8, 2016 05:25 |
|
Jabor posted:Actually, just scanning over a single array to find a value is also something you want to extract into its own function. Herb Sutter and Scott Meyers have completely corrupted the minds of an entire generation.
|
# ? Mar 8, 2016 05:29 |
|
For loops are more practically editable as you maintain your code between now and infinity. You want to keep your code in a low-energy state so that there's low cost to making changes, adding logging statements and the like, and making improvements. sarehu fucked around with this message at 05:59 on Mar 8, 2016 |
# ? Mar 8, 2016 05:55 |
|
What's low energy code?
|
# ? Mar 8, 2016 09:00 |
|
hackbunny posted:I should have added an asterisk to that "nothing". Placement new is another easy way to skip destructors (I don't recommend using placement new, like ever) Do you mean that you have to explicitly specify how to call the destructor if you're unique_ptr-ing a placement new?
|
# ? Mar 8, 2016 16:00 |
|
roomforthetuna posted:Why is placement new special for skipping destructors? You can skip destructors with any 'new' you like, by not calling delete, just like you might skip calling the destructor with placement new. No placement delete, you have to call the destructor (!) yourself. Don't use placement new unless you're absolutely totally sure of what you're doing
|
# ? Mar 8, 2016 16:09 |
|
Klades posted:Ideally, the function name should be obvious enough that there's no need to actually look at the definition if you're trying to figure out what the code is doing anyway. You can collapse a code region and put a comment above it too though. code:
I can't really articulate why I don't like that. Sex Bumbo fucked around with this message at 21:34 on Mar 8, 2016 |
# ? Mar 8, 2016 21:26 |
|
pseudorandom name posted:What's low energy code? Maybe it's a high-energy state and I got the metaphor backwards. Anyway you can change your code from one state to another more easily if it's written using for loops and such, compared to if you use find_if or accumulate and such, where you have to do more janitoring to get it from one form to another. So if you write code with find_if, that's neat, in particular if it's less work in the first place (and IMO it often is, especially in non-C++ languages) -- but once you need to change it to something for which your higher-level function doesn't work, you should drop it and just have a honking for loop, or while loop. (And maybe some gotos, for garnish.)
|
# ? Mar 8, 2016 22:29 |
|
Sex Bumbo posted:You can collapse a code region and put a comment above it too though. Well your code begins to look like Perl, for one
|
# ? Mar 8, 2016 22:44 |
|
hackbunny posted:No placement delete, you have to call the destructor (!) yourself. Don't use placement new unless you're absolutely totally sure of what you're doing Placement new is really no harder to handle than regular new, it just has less support in unique_ptr etc. and you're less likely to know about it because it doesn't tend to get taught. But if it did get taught, it isn't any harder to understand placement new + call the destructor than it is to understand new and delete. (To be fair, when I mentioned this earlier I did have to look up unique_ptr to see if it's possible to scope-destruct things you placement-new'd - it is, but not trivial. I think you could fairly easily make a unique_placement_ptr template that would handle it correctly.)
|
# ? Mar 9, 2016 01:46 |
|
roomforthetuna posted:(To be fair, when I mentioned this earlier I did have to look up unique_ptr to see if it's possible to scope-destruct things you placement-new'd - it is, but not trivial. I think you could fairly easily make a unique_placement_ptr template that would handle it correctly.) code:
|
# ? Mar 9, 2016 02:05 |
|
roomforthetuna posted:Sure, but don't use new either if you don't know what you're doing. That's even worse because you're introducing memory leaks when you neglect to clean up, whereas with placement new at least you're only leaking sub-objects. What would you suggest to do when dealing with a C API that accepts a struct as a parameter, and that struct has a "void* user_data" member? And then you need that user_data later on, when you're far away from the original scope when the struct was created and initialized? Making an unique_ptr live that long would require quite a bit of refactoring plus not to mention leaking the API to the header and to whoever includes that. That can be solved with pimpl, but you are still left with the non-trivial refactoring problem.
|
# ? Mar 9, 2016 02:11 |
|
Sometimes refactoring is necessary to allow resource ownership to be explicitly encoded. Do it, preempt the otherwise nearly inevitable leaks, and try to plan ahead better next time.
|
# ? Mar 9, 2016 02:22 |
|
Ralith posted:Sometimes refactoring is necessary to allow resource ownership to be explicitly encoded. Do it, preempt the otherwise nearly inevitable leaks, and try to plan ahead better next time. I understand that and I agree ... usually ... but in this particular case the struct itself is the owner. What refactoring would do would destroy an otherwise very clean design with clearly defined boundaries. To leak that pointer outside the scope of the struct (in order to prolong its life) would essentially give ownership of that unique_ptr to a different entity who should not have any business in managing lifetime of those objects. Essentially, from what I can see, I can either maintain the clean design, with the downside of having to do a new and later on a delete (all encapsulated in a higher order unique_ptr with a custom deleter, since ... that's life in C) or break the design only so that I don;t have to do new/delete. Anyway, thanks for the input. Its been bugging me for a while that maybe I'm missing something, some better way.
|
# ? Mar 9, 2016 02:39 |
|
Volguus posted:I understand that and I agree ... usually ... but in this particular case the struct itself is the owner. It's possible for a poorly designed or sufficiently foreign library to force you to write ugly code, but I've worked extensively with that type of struct-with-a-pointer C API in e.g. libuv and never had trouble applying safe(r) resource management with it. Ralith fucked around with this message at 02:53 on Mar 9, 2016 |
# ? Mar 9, 2016 02:47 |
|
Ralith posted:Well, who owns the struct? Is there anything stopping you from exposing a wrapped version of it with a destructor, move constructors, etc? I could wrap it I guess, it would be a solution. I just wrote a paragraph explaining my dilemma, removed it, I guess I better just show some code (changed to protect the innocent and my company from killing me. it's from memory anyway): C++ code:
Volguus fucked around with this message at 04:32 on Mar 9, 2016 |
# ? Mar 9, 2016 04:30 |
|
Grocer Goodwill posted:Herb Sutter and Scott Meyers have completely corrupted the minds of an entire generation. I couldn't agree more - but I usually see it as a phase. Most of the better programmers I know has been through STL/boost/template phases, but come to their senses. Others seem to get stuck in that swamp forever and preach it every chance they get.
|
# ? Mar 9, 2016 15:23 |
|
Zerf posted:I couldn't agree more - but I usually see it as a phase. Most of the better programmers I know has been through STL/boost/template phases, but come to their senses. Others seem to get stuck in that swamp forever and preach it every chance they get. I haven't done much more than maintenance C++ stuff in a long time, and these ports are 99% C or simple C++ (or Pro-C, god I hate Oracle), so I've lost touch. What do you mean by STL/boost/template phases, exactly?
|
# ? Mar 10, 2016 00:30 |
|
Ciaphas posted:I haven't done much more than maintenance C++ stuff in a long time, and these ports are 99% C or simple C++ (or Pro-C, god I hate Oracle), so I've lost touch. What do you mean by STL/boost/template phases, exactly? He means people who chase whatever trend or whatever. They like STL, and then boost is the cool thing now so we'll add all that poo poo. Etc. etc.
|
# ? Mar 10, 2016 00:42 |
|
Oh, right, okay, I was looking too deeply into it and feeling vaguely worried
|
# ? Mar 10, 2016 00:44 |
|
Hi, I'm learning C, just by doing the exercises in the K&R book. Everything's been going pretty smoothly until I got to the example where I make a function that passes a character array. Long story short the point of this program is to just type words and then when you're done, it prints the longest, I've typed it word for word from the book twice, and I've really tried to strip it down to the fundamentals, but I'm just getting conflicting type errors:code:
code:
|
# ? Mar 18, 2016 12:54 |
|
What's the difference between a (char) and a (char *)?
|
# ? Mar 18, 2016 13:03 |
|
Jabor posted:What's the difference between a (char) and a (char *)? So as I understand it, if it's char *, it's just in memory aaaand immutable, I think. Whereas char[] is an array with characters as the elements. Oh, yeah, I fixed that. but my main issue is the second to last one: code:
bollig fucked around with this message at 13:08 on Mar 18, 2016 |
# ? Mar 18, 2016 13:06 |
|
There's already a function called getline in the c standard library and its declared in stdio.h
|
# ? Mar 18, 2016 13:10 |
|
astr0man posted:There's already a function called getline in the c standard library and its declared in stdio.h AHA! This is it. Thank you.
|
# ? Mar 18, 2016 13:33 |
|
So, to be clear, while K&R is a good book, it's also 28 year old. The built-in getline function was added to GNU libc as an extension and was later standardized in POSIX in the interim. If you want to follow the example in K&R, you'll have to call it "getline2" or something.
|
# ? Mar 18, 2016 16:53 |
|
bollig posted:So as I understand it, if it's char *, it's just in memory aaaand immutable, I think. Whereas char[] is an array with characters as the elements. char * is a pointer to a char, that's all, but is usually understood to be a pointer to an array of chars (such as a NULL-terminated string). When it comes to function arguments, char[] is basically the same thing, only you're being more explicit in your code about what the intent is: you want an array of chars. Either can be used to pass a char array, and in fact pretty much every C function that takes a string will take a char * or const char *. I forget what the exact term is, but passing an array in C results in it devolving into a pointer and the pointer being passed instead. Such as: C code:
Doc Block fucked around with this message at 18:06 on Mar 18, 2016 |
# ? Mar 18, 2016 18:03 |
|
bollig posted:AHA! This is it. Thank you. You've also got inconsistencies between the first declaration and then the definition, you have one taking a single character, and another taking an array.
|
# ? Mar 18, 2016 19:07 |
|
Doc Block posted:I forget what the exact term is, but passing an array in C results in it devolving into a pointer and the pointer being passed instead. decay
|
# ? Mar 19, 2016 03:34 |
|
Can anyone recommend a good source or book on more low-level stuff (doesn't strictly have to be C/C++ related but that is kinda the higher context I'm working with)? I do a lot of embedded stuff and I feel I could do with more information on low-level stuff such as linking (memory layout etc.), compilation process, compiler optimizations etc. I have a good understanding of using C/C++ and I have a good understanding of CPU architectures but what happens in between could be clearer to me.
|
# ? Mar 21, 2016 08:12 |
|
Hyvok posted:Can anyone recommend a good source or book on more low-level stuff (doesn't strictly have to be C/C++ related but that is kinda the higher context I'm working with)? I do a lot of embedded stuff and I feel I could do with more information on low-level stuff such as linking (memory layout etc.), compilation process, compiler optimizations etc. I have a good understanding of using C/C++ and I have a good understanding of CPU architectures but what happens in between could be clearer to me. The classic text here is the dragon book; it's been awhile since the second edition, but it's a pretty slow-moving field in the macro. I had a coworker who also recommended Linkers and Loaders, although I can't personally speak to it. We're not going to meaningfully replace reading a book, but if you have any questions while reading those, feel free to ask here.
|
# ? Mar 21, 2016 17:47 |
|
|
# ? May 19, 2024 07:05 |
|
On the other end of that is the Computer Systems: A Programmer's Perspective textbook. It assume you're familiar with C, and it doesn't actually go into compilers proper, but covers a pretty broad range of Unix systems stuff. Textbooks are shockingly expensive, but even the first edition that came out nearly 15 years ago (and the one I'm actually familiar with) is still relevant, especially at a high level, and I think there's a more recent second edition that's probably pretty cheap now.
|
# ? Mar 22, 2016 14:47 |