|
Flobbster posted:STL algorithms. Use 'em, motherfuckers Can't wait for C++0x lambda functions to make STL predicates so much less a pain in the rear end.
|
# ? Jan 17, 2009 14:12 |
|
|
# ? May 15, 2024 03:05 |
|
Otto Skorzeny posted:The best part of reinventing the wheel: you can make it a triangle!
|
# ? Jan 17, 2009 21:25 |
|
I wrote some C# code last week that made me laugh later: session.Close(); session.Dispose(); session = null; The next day, I see this article on Reddit: http://www.codinghorror.com/blog/archives/001211.html I brought it up to the other guy on the project, who assured me he did not submit the code in question. He then politely introduced me to the "using" statement.
|
# ? Jan 17, 2009 21:56 |
|
julyJones posted:I wrote some C# code last week that made me laugh later: There are some people that shouldn't write about programming. Jeff Atwood is one of them. Relying on the garbage collector to free resources other than memory (sockets, database connections, etc.) is pretty dumb because the behaviour of the GC is determined only by the state of the heap. If you run out of space in the active portion of the heap it will collect but if you depend on finalizers to clean up other resources you can easily run into problems where the resource is exhausted and the GC hasn't yet run. The GC doesn't care if you've hit your connection limit or whatever because it's just monitoring heap activity. If you're using unmanaged resources (sockets, files, database connections, etc.), dispose of them after use and don't let the GC clean up after you if you want consistent performance and behaviour.
|
# ? Jan 17, 2009 22:15 |
|
Flobbster posted:Smackbilly is correct, but at the same time erase is still guaranteed to return a valid iterator to the element after the one being erased, regardless of whether the container's semantics invalidate other iterators on erasure. Yeah, the main thing that was concerning me is that loops like that will work fine until someone comes along and changes the typedef of whatever the WidgetList actually is. The solution is, as you say, to use the algorithms (but that's not always easy when working with an existing codebase), or to ensure that you're setting the counter-iterator to the value from erase. It just got me thinking about some code I've written in the past and whether it's buggy in this way.
|
# ? Jan 17, 2009 22:20 |
|
ehnus posted:Relying on the garbage collector to free resources other than memory (sockets, database connections, etc.) is pretty dumb. . . That is my thinking as well, so I disagree with the article a bit. It was funny though to see code almost identical to mine appear on a WTF-type blog. I like to code defensively, so I'd honestly probably do the same thing again if I hadn't learned about "using". As I understand it, it's basically syntactic sugar for calling Dispose() in a finally block on whatever you're "using".
|
# ? Jan 17, 2009 22:48 |
|
julyJones posted:That is my thinking as well, so I disagree with the article a bit. It was funny though to see code almost identical to mine appear on a WTF-type blog. Yeah, that's exactly what using does, it's pretty handy.
|
# ? Jan 17, 2009 22:49 |
|
STL kind of delights and disappoints me at the same time because it has a lot of convenient libraries but the designers didn't seem to believe in the principal of least-surprise. There are so many caveats with iterators, for example, I find it easier with most types of data to just stick with vector and traverse using integers. Does that make me a hopeless knuckle-dragger?
|
# ? Jan 17, 2009 23:06 |
|
ehnus posted:Relying on the garbage collector to free resources other than memory (sockets, database connections, etc.) is pretty dumb... An ex-colleague of mine used to actually do this every time he used FileStreams, he never closed them, just let them drop out of scope, or nulled all references. His code was always peppered with GC.Collect.
|
# ? Jan 17, 2009 23:08 |
|
Explicitly nulling references is worthless 98% of the time, yet it seems to be a pretty popular M.O.
|
# ? Jan 18, 2009 02:49 |
|
Smackbilly posted:Can't wait for C++0x lambda functions to make STL predicates so much less a pain in the rear end. Oh, but there is already boost.phoenix to tempt you with the prospect of making STL predicates so very elegant and easy, only to drown you in an ocean of template errors if you actually try to use it
|
# ? Jan 18, 2009 02:50 |
|
julyJones posted:There are so many caveats with iterators, for example, I find it easier with most types of data to just stick with vector and traverse using integers. When you start using more complex container types you will be very very glad iterators exist. Also, C++0x is introducing the following foreach syntax code:
code:
|
# ? Jan 18, 2009 09:18 |
|
Otto Skorzeny posted:Here also note the use of 'auto' for compile-time type inference, which really comes into its own in situations like Also C++0x will finally make >> in a template context not be a right shift operator, thus eliminating the syntax error that the above code would have had in current C++. Thank god.
|
# ? Jan 18, 2009 14:14 |
|
julyJones posted:STL kind of delights and disappoints me at the same time because it has a lot of convenient libraries but the designers didn't seem to believe in the principal of least-surprise. quote:There are so many caveats with iterators, for example, I find it easier with most types of data to just stick with vector and traverse using integers. There is a flow chart floating around telling you which type of collection to use for different situations. It's wrong, it should read "use a vector". Every rule has exceptions of course, when you encounter one of these exceptions you will wish you used iterators.
|
# ? Jan 18, 2009 14:36 |
|
quote:What surprises you about it? As far as "least-surprise" goes, as an example, I don't think an iterator should be invalidated by a change in the state of the collection. When you're iterating over a vector and push_back() makes your iterator wild, instead of, say, throwing an exception, it comes as a surprise (unless you were patient and actually read the entire documentation, but who does that? ) I don't mean to presume it's wrong- it's just not something you'd expect, hence the "surprise". Please note my sarcasm detector is in the shop, but this second part sounds like bad advice. For example, sorting is not supported by vectors and inserting elements into a vector is an O(n) operation. You do need to know something about the implementations of each to use the right collection.
|
# ? Jan 18, 2009 21:48 |
|
Mustach posted:Explicitly nulling references is worthless 98% of the time, yet it seems to be a pretty popular M.O.
|
# ? Jan 18, 2009 22:59 |
|
julyJones posted:As far as "least-surprise" goes, as an example, I don't think an iterator should be invalidated by a change in the state of the collection. When you're iterating over a vector and push_back() makes your iterator wild, instead of, say, throwing an exception, it comes as a surprise (unless you were patient and actually read the entire documentation, but who does that? ) I don't mean to presume it's wrong- it's just not something you'd expect, hence the "surprise". The problem with this is, some of what you're asking would have a substantial negative effect on performance, when C++'s iterators are implemented with specifically that goal in mind. For instance, in your vector example, vector<T>::iterator (in most release builds) is nothing more than T*, so there isn't even a mechanism there to deal with exception handling if you dereference or increment an invalidated iterator. I can't really see where the "surprise" is in your use case. If you're doing something during an iteration that makes your iterator go invalid, you know you're doing it and that you will have to readjust in some way, so an exception adds complexity with zero benefit. Let's say you catch the exception, then what? You have either this: code:
code:
|
# ? Jan 19, 2009 00:05 |
|
Zombywuf posted:There is a flow chart floating around telling you which type of collection to use for different situations. It's wrong, it should read "use a vector". Every rule has exceptions of course, when you encounter one of these exceptions you will wish you used iterators. Vectors are gross.
|
# ? Jan 19, 2009 00:35 |
|
Flobbster posted:Smackbilly is correct, but at the same time erase is still guaranteed to return a valid iterator to the element after the one being erased, regardless of whether the container's semantics invalidate other iterators on erasure. I didn't know this off the top of my head but I just discovered that this is not actually true. The erase() method in associative containers (such as std::set and std::map) returns void. It neither invalidates all iterators nor returns an iterator. Only sequence containers return an iterator from erase(). On the one hand this is annoying because it is inconsistent, but on the other hand, advancing an iterator in an associative container may take non-constant time, and advancing the iterator is not necessarily required to perform the erasure, so I suppose this was done for efficiency reasons.
|
# ? Jan 19, 2009 03:26 |
|
I am re-writing parts of my companies Intranet site. And have come across this gem. All I can think of is that it was made using the query designer tools and then left as it worked.code:
I should do something about it, but i've just turned it into a Stored Procedure so I never have to look at it again. [edit]Haha it breaks the tables, typical.
|
# ? Jan 19, 2009 12:54 |
|
Iniluki posted:
By itself, that's not a "coding horror". In fact, it's necessary for lots of legitimate queries. Whether or not this particular query is terrible in other ways, I have no idea.
|
# ? Jan 19, 2009 13:26 |
|
Inherited an ASP.NET 1.0 application. All SQL is written directly in the ASPX.CS files like this:code:
Also thanks for the comment telling me you are going to write some SQL but no explanation what the point of the SQL is in relation to the application or display. It is pretty sweet when the app is 100+ ASPX pages large. I don't even know why it has that many files either its not the largest app. EDIT: This code is p.sweet just because I have now found it is included with the database open and closing, and error checking code on almost every ASPX page in the app, and just returns and a 2 column list of names in only 70 lines! da keebsta knicca fucked around with this message at 21:36 on Jan 19, 2009 |
# ? Jan 19, 2009 18:40 |
|
julyJones posted:As far as "least-surprise" goes, as an example, I don't think an iterator should be invalidated by a change in the state of the collection. When you're iterating over a vector and push_back() makes your iterator wild, instead of, say, throwing an exception, it comes as a surprise (unless you were patient and actually read the entire documentation, but who does that? ) I don't mean to presume it's wrong- it's just not something you'd expect, hence the "surprise". quote:Please note my sarcasm detector is in the shop, but this second part sounds like bad advice. For example, sorting is not supported by vectors and inserting elements into a vector is an O(n) operation. You do need to know something about the implementations of each to use the right collection. Sorting is supported by vectors, in fact it's probably the fastest way to sort unsorted data. I think you meant "doesn't store its data sorted", which is true. I find I rarely need this capability. Inserting new data in the middle of a collection is slow, but again I rarely need to do this. Basically, default to vector (unless you need a pair associative container) and only change to something else if you are really sure you need to. In any case, use iterators.
|
# ? Jan 19, 2009 23:02 |
|
Zombywuf posted:Sorting is supported by vectors, in fact it's probably the fastest way to sort unsorted data. I meant that vector::sort doesn't exist. You can use algorithm sort though, so I am wrong about not being able to sort.
|
# ? Jan 20, 2009 01:37 |
|
julyJones posted:I meant that vector::sort doesn't exist. You can use algorithm sort though, so I am wrong about not being able to sort. And it shouldn't. That violates the whole idea of generic programming. Honestly, I hope that with concepts, we can do away with list::sort, which really could be implemented as a free function (and probably should have).
|
# ? Jan 20, 2009 03:37 |
|
Avenging Dentist posted:And it shouldn't. That violates the whole idea of generic programming. Honestly, I hope that with concepts, we can do away with list::sort, which really could be implemented as a free function (and probably should have). I'd always assumed that the current STL used iterator categories to handle that. Bit odd that it doesn't.
|
# ? Jan 20, 2009 22:14 |
|
Everything on this page: http://www.xsharp.org/samples/
|
# ? Jan 21, 2009 23:05 |
|
Zombywuf posted:I'd always assumed that the current STL used iterator categories to handle that. Bit odd that it doesn't. It does, in the sense that std::sort expects a random-access iterator (which list iterators obviously do not satisfy).
|
# ? Jan 21, 2009 23:07 |
|
shrughes posted:Everything on this page: http://www.xsharp.org/samples/ Jesus Christ. I don't know what to say. The site's too detailed to be a joke. The most hilaroius thing is the tag-line "Code is poetry". Yes, and X# is Jabberwocky
|
# ? Jan 21, 2009 23:41 |
|
I can't believe it. I've been on this job three months, working with really intelligent guys like 25 years my senior, and today in my exploration of our code base,code:
|
# ? Jan 23, 2009 05:46 |
|
I inherited a small codebase from a professional software firm for my first real programming job and I noticed this today (I changed some identifiers):code:
|
# ? Jan 23, 2009 07:08 |
|
code:
TextMarkup entries live in their own table. __construct takes the $id and $type arguments, which act as a compound primary key in the table. __construct is also what is responsible for checking and writing to the cache. The object has a set of methods that convert text based on the selected markup type, such as BBCode, Wiki markup, HTML sanitization, etc. It needs a little cleaning up, but it's not bad. Oh, except it can't save itself. No, saving is done by the thing referencing the TextMarkup. By extracting the properties directly from the object and calling a static method to produce the original text. The external code then performs the SQL required to update the table, and conveniently does not clear the cached entry. But that isn't the horror. The horror is that this code has been in production for probably three or four years now, as-is. And somehow the bug (the fact that the cache is never updated) has been entirely invisible. In fact, I can't replicate it on the development environment at all, even though I'm the only one on the team that actually has the audacity to have memcache enabled in my environment. I ended up finding it when I bounced memcached on live, thinking to myself "na, this can't be it." Sigh. The only change needed to uncover this bug is that the live application is now looking at a different database server. I changed this in the one and only place it needed to be changed (in loving /etc/hosts). I don't understand how making this one change could possibly uncover a bug that has existed since the beginning of time when there is no common code involved at all. I hate this codebase. McGlockenshire fucked around with this message at 02:07 on Jan 24, 2009 |
# ? Jan 24, 2009 02:04 |
|
I remember seeing this in my first month on the job.code:
|
# ? Jan 24, 2009 07:39 |
|
ColdPie posted:I remember seeing this in my first month on the job. I got something almost exactly like this (except in C, not Java) in code written by someone senior to me a few months ago. It was doubly odd because aside from that the code was very good and WTF-free.
|
# ? Jan 24, 2009 15:09 |
|
I suppose my thread here: http://forums.somethingawful.com/showthread.php?threadid=3061838 Deserves an honorable mention. To get around the strict typing of C# and to have flexible functions I have to basically work in lowest common denominator (func<object,object> & object) to implement the basics of church numerals. Here is a sample of some of the "pretty code" code:
|
# ? Jan 24, 2009 18:02 |
|
weaaddar posted:I suppose my thread here: http://forums.somethingawful.com/showthread.php?threadid=3061838 I did something similar in Javascript and it was only slightly more readable. Ugh. Square peg meet round hole. A line from OsCommerce that I feel really exemplifies the entire project: code:
|
# ? Jan 24, 2009 19:24 |
|
code:
|
# ? Jan 24, 2009 23:43 |
|
I mentioned this in IRC as it was playing out, but I'm sitting in a Computer Science majors computer lab, and there are three guys sitting next to me working on a Perl assignment. I know for a fact they're not freshmen or sophomores but even if they were, ugh. So, they have to take input into their program and want to validate and make sure the user enters in a number (as opposed to something else.) Their solution? Store the input in a temp variable. Multiply the temp variable by 1. Make sure the temp variable is the same as the input. Also this quote "You could also use a regular expression but that'd be a pain in the rear end." Ugh.
|
# ? Jan 26, 2009 20:07 |
|
Degrees don't mean poo poo! I wonder what their thought process was that using regexp validation, which is infinitely more robust, was somehow worth less than "multiplying something by one"? Geniuses at work, people.
|
# ? Jan 26, 2009 20:34 |
|
|
# ? May 15, 2024 03:05 |
|
but think of it this way: if(args[0]*1 == args[0]) [stuff to do on good input] else [stuff to do on bad input] Is certainly a lot easier to write then a Regex to validate against numbers, because the 2 seconds of brain power required or the the Google search is inconceivable. Plus the whole unreadability of the code is got to be worth points, after all your coding in perl, if its not an exercise to figure out what your doing, it's wrong.
|
# ? Jan 26, 2009 20:43 |