--- Log opened Sat Mar 01 00:00:40 2008 |
00:00 | | You're now known as TheWatcher[T-2] |
00:02 | | You're now known as TheWatcher[zZzZ] |
01:05 | | Thaqui [~Thaqui@222.154.187.ns-2601] has joined #code |
01:05 | | mode/#code [+o Thaqui] by ChanServ |
01:06 | | * AnnoDomini ponders. According to his guesstimate, there should be a script or application for checking whether a given URL has updated since last checked. But fails to find it, probably due to lack of the correct question. |
01:12 | <@AnnoDomini> | Shouldn't be difficult to code. Store a local copy. Download current version. Compare, prompt accordingly. |
01:26 | <@McMartin> | Argh |
01:27 | | * McMartin does the Ugly Java Dance To Work Around The Fact That It Is Not C#. |
01:28 | <@McMartin> | http://rafb.net/p/WfefnZ66.html |
01:29 | <@McMartin> | Well, that link looks like it went through here, despite Chanserv bitching. |
01:29 | | mode/#code [+oooooo Attilla C_tiger EvilDarkLord GeekSoldier|bed gnolam Goddess] by Vornicus |
01:29 | | mode/#code [+oooooo McMartin MyCatVerbs Reiv Serah TheWatcher[zZzZ] ToxicFrog] by Vornicus |
01:30 | | mode/#code [+o Vornicus] by Vornicus |
01:30 | <@Vornicus> | It didn't. |
01:30 | <@McMartin> | http://rafb.net/p/WfefnZ66.html |
01:30 | <@Vornicus> | You may see it, but that's because your sent messages are maintained by your client, you don't get confirmation for them. |
01:30 | <@McMartin> | Aha. |
01:30 | <@Vornicus> | (most other things are confirmed) |
01:44 | | * McMartin dances |
01:44 | <@McMartin> | Blorple's browsing capabilities are now perfected |
01:45 | <@McMartin> | Now I just need to add stuff like copyright notices and stuff. |
01:48 | <@ToxicFrog> | It came through here, though. |
01:48 | <@ToxicFrog> | So, we have a desync |
01:48 | | mode/#code [-o+o McMartin McMartin] by ToxicFrog |
01:48 | <@ToxicFrog> | AnnoDomini: it's called wget. |
01:48 | <@ToxicFrog> | Curl also has this capability. |
01:49 | <@ToxicFrog> | With various degrees of coarsness and meaning of what exactly "updated" means. |
01:49 | <@ToxicFrog> | Add in external programs like md5sum, diff or grep for more power; simmer for 10 minutes. Serve hot. |
01:52 | <@AnnoDomini> | wget is some kind of command line program thingie, aye? |
01:52 | <@ToxicFrog> | Yes. |
01:52 | <@ToxicFrog> | As is curl. |
01:53 | <@ToxicFrog> | Anyways, the short form is: wget -N <url> |
01:53 | <@ToxicFrog> | Which will download <url> only if the server timestamps say that it's updated more recently than your local copy. |
01:54 | <@ToxicFrog> | (and will overwrite the old version, if so) |
01:56 | <@McMartin> | Prerelease version of Blorple! http://www.stanford.edu/~mcmartin/if/blorple.jar |
01:56 | <@McMartin> | (Should open with double-click) |
01:56 | <@McMartin> | (Does not play nice with Macs) |
01:58 | <@ToxicFrog> | Ok, so |
01:58 | <@ToxicFrog> | The choose-location-to-scan thing is not entirely intuitive |
01:59 | <@ToxicFrog> | In particular, there appears to be no way to enter a directory to cd to without choosing that as the one to scan |
01:59 | <@ToxicFrog> | (and once it decides it's scanning your 60+GB home directory - over ssh - there is no way to stop it that I can determine short of ^C) |
02:00 | <@ToxicFrog> | Also, if you give it a directory that doesn't exist, it closes without complaint and simply adds nothing to the list. |
02:00 | <@McMartin> | Mmm. OK, need SwingWorkers to scan in background. |
02:01 | <@McMartin> | Also, once you do the scan once, you never have to again. |
02:02 | <@McMartin> | (It keeps the results in its app directory) |
02:02 | | * ToxicFrog nods |
02:02 | <@ToxicFrog> | What I wanted to do was look at /mnt/orias/home/ben, because I couldn't remember exactly where I kept my blorbs. |
02:02 | <@ToxicFrog> | It ended up trying to scan it. |
02:02 | <@McMartin> | Hrm. |
02:02 | <@ToxicFrog> | Apparently, the text box at the bottom is "scan now" when you hit enter, and the one at the top showing your current location lets you cd .. but not actually enter paths. |
02:03 | <@McMartin> | Hm. |
02:03 | <@McMartin> | I think the issue here is that directory choosers suck. |
02:03 | <@McMartin> | Perhaps I should make it a general file chooser and let it select directories? |
02:04 | <@ToxicFrog> | Hmm. Is it using the system directory chooser, or a java builtin one? |
02:05 | | AnnoDomini [AnnoDomini@83.21.47.ns-4083] has quit [Quit: Death is always at your back, for all return to the earth from which they came, the fire of life is at the births to come, the tears of a mourning woman are at your left, and the wind blows forth from your right.] |
02:05 | <@ToxicFrog> | Because if the former, it could well be "the GNOME directory chooser sucks", which I can easily believe. |
02:05 | <@McMartin> | It's using a Java builtin one that in theory is supposed to basically match the system one. |
02:05 | <@McMartin> | It's certainly the case that when I run this on OS X it looks a lot different than when I run it on Windows. |
02:05 | <@ToxicFrog> | Fundamentally, the issue appears to be that the dropdown at the top is not a combobox~ |
02:06 | <@McMartin> | Heh |
02:06 | <@McMartin> | Yeah, I'll see if I can make the default file chooser do what we want. |
02:33 | | Goddess [Jennet@Nightstar-20631.216-254-250.iw.net] has quit [Quit: ] |
02:33 | | Raif [~corvusign@67.161.90.ns-4200] has joined #Code |
03:00 | | GeekSoldier|bed [~Rob@91.18.99.ns-4994] has quit [Ping Timeout] |
03:06 | | gnolam [lenin@Nightstar-10613.8.5.253.static.se.wasadata.net] has quit [Quit: Z?] |
03:16 | | Vornicus is now known as Finerty |
05:45 | | GeekSoldier|bed [~Rob@91.18.105.ns-12576] has joined #code |
05:47 | | GeekSoldier|bed is now known as GeekSoldier |
07:01 | | Finerty is now known as Vornicus |
07:09 | | Vornicus is now known as Vornicus-Latens |
07:39 | | You're now known as TheWatcher |
08:37 | | Chalcedon [~Chalcedon@Nightstar-10679.ue.woosh.co.nz] has quit [Connection reset by peer] |
09:17 | | AnnoDomini [AnnoDomini@83.21.47.ns-4083] has joined #Code |
09:17 | | mode/#code [+o AnnoDomini] by ChanServ |
09:27 | | You're now known as TheWatcher[afk] |
10:15 | | * GeekSoldier has to learn jython... |
10:15 | | * GeekSoldier is reading about it. |
10:15 | | * GeekSoldier is failing to see its utility. |
10:17 | <@jerith> | It's a way to get management to let you run Python? |
10:17 | < GeekSoldier> | hmm. fair enough. |
10:17 | <@jerith> | Its utility is mostly in integration with existing Java code. |
10:17 | < GeekSoldier> | it looks to me to be Python, wrapped in Java. |
10:19 | <@jerith> | It's a Python runtime written for the JVM. |
10:21 | < GeekSoldier> | Perhaps my thing is this: why does it merit a chapter in this course, then? Python is a prereq, and we are supposed to be learning Java now... |
10:27 | <@jerith> | Dunno. Last I heard it wasn't particularly usable. |
10:29 | < GeekSoldier> | essentially, they want us to make sure that it is running in Eclipse, then re-implement something we did in the last class. |
10:29 | < GeekSoldier> | oh well. |
10:30 | | * jerith shrugs. |
10:30 | <@jerith> | That seems silly. |
11:13 | | Reiv is now known as Reiver |
11:25 | | Thaqui [~Thaqui@222.154.187.ns-2601] has left #code [Leaving] |
11:42 | | You're now known as TheWatcher |
12:11 | | GeekSoldier [~Rob@91.18.105.ns-12576] has quit [Ping Timeout] |
12:14 | | GeekSoldier [~Rob@91.18.78.ns-3991] has joined #code |
13:02 | | Vornicus-Latens [~vorn@ServicesOp.Nightstar.Net] has quit [Ping Timeout] |
13:05 | | AnnoDomini [AnnoDomini@83.21.47.ns-4083] has quit [Ping Timeout] |
13:12 | | AnnoDomini [AnnoDomini@83.21.28.ns-3498] has joined #Code |
13:12 | | mode/#code [+o AnnoDomini] by ChanServ |
14:29 | | gnolam [lenin@Nightstar-10613.8.5.253.static.se.wasadata.net] has joined #Code |
14:29 | | mode/#code [+o gnolam] by ChanServ |
15:11 | <@ToxicFrog> | The utility is "hey, I have this huge Java program, I want to integrate some form of high-level scripting language into it for easy configuration/modding/whatever" |
15:12 | < GeekSoldier> | ah, I didn't see that. |
15:14 | <@ToxicFrog> | At which point you turn to either Jython or one of the six Lua/Java implementations depending on whether Python or Lua is a better fit for your project. |
15:15 | < GeekSoldier> | I can't really see myself ever saying "Hey I have this huge Java program," though. |
15:17 | <@ToxicFrog> | Even if you don't plan on writing one, you could always get hired to work on one. |
15:17 | < GeekSoldier> | true. |
15:51 | | Vornotron [~vorn@Admin.Nightstar.Net] has joined #code |
16:12 | | Vornotron is now known as Vornicus |
16:13 | | Vornicus is now known as NSGuest-5329 |
16:15 | | Xiphias [~Ameroth@Nightstar-12871.wlms-broadband.com] has joined #code |
16:15 | | NSGuest-5329 is now known as Vornicus |
16:25 | <@Attilla> | Gah, can't remember. But what's the Home IP? |
16:27 | < Xiphias> | 127.0.0.1? |
16:29 | <@Attilla> | Thanks |
16:31 | <@ToxicFrog> | The technical term is localhost |
16:32 | <@Attilla> | I had gathered that by now. |
16:45 | <@Serah> | Let's see if I remember this correctly. 0.* is a routing IP supposed to be nothing. 1.* is the router, 255.* is broadcast. Broadcast can be used on any subsocket. |
16:45 | <@Serah> | 255.255.255.255 is broadcast to everyone. |
16:46 | <@Serah> | Usually restricted to the people on your immidiate LAN. |
16:53 | <@ToxicFrog> | 0.* is not permitted. |
16:53 | <@ToxicFrog> | *.0.0.* is, however. |
16:53 | <@ToxicFrog> | 127.* is localhost, traditionally 127.0.0.1. |
16:54 | <@ToxicFrog> | There's no address reserved for routers, although traditionally it's *.1. |
16:56 | <@ToxicFrog> | *.255... is local broadcast; eg, 192.168.255.255 hits everything on 192.168.*.* |
16:57 | <@ToxicFrog> | 254.* and 255.* are reserved for IP multicast. |
16:57 | <@ToxicFrog> | And 255.255.255.255 is the entire-LAN broadcast address. |
17:13 | | You're now known as TheWatcher[afk] |
17:30 | < Xiphias> | Why does java start numbering months at zero? |
17:32 | < GeekSoldier> | Java counts everything starting at 0. |
18:06 | | wppjdp [sqluqms@89.190.199.ns-13536] has joined #Code |
18:06 | | wppjdp [sqluqms@89.190.199.ns-13536] has left #Code [] |
18:16 | | Xiphias [~Ameroth@Nightstar-12871.wlms-broadband.com] has quit [Quit: I was never gone] |
18:48 | | You're now known as TheWatcher |
19:30 | <@AnnoDomini> | Hrm. Is it possible to make a function return a string (as in the container string)? |
19:30 | | Seratonin [~servoserv@88.234.51.ns-12651] has joined #code |
19:34 | | Seratonin [~servoserv@88.234.51.ns-12651] has quit [Quit: ] |
19:35 | <@AnnoDomini> | Nevermind. |
19:35 | <@AnnoDomini> | I think I figured it out. |
19:37 | <@AnnoDomini> | Excellent. My line reading function seems to work, albeit has a bug leading to the application crashing. |
19:38 | <@Attilla> | Either that was just a nick, or my seratonin appears to be of Turkish origin. |
20:21 | <@AnnoDomini> | http://pastie.caboo.se/159852 <- Anyone know why it terminates abnormally when I try to read a line beyond the file's line length? |
20:22 | <@McMartin> | Where is getline defined? |
20:23 | <@C_tiger> | I'd assume getline isn't returning false when it hits EOF. |
20:23 | <@McMartin> | But is instead dying horribly |
20:23 | <@AnnoDomini> | http://www.cplusplus.com/reference/string/getline.html <- It's this getline. |
20:23 | | You're now known as TheWatcher[afk] |
20:24 | <@AnnoDomini> | I tried putting the loop inside a try, catching an fstream::failure but that didn't make the problem go away. |
20:24 | <@McMartin> | Yeah, your test is wrong |
20:24 | <@McMartin> | You want to check the stream's eofbit. |
20:24 | <@McMartin> | The exception will only be thrown if you've set the stream to do so. |
20:25 | <@McMartin> | The return value here is always going to be file_stream |
20:25 | <@AnnoDomini> | Okay... |
20:26 | <@AnnoDomini> | But I still don't understand what I should be doing. |
20:26 | <@McMartin> | Well, first, do you realize why it's wrong? |
20:27 | <@AnnoDomini> | The return value isn't true/false. |
20:27 | <@McMartin> | That's not a problem in C. |
20:27 | <@McMartin> | Or C++. |
20:28 | <@AnnoDomini> | It doesn't give a 0 when the file ends? |
20:28 | <@McMartin> | As if the return value is a pointer, it's false if NULL and true otherwise. |
20:28 | <@McMartin> | Right. |
20:28 | <@McMartin> | And your intent is to loop until the file is done. |
20:28 | <@AnnoDomini> | !file_stream.eof() <- I tried putting this in the while condition, but it didn't work. |
20:29 | <@McMartin> | Hmm |
20:29 | <@McMartin> | OK, this isn't related to the loop, but |
20:29 | <@McMartin> | Maybe you should also check file_stream.fail() and faile_stream.bad() before reading? |
20:30 | <@McMartin> | My first shot at the loop, however, would be: |
20:30 | <@McMartin> | while {!file_stream.eof) { getline (/* as per current loop condition */); /* rest of loop */ } |
20:31 | <@AnnoDomini> | file_handling.cpp:17: error: could not convert `file_stream.std::basic_ios<_Char |
20:31 | <@AnnoDomini> | T, _Traits>::eof [with _CharT = char, _Traits = std::char_traits<char>]' to `boo |
20:31 | <@AnnoDomini> | l' |
20:32 | <@McMartin> | Er |
20:32 | <@McMartin> | .eof(). |
20:32 | <@AnnoDomini> | Still crashes. |
20:32 | <@McMartin> | Where? |
20:32 | <@AnnoDomini> | (Compiles, but crashes.) |
20:32 | <@McMartin> | Yes, but where? |
20:32 | <@McMartin> | Do you even know if it's crashing in this function? |
20:33 | <@AnnoDomini> | If I set the program only to read the lines that really are in the file, the program runs correctly. |
20:33 | <@McMartin> | That wasn't my question. |
20:34 | <@McMartin> | What OS are you developing on? |
20:34 | <@AnnoDomini> | WinXP. |
20:34 | <@McMartin> | And what development environment are you using? |
20:35 | <@AnnoDomini> | A text editor and a batch file. The latest MinGW compiler, I believe. |
20:35 | <@McMartin> | OK. |
20:35 | <@McMartin> | Does this mean you have gdb? |
20:35 | <@McMartin> | Run it in a debugger to find out exactly what line it's crashing on. |
20:36 | <@McMartin> | If you don't have a debugger, or it's somehow failing without noticing the debugger (Bad C++! Another sin to add to your heavy load thereof already!), put a cout << "Status message of some kind" << endl; after every line on your own. |
20:36 | <@McMartin> | But you should really have a debugger. |
20:36 | <@AnnoDomini> | 'gdb' seems absent from the MinGW directory. |
20:37 | <@McMartin> | Bad Times. |
20:37 | <@McMartin> | I suggest either going full cygwin for development, developing using MS tools, or developing on a different OS |
20:37 | <@McMartin> | Any of those are a good long term solution. |
20:37 | <@McMartin> | In the meantime, cout. |
20:39 | <@McMartin> | A good inflection poitn would be line 18. |
20:39 | <@McMartin> | Since if the crash is happening outside of the loop, then obsessing over eof() is not the problem. =P |
20:42 | <@ToxicFrog> | Full cygwin or MSYS. |
20:42 | <@ToxicFrog> | mingw is pretty bare-bones and is really meant to be invoked either from MSYS or from an IDE. |
20:43 | <@ToxicFrog> | That said, it should include gdb, since some of the IDEs that use it use that as the debugging backend. |
20:45 | <@McMartin> | Aha OK. |
20:45 | <@AnnoDomini> | WTF? couting seems to indicate that it crashes on "return output;". |
20:45 | <@McMartin> | ... yes, yes it is. |
20:45 | | * McMartin headdesks at not noticing that immediately. |
20:46 | <@McMartin> | Welcome to another lesson in Why C++ Sucks |
20:46 | | * AnnoDomini takes a seat by the window. |
20:46 | <@McMartin> | Also, full bonus points to g++ for not throwing a warning about it. |
20:46 | <@AnnoDomini> | No warnings. |
20:46 | <@McMartin> | Go up with me to line 3. |
20:47 | <@McMartin> | string output=""; |
20:47 | <@McMartin> | That constructs output. |
20:47 | <@AnnoDomini> | Okay. |
20:47 | <@McMartin> | Now go down to me to lines 15 or 21. |
20:47 | <@McMartin> | return output; |
20:47 | <@McMartin> | That destroys output, and then returns a bit-copy of the deallocated memory. |
20:48 | <@AnnoDomini> | One would think that would return an empty string. |
20:48 | <@McMartin> | Because output, as a local variable, is automatically destroyed when you leave its scope. |
20:48 | <@McMartin> | The memory it refers to will be overwritten upon the next procedure call, so basically Any Kind Of Random Shit Can Happen |
20:49 | <@McMartin> | And not only is this easily detectable -- far more so than C's equivalent error (returning a pointer to a stack-allocated variable) -- the compiler doesn't tell you about it. |
20:49 | <@McMartin> | Go team C++! |
20:50 | | GeekSoldier is now known as GeekSoldier|bed |
20:50 | <@McMartin> | In Java, this can't happen because everything that's not an int or float or something can only be created with new(). |
20:50 | <@McMartin> | Anyway. |
20:50 | <@McMartin> | There are two ways to get around this. |
20:50 | <@AnnoDomini> | Waitwait, I still don't get it. |
20:50 | <@McMartin> | OK, have you done any C? |
20:50 | <@McMartin> | It's easier to demonstrate in C. |
20:50 | <@AnnoDomini> | Not really. |
20:50 | <@McMartin> | OK, have you done any work with pointers in C++? |
20:51 | <@AnnoDomini> | I try to avoid them like the plague. Not really, yet. |
20:51 | <@McMartin> | OK. |
20:51 | <@McMartin> | Have you learned about "the stack", at least as differentiated from "the heap"? |
20:52 | < Vornicus> | Stack Collision With A Heap! |
20:52 | <@AnnoDomini> | I know how stacks work, from various assembler languages I've been forced to learn via Uni. |
20:52 | <@McMartin> | OK, great. |
20:52 | <@McMartin> | That will make it easier to explain what's going on. |
20:52 | <@McMartin> | Let's say main's calling readline. |
20:53 | <@McMartin> | The stack looks like this. |
20:53 | <@McMartin> | |main's stack|readline's stack| |
20:53 | <@McMartin> | Right? |
20:53 | <@McMartin> | And past readline's stack there be dragons. |
20:53 | <@McMartin> | Er, past its stack space. |
20:53 | <@McMartin> | output lives in readline's stack space. |
20:53 | <@AnnoDomini> | The stack pointer doesn't wrap around? |
20:53 | <@McMartin> | No, it just runs off into random memory. |
20:54 | <@McMartin> | Or, it hits the edge of protected memory and crashes. |
20:54 | <@McMartin> | After readline returns, the stack looks like this: |
20:54 | <@McMartin> | |main's stack space| |
20:54 | <@McMartin> | And then dragons. |
20:54 | <@McMartin> | Note that that's where output is at this point. |
20:54 | <@McMartin> | main then copies the value of output over to its own space, from the dragons. |
20:54 | <@McMartin> | It might work, if nothing else has happened to the stack since then. |
20:55 | <@McMartin> | Or it might crash with a segfault because the OS decided to reprotect that memory. |
20:55 | <@AnnoDomini> | Oh. Okay. |
20:55 | <@AnnoDomini> | But what could reprotect that memory? |
20:56 | <@McMartin> | The OS itself is allowed to intervene at any point with resources its programs don't care about anymore. |
20:56 | <@McMartin> | And at function return, your application officially doesn't care about that functions local variables anymore. |
20:57 | <@McMartin> | There's an additional wrinkle here having to do with constructors and destructors, but it shouldn't be an issue here. The main issue is Never Return Local Objects Or Pointers To Local Variables. |
20:58 | <@AnnoDomini> | I don't follow. How do getters work, then? |
20:58 | <@AnnoDomini> | These return local variables, right? |
20:58 | <@McMartin> | local objects. |
20:58 | <@McMartin> | primitives aren't objects. |
20:59 | <@McMartin> | So a getter that returns an int, or a double, or whatever, that's fine. |
20:59 | <@ToxicFrog> | Also, private members are not the same as local anything. |
20:59 | <@McMartin> | Pointers are also primitives. |
20:59 | <@McMartin> | Also that. |
20:59 | <@AnnoDomini> | Okay... so I shouldn't be returning a string. |
20:59 | <@McMartin> | Right. |
20:59 | <@AnnoDomini> | Or a pointer to string. |
20:59 | <@McMartin> | Returning a pointer to a string is acceptable *if* the target is not a stack variable. |
20:59 | <@McMartin> | string *x = new string("zOMGHAX!"); return x; |
20:59 | <@McMartin> | is fine. |
21:00 | <@McMartin> | string x = "zOMGHAX!"; string *y = &x; return y; is doom. |
21:00 | <@AnnoDomini> | The first won't be destroyed when you leave and the second will be, right? |
21:00 | <@McMartin> | That's right. |
21:00 | <@McMartin> | The first won't be destroyed until someone calls delete() on a pointer to it. |
21:01 | <@McMartin> | But you haven't really gotten into pointers yet, so let's move on to the other way of fixing this routine, which is better anyway. |
21:01 | <@McMartin> | And that's to copy what getline() itself is doing. |
21:01 | <@McMartin> | In short, take in a reference to a string (a string&) as one of our arguments, and reassign that argument to our result. |
21:03 | <@McMartin> | Essentially, if we remove line to, change line 1 to "void readline(string path, int line, string& output)", change the "return output"s to "return"s, it should be golden. |
21:03 | <@McMartin> | It may be necessary to modify line 20, depending on what string's operator=() looks like, but it ought to be sensible there. |
21:03 | <@AnnoDomini> | How does that work, anyway? In the case of getline's syntax, we seem to be putting an object in a spot for the address of an object... I think. |
21:04 | <@McMartin> | Yeah. |
21:04 | <@McMartin> | That's what the & does |
21:04 | <@McMartin> | It essentially looks like an actual object but is secretly a pointer to it. |
21:04 | <@McMartin> | C++ is all about making it extremely difficult to determine from the local syntax exactly what is going on. |
21:04 | <@McMartin> | The only way to distinguish between a reference call and a copy-constructor call is by looking at the relevant .h file. =P |
21:05 | <@McMartin> | Or, in this case, the reference. |
21:05 | <@McMartin> | istream& getline ( istream& is, string& str ); |
21:05 | <@McMartin> | The "&" means "this is actually an address, but it's not a modifiable one so most of the pointer jackassery cannot be done to it." |
21:05 | <@McMartin> | "That said, changes you make to this object will be reflected in the caller's copy, so beware or rejoice as appropriate." |
21:07 | <@AnnoDomini> | Hm. Right, so I change the first line to what you said, and remove the parameter from the returns. |
21:07 | <@AnnoDomini> | But is that all I need to do? |
21:07 | <@McMartin> | Also don't have a local variable by the same name. |
21:07 | <@McMartin> | But that should be all you need to do, unless I missed something, which is plausible. |
21:07 | <@McMartin> | It's Another Bug Down, though. |
21:08 | <@McMartin> | I think. |
21:09 | <@McMartin> | Frankly, since you weren't explicitly working with references, the return "should have" worked, via copy constructors. |
21:10 | <@McMartin> | So I would not be at all surprised if Something Else Were Breaking. |
21:10 | | * McMartin also isn't entirely clear on whether or not getline actually replaces its contents or just appends to it, from the description. |
21:10 | <@McMartin> | Also also, and this is kind of an aside at this point |
21:11 | <@McMartin> | This routine is for practice/for a class, right? You don't intend on actually using it in production code, do you? |
21:11 | <@AnnoDomini> | Hm. I get the same error message. I'll try to debug using cout again. |
21:11 | <@McMartin> | Don't forget to put cout writes in the caller, too. |
21:11 | <@AnnoDomini> | Uh, yeah. I'm just fiddling around. |
21:11 | <@McMartin> | OK, good. |
21:12 | <@McMartin> | Because having a "get the nth line of a file" routine is just inviting someone to do a loop calling it with ever increasing "i" |
21:12 | <@AnnoDomini> | (It seems like a waste of processing power to find the appropriate line like that.) |
21:12 | <@McMartin> | Yes. |
21:12 | <@McMartin> | Well |
21:12 | <@McMartin> | Waste of disk time, really. |
21:12 | <@McMartin> | But you can just see someone doing a succession of calls to it with ever-increasing line numbers |
21:13 | | * AnnoDomini nods. |
21:13 | <@AnnoDomini> | I saw myself doing something like that. |
21:13 | <@AnnoDomini> | In fact, that's what I'm doing in main();. |
21:13 | <@McMartin> | Well, right, but that's to test it. |
21:13 | <@McMartin> | Doing it in production brings us to http://s262.photobucket.com/albums/ii94/TheWalkingDude/?action=view¤t=2.jp g |
21:14 | <@McMartin> | Being inefficient about things in test is fine. |
21:14 | <@McMartin> | Tests are *supposed* to be perverse, anyway |
21:15 | <@AnnoDomini> | I'm just learning C++ here. Frankly, I don't know how to do it any other way. |
21:15 | <@McMartin> | tests should also, for instance, try negative line numbers. |
21:15 | <@McMartin> | Yeah, this isn't a criticism. |
21:15 | <@McMartin> | I had this horrible vision of this being used as a component for a seriously intended application, though. |
21:16 | <@McMartin> | Actually, that's a good followup problem. |
21:16 | <@McMartin> | "Design a version of this that would actually be sensible for a time-constrained but not necessarily space-constrained application." |
21:17 | <@McMartin> | If you're space-constrained there's really nothing for it but something *like* this - the only real optimization left is to take the istream as an argument too, getline style. |
21:18 | <@McMartin> | But by all means, make this one work first. |
21:18 | <@McMartin> | (I'm also not entirely sure the followup problem can be done without parts of the library you haven't studied yet -- but I don't know how much you've studied) |
21:20 | <@AnnoDomini> | It still crashes on return. |
21:21 | <@McMartin> | Hmm. |
21:21 | <@McMartin> | Can you also paste your main()? |
21:21 | | * McMartin will try to duplicate it on a machine with gdb installed. |
21:24 | <@AnnoDomini> | Okay, gimme a moment. |
21:25 | <@AnnoDomini> | http://pastie.caboo.se/159869 <- I suppose you'll want color.cpp/.h and file_handling.cpp/.h? |
21:25 | <@McMartin> | It will probably be important. |
21:25 | <@McMartin> | That said |
21:26 | <@McMartin> | The code, even with "return output", works fine on my Linux box. |
21:26 | <@McMartin> | Even with overlarge values, it returns "EOF" with no problem. |
21:27 | | * AnnoDomini WTFs. |
21:28 | <@McMartin> | This main() is larger than I expected |
21:28 | <@McMartin> | OK, next lesson: unit testing |
21:28 | <@AnnoDomini> | http://pastie.caboo.se/159871 http://pastie.caboo.se/159872 http://pastie.caboo.se/159874 http://pastie.caboo.se/159873 |
21:31 | <@AnnoDomini> | (The color files aren't mind, if you're wondering. I've copied them from a forum somewhere, where someone who knew how to use curses was feeling helpful.) |
21:31 | <@AnnoDomini> | *mine |
21:31 | <@McMartin> | Nod |
21:33 | <@McMartin> | ..... |
21:33 | <@McMartin> | ... oh, wait, I see. |
21:34 | <@McMartin> | OK |
21:34 | <@McMartin> | See if this program works for you: |
21:34 | <@McMartin> | http://pastie.caboo.se/159878 |
21:34 | <@McMartin> | This was more of what I was expecting from your main(). |
21:35 | <@McMartin> | (You'll note that I'm using an 'older version' of readline here.) |
21:39 | <@AnnoDomini> | This one works. |
21:40 | <@McMartin> | Your program produced this output and waited for a key: |
21:40 | <@McMartin> | 1 |
21:40 | <@McMartin> | before 2 |
21:40 | <@McMartin> | 2 |
21:40 | <@McMartin> | before 3 |
21:40 | <@McMartin> | 3 |
21:40 | <@McMartin> | before 4 |
21:41 | <@McMartin> | 4 |
21:41 | <@McMartin> | before 5 |
21:41 | <@McMartin> | 5 |
21:41 | <@AnnoDomini> | I think those are my debugging couts. |
21:41 | <@McMartin> | Likely |
21:42 | <@McMartin> | Though when I remove file.txt, I instead just get " opening file!" five times. |
21:42 | | * AnnoDomini has absolutely no idea why that happens. |
21:42 | <@McMartin> | Aha! Got it to crash. |
21:43 | <@McMartin> | And it's an uncaught exception |
21:43 | <@McMartin> | And my runtime is clearly better than MinGW's, because it said which one it was. |
21:43 | <@AnnoDomini> | All mine says is: |
21:43 | <@AnnoDomini> | This application has requested the Runtime to terminate it in an unusual way. |
21:43 | <@AnnoDomini> | Please contact the application's support team for more information. |
21:43 | <@McMartin> | Awesome. |
21:43 | <@AnnoDomini> | Quite unhelpful. |
21:43 | <@McMartin> | I'll quote mine once I get gdb running, because you're seriously going to kick yourself for this one. |
21:44 | <@McMartin> | And I'd rather be able to say "do this in mysterious cases" and be able to make it stick. |
21:45 | <@McMartin> | Oops. I suppose it would help if I compiled in debug symbols. |
21:45 | <@McMartin> | Right. |
21:46 | <@McMartin> | After the crash, I typed in "bt" at gdb and got a bunch of stuff, ending with this: |
21:46 | <@McMartin> | http://pastie.caboo.se/159884 |
21:47 | <@McMartin> | Also, I must now modify my earlier statement. |
21:47 | <@AnnoDomini> | std::out_of_range? |
21:47 | <@McMartin> | It is, in fact, OK to return a local Object if that object has a copy constructor (which string does). It will make a copy in the caller's stack frame. |
21:47 | <@McMartin> | It is still not OK to return a pointer or reference to one of your own local variables. |
21:47 | <@McMartin> | Look at line 38. |
21:48 | <@McMartin> | (from line 21 of my paste there) |
21:48 | <@McMartin> | n is, at that point, 4. |
21:48 | <@McMartin> | So, you're calling substr(5, 2048) on the result of readline. |
21:49 | <@McMartin> | The string you return at the end of file is "EOF", which is only three characters long. |
21:49 | | * AnnoDomini nods. |
21:49 | <@AnnoDomini> | Aha. |
21:49 | <@McMartin> | substring thus attempts to build a substring starting past the end of the string, and complains righteously. |
21:50 | <@McMartin> | Now, the "printing out which exception was uncaught" part was actually my system's runtime. |
21:52 | <@McMartin> | That said, your writing stuff isn't working either - file2.txt is never created on my system. |
21:52 | <@McMartin> | Anyway. |
21:52 | <@McMartin> | In gdb, when your program crashes, type "bt" (or "backtrace", but bt is shorter) and it will show the call stack. |
21:53 | <@AnnoDomini> | (It's supposed to be there already.) |
21:53 | <@McMartin> | (aha) |
21:53 | <@McMartin> | Read down it until you find a source file that you wrote, and note the line number. |
21:53 | <@McMartin> | That was the point at which the program had its fault. |
21:53 | <@McMartin> | It is not always where the error actually is |
21:54 | <@McMartin> | If n were normally, for instance, guaranteed to be in range, but something had scribbled over its value, the error would be at the scribble point. |
21:54 | <@McMartin> | But the backtrace is usually a good start. |
21:54 | <@AnnoDomini> | Aha. Is there a way to catch any exception, BTW? |
21:54 | <@McMartin> | You can also move up and down the call stack and ask it about the values of variables. |
21:55 | <@McMartin> | Probably, but C++ exceptions are not something I've studied. |
21:55 | <@AnnoDomini> | Well, anyway. Thanks for all your time. |
21:55 | <@McMartin> | If memory serves, C++ lets you throw anything, up to and including floating point numbers |
21:56 | <@McMartin> | For language-specific stuff, you're probably better off checking out a copy of Deitel and Deitel or something. |
21:59 | <@AnnoDomini> | http://pastie.caboo.se/159886 <- I'm trying this, but it isn't working. What am I doing wrong? |
22:00 | <@McMartin> | "It doesn't work" is the second worst bug report ever. |
22:01 | <@AnnoDomini> | What's the first? |
22:01 | <@McMartin> | "It works" |
22:01 | <@McMartin> | As a bug report |
22:01 | | * AnnoDomini should have probably said, "output the same". |
22:01 | <@McMartin> | Ah. |
22:02 | <@McMartin> | My guess is that ios_base::failure is not a superclass of whatever that out_of_range thing is. But that's not actually what you're doing wrong. |
22:02 | <@McMartin> | What you're doing wrong here is relying on C++ exceptions. |
22:02 | <@McMartin> | What you should be doing instead is checking the length of the string, and if it is n or less, printing the whole thing. |
22:03 | <@AnnoDomini> | Oh. |
22:03 | <@AnnoDomini> | I'm used to using try and catch as a way to solve uncatched exceptions from Java. It works there. |
22:03 | <@McMartin> | Yeah. |
22:04 | <@McMartin> | Java Exceptions are actually properly documented, and the library relies on them exclusively. |
22:04 | <@McMartin> | C++ exceptions have neither of these properties. |
22:05 | <@McMartin> | You can make iostreams throw exceptions too, but the default is for them to set status bits that you check. |
22:05 | <@McMartin> | The only time C++ will throw exceptions by default are for things that Java would classify as RuntimeExceptions or as Errors. |
22:06 | <@McMartin> | And, well, in Java's case, you wouldn't fix this by catching ArrayIndexOutOfBoundsException or IllegalArgumentException -- or, at least, you shouldn't. |
22:06 | <@McMartin> | You'd check the size first. |
22:08 | <@McMartin> | (there are a couple slippery cases, like FileNotFoundException, in the Java libraries, but those cases are usually handled via "bad" results in C++) |
22:09 | <@McMartin> | Java's more exception-friendly than C++ in general. That said, it shouldn't be used as an example of excellence |
22:09 | <@McMartin> | But that's a different rant |
22:10 | <@McMartin> | To wit, this one: http://rafb.net/p/WfefnZ66.html |
22:13 | | * AnnoDomini scratches head. What's it do? To me it looks like it cascades down into doing nothing if there are too many exceptions. Or something. |
22:13 | <@McMartin> | (C++ uses a semantics called "precise destructors" that gets around this to an extent, essentially exploiting some of the properties of stack objects, which Java doesn't have. C# adds an additional language construct that lets you do it explicitly.) |
22:13 | <@McMartin> | It ensures that the file is closed if it is ever opened, regardless of what exceptions may occur. |
22:14 | <@McMartin> | The last "do nothing" catch is if the close somehow fails. |
--- Log closed Sun Mar 02 00:00:50 2008 |