|
more falafel please posted:The biggest problem people generally have with learning pointers is that they're told "oh yeah, pointers are hard, that's why I hate C," and then they believe it's some horrible convoluted thing. Agreed. Pointers are hard to avoid making mistakes with (memory leaks, etc). They aren't hard to understand. A lot of new programmers don't pick up on that distinction when some people bitch about pointer problems.
|
# ? Jun 13, 2008 01:09 |
|
|
# ? Apr 29, 2024 07:57 |
|
Smackbilly posted:Agreed. Pointers are hard to avoid making mistakes with (memory leaks, etc). They aren't hard to understand. A lot of new programmers don't pick up on that distinction when some people bitch about pointer problems. Well to be fair if your first language isn't strongly-typed and you come to C later on it can get hairy and that may trickle down to pointers, too. Also, the concept of pass-by-reference versus pass-by-value is more obfuscated in other weakly(okay fine, "dynamically")-typed languages, though in essence I think it's the same issue. People think pointers are difficult (I thought so too), but the trick is they are simple, just deceptively so.
|
# ? Jun 13, 2008 01:41 |
|
chutwig posted:Just telling somebody to read K&R again doesn't help much when dealing with something like pointers that is very complex.
|
# ? Jun 13, 2008 09:56 |
|
more falafel please posted:The biggest problem people generally have with learning pointers is that they're told "oh yeah, pointers are hard, that's why I hate C," and then they believe it's some horrible convoluted thing. Yeah, I do wonder how many problems could be solved with: code:
|
# ? Jun 13, 2008 13:06 |
|
Zombywuf posted:Yeah, I do wonder how many problems could be solved with:
|
# ? Jun 13, 2008 14:09 |
|
I'm working on a fixed point class, which looks kind of like this:code:
code:
Why doesn't this work, and is there a way to resolve these ambiguities without explicitly casting ints and floas to cFp objects? I'm afraid it will require listing a new operator overload for each primitive type I want to use, but I'm hoping there's an easier, cleaner way. deadjb fucked around with this message at 15:42 on Jun 13, 2008 |
# ? Jun 13, 2008 15:38 |
|
TSDK posted:Well chapter 5 is one of the best and most concise explanations of pointers, so it is well worth giving it another read. It's certainly a much better explanation than anything I could have typed in response. 100% agreed. Pointers were a problem for me until I read chapter 5 of K&R carefully, not moving to the next example until I understood the previous one completely. When I finished, all ambiguity and confusion was gone, and I haven't had a problem since.
|
# ? Jun 13, 2008 15:49 |
|
The compiler doesn't know whether you want to implicitly convert 2 to a cFp, or f to an int. Get rid of those user defined cast operators in cFp and replace them with: code:
|
# ? Jun 13, 2008 15:49 |
|
I could be wrong about this because C++ overload resolution rules are really loving confusing, but here's what I think: It's because you have an implicit cast from int, so it can't tell whether to use +(int, int) or +(cFp, cFp). (I believe the += works because it's a member of the cFp class and not just a related function.) If you add an "explicit" keyword to your constructors, it should fix this problem at the cost of making you say, "cFp f = cFp(3)" instead of "cFp f = 3". ISTR Alexandrescu having a chapter about this issue. EDIT: now that I see it I think TSDK's right, it's because you have both an implicit cast to int and an implicit constructor from it. One or the other should work but not both.
|
# ? Jun 13, 2008 15:54 |
|
JoeNotCharles, TSDK posted:advice Ah, yeah, I completely understand now. Thank you both of you. I really, really like this thread. I hope I can be of more help in the future. Edit: I removed the casting operators (changing them to the AsInt/AsFloat methods), but I get a problem with (f+2). The error is "error: no match for 'operator+' in 'f + 2'". Shouldn't this work now, because 2 should be treated as a cFp? deadjb fucked around with this message at 16:15 on Jun 13, 2008 |
# ? Jun 13, 2008 16:03 |
|
I pasted my code to Nopaste. It's templated code, because I want to have varying precision and internal types. Additionally, I have a #define to create the binary arithmetic operators, because it's a lot of repeated code that doesn't really change save for which operators are being made. At the bottom of the file is my main function, with a simple typedef to avoid repeated template parameters. I added the error messages in the appropriate lines of the main function. http://rafb.net/p/RrIa7B42.html vvvvvvvvvv Thanks, I've cleaned that up in my local now. deadjb fucked around with this message at 20:24 on Jun 13, 2008 |
# ? Jun 13, 2008 19:21 |
|
One thing: inside cFixedPoint, don't type cFixedPoint<Storage, LongStorage, kPrecision>, it's not necessary. Just the name is sufficient; the compiler will deduce the template parameters. EDIT: As for your problem, the compiler isn't going to be able to deduce the type of a template if both arguments ("f" and "2") aren't of the appropriate type (cFixedPoint in this case). If you want to allow addition of literals, you'll need operator overloads for them. Boost's enable_if will simplify this for you. Avenging Dentist fucked around with this message at 20:27 on Jun 13, 2008 |
# ? Jun 13, 2008 20:21 |
|
Avenging Dentist posted:One thing: inside cFixedPoint, don't type cFixedPoint<Storage, LongStorage, kPrecision>, it's not necessary. Just the name is sufficient; the compiler will deduce the template parameters. I thought C++ supported automatic promotion if there exists a constructor which takes the type you're promoting from as its only parameter? EDIT: At least, that's what I believe this is claiming (down in the "Overloading binary operators" section), is it not?: http://oopweb.com/CPP/Documents/CPPAnnotations/Volume/cplusplus09.html deadjb fucked around with this message at 20:32 on Jun 13, 2008 |
# ? Jun 13, 2008 20:29 |
|
It doesn't work for templated operators, since the template instantiation occurs before type promotion does, and without type promotion, the proper template instantiation can't be chosen.
|
# ? Jun 13, 2008 21:07 |
|
Alright, I understand. I took a look through enable_if, and while I understand it, for now I'm going to just do some #define-ing. I don't really like to use #define, but it should make it pretty straightforward to read the interface.
|
# ? Jun 13, 2008 21:57 |
|
Smackbilly posted:Agreed. Pointers are hard to avoid making mistakes with (memory leaks, etc). They aren't hard to understand. A lot of new programmers don't pick up on that distinction when some people bitch about pointer problems. I figured out my earlier stupidity. Obviously, I came from Java. It was also good to get some experience working with valgrind and MallocDebug to see that I'm managing memory properly now and mallocing/freeing in the right places. Doing it correctly also helps enforce the difference between statically allocating memory on the stack and dynamically allocating it from the heap. In my own experience, the fundamental notion of a pointer is not hard. It's a variable that stores a memory address. Most of my confusion originates in what I perceive to be counterintuitive syntax by C. When you write something like char *blah, if you're reading it left to right, you initially think it's a variable of type char, and then have to reset mentally and re-read it as a pointer pointing to something of type char. I feel that syntax such as "&char blah", which could be read "address-of-char", would have been a more intuitive way to declare a pointer. The fact that * both declares and dereferences pointers is likewise confusing and is only overcome after you spend a while working with the language. I'm sure most of you will disagree with me, but that's just how I feel about these particular operators; that they were chosen for their roles somewhat haphazardly and inconsistently. That being said, I am now having another runabout with C, this time in printing out pieces of my earlier struct. Consider the following gdb output: code:
code:
code:
If only I understood your mysteries, C. I discovered this initially because invoking printf within the program with something like code:
This seems to be the case with all the GStrings in the struct; if you call printf within gdb and ask it to print the actual null-terminated string out, it prints out the integer value of len instead. If you ask it to print the integer value of len out, you always get 1. If you ask for it as a string value, the program then segfaults in the debugger. What's going on here? Here's a sample of the code that sets up the GString (I know it sucks, but it's the only way I could devise in which I could actually free the PGresult after I was done with it without causing a crash, and I didn't try to optimize it at all once I figured out a way). code:
|
# ? Jun 13, 2008 22:15 |
|
I'm pretty sure that value gdb prints each time is the return value of the function. printf doesn't return a string, it returns the amount of characters it wrote (an int). You probably aren't seeing it actually print anything because you aren't including a newline, so stdout isn't getting flushed. Also, it probably doesn't make sense to print curr_q as a string since it looks like its first member isn't a string. You should be using the proper data types in your format strings. %i (or more commonly, %d) refers to a signed integer. Basically, you need to read the documentation for the libraries you're using, including glib's documentation and the standard library documentation for your distribution. You also might want to read gdb's documentation.
|
# ? Jun 13, 2008 23:35 |
|
chutwig posted:Most of my confusion originates in what I perceive to be counterintuitive syntax by C. When you write something like char *blah, if you're reading it left to right, you initially think it's a variable of type char, and then have to reset mentally and re-read it as a pointer pointing to something of type char. I feel that syntax such as "&char blah", which could be read "address-of-char", would have been a more intuitive way to declare a pointer. And yes, the overloading of the * operator is fairly obnoxious, but then again I could say the same about the . operator in Java.
|
# ? Jun 14, 2008 02:06 |
|
One more GDI question. I seem to be getting horrible flickering when I blit something ontop of another, for instance a mask for transparency to a picture, and then the actual picture. It works fine, I just get really bad flickering, which I guess makes sense. How do I avoid this? If anyone cares, source and example: http://dykebeard.drinkhound.com/porn/starfield.rar edit: Yeah, I suck cocks. I want double buffering. Somehow it took all day to think of blitting the whole thing at once, only to find out that is double buffering. slovach fucked around with this message at 04:19 on Jun 14, 2008 |
# ? Jun 14, 2008 03:02 |
|
Milde posted:Basically, you need to read the documentation for the libraries you're using, including glib's documentation and the standard library documentation for your distribution. You also might want to read gdb's documentation. That's great, except notwithstanding that I forgot printf's return type due to my inexperience, it still doesn't explain why saying code:
chutwig fucked around with this message at 03:13 on Jun 14, 2008 |
# ? Jun 14, 2008 03:02 |
|
You should read the documentation for something if you aren't familiar with it or haven't used it in a while. Man pages will describe return values. If you're using a function and it's returning something that doesn't make any sense to you, it's probably a good idea to review the documentation before you jump to conclusions. Your second example calls printf without newlines, which means the output won't necessarily show up in your console immediately. And the second call to printf passes curr_q as a string, even though it's a struct. I wasn't commenting on your first example, and I said it doesn't make sense to print the struct as a string, not that it's irrelevant. I don't know why you're getting different results in and out of the debugger, but sometimes it is possible for this to happen. Were those debugger commands run postmortem? Have you tried loading the core dump the program generated when it crashed? If you're really absolutely stumped, I recommend running valgrind on your program. It might reveal the source of the problem, or reveal that something else is indirectly causing the crash. Turning on all/extra warnings in your compiler might also help. Allie fucked around with this message at 04:38 on Jun 14, 2008 |
# ? Jun 14, 2008 04:35 |
|
What happens if you printf(curr_q->current_query->str) directly?
|
# ? Jun 14, 2008 05:39 |
|
chutwig posted:That's great, except notwithstanding that I forgot printf's return type due to my inexperience, it still doesn't explain why saying My first thought with this bug would be that the string that you're printing is not null terminated. In GDB the block that you malloc might be set to all nulls, whereas at runtime it may not be. Try using memset to set your string to all NULs right after you malloc it, and see if the problem goes away. If so, double check your sizes and string copy operations to see where you're writing one too many characters into the string.
|
# ? Jun 14, 2008 07:18 |
|
Smackbilly posted:My first thought with this bug would be that the string that you're printing is not null terminated. In GDB the block that you malloc might be set to all nulls, whereas at runtime it may not be. The str segment in a GString is null-terminated, so it's usable as a valid C string. In the course of my learning about malloc, I was initially mallocing the GString as well as using g_string_new on it, but that turned out to be a double malloc, so I was leaking memory every time I did that. The way I'm handling it now, with g_string_new and then g_string_free if I'm deleting the struct from the hash table, seems to be the correct way to handle things. vanjalolz posted:What happens if you printf(curr_q->current_query->str) directly If I puts it by itself, no problem. If I printf it by itself, even, again, no problem. Only when I try to print it together with other non-string variables does it explode like this. That would explain why I wasn't having the problem in the debugger, because I wasn't doing the exact same thing. Now that I'm trying the exact same thing: code:
That being said, I can solve this pretty easily by either just printing them separately, or using a regular char* instead of a GString. Any thoughts on what might cause this behavior? I'm using OS X right now, but I first noticed the behavior on Linux. Since I'm on OS X right now, I don't have access to valgrind, but I do have MallocDebug (which does the same thing as memcheck), and there's no memory being leaked anywhere. chutwig fucked around with this message at 20:10 on Jun 14, 2008 |
# ? Jun 14, 2008 20:05 |
|
Not sure, maybe GStrings aren't 8 byte characters or something. I had problems with %s before, no idea how I fixed it. Try sprintf perhaps.
|
# ? Jun 15, 2008 11:40 |
|
chutwig posted:
It looks to me that curr_q->datid isnt a 4byte integer (probably 8) and its remaining top bytes are being used for the %s argument (which would be the NULL). Test: code:
|
# ? Jun 15, 2008 13:02 |
|
ani47 posted:It looks to me that curr_q->datid isnt a 4byte integer (probably 8) and its remaining top bytes are being used for the %s argument (which would be the NULL). Yeah, that actually occurred to me this morning, but since I'm currently babysitting some Exchange 2007 service pack updates I haven't had a chance to try it and see what happens. It would make sense, though.
|
# ? Jun 15, 2008 16:43 |
|
chutwig posted:Most of my confusion originates in what I perceive to be counterintuitive syntax by C. When you write something like char *blah, if you're reading it left to right, you initially think it's a variable of type char, and then have to reset mentally and re-read it as a pointer pointing to something of type char. I think K&R says that it's supposed to be a mnemonic. In char *b = 'R';, *b is kind of defined to "return" a char.
|
# ? Jun 16, 2008 02:55 |
|
I've been pouring over git tutorials and I can't find the answer to a simple question: I've made changes to several files in a directory, but not added them to the index yet because I'm just screwing around. I decide that the changes to about half the files are crap, and I want to throw them away (revert them to the version in the index). How do I do this? All I can find is "git reset --hard HEAD" which reverts both the index and working dir, and only works on whole directories at a time, and "git reset --mixed HEAD", which makes the index match the working tree. I can't figure out how to do the opposite of --mixed.
|
# ? Jun 16, 2008 16:46 |
|
I'm by no means a git expert but I use it for personal projects sometimes. In the past I've simply used git checkout to "unedit" (BitKeeper terminology) files. However it appears there are better options: http://bryan-murdock.blogspot.com/2007/07/git-revert-is-not-equivalent-to-svn.html
|
# ? Jun 16, 2008 17:03 |
|
Lexical Unit posted:I'm by no means a git expert but I use it for personal projects sometimes. In the past I've simply used git checkout to "unedit" (BitKeeper terminology) files. However it appears there are better options: http://bryan-murdock.blogspot.com/2007/07/git-revert-is-not-equivalent-to-svn.html code:
That link just says to use "git reset --hard HEAD", which doesn't work because it blows away changes to the index file too, and doesn't take a list of file: code:
|
# ? Jun 16, 2008 19:18 |
|
JoeNotCharles posted:
You can do a partial checkin and then a hard reset: code:
|
# ? Jun 16, 2008 19:31 |
|
JoeNotCharles posted:
You want to use git checkout without the -f, as explained in the comments of that link and the error message you got.
|
# ? Jun 16, 2008 19:35 |
|
floWenoL posted:You can do a partial checkin and then a hard reset: That doesn't help if I've got a bunch of stuff that's not ready to commit, and a bunch of stuff which is definitely garbage. I guess the git way is to make a "not ready to commit" branch and check all the stuff that's not ready in anyway. ShoulderDaemon posted:You want to use git checkout without the -f, as explained in the comments of that link and the error message you got. Aha, I skimmed over the second paragraph of the man page and just saw "-f: This is used to throw away local changes". Thanks, that's just what I wanted!
|
# ? Jun 16, 2008 19:50 |
|
I'm working with ncurses and I'm having a problem with getch(). I have a loop that sort of looks like: code:
MagneticWombats fucked around with this message at 08:51 on Jun 17, 2008 |
# ? Jun 17, 2008 08:49 |
|
mofmog posted:
I think you need to have your calls to getch() not be effected by your delay. I don't know anything about ncurses, so there might be other alternatives, but you could try something along these lines: code:
|
# ? Jun 23, 2008 16:34 |
|
Is there an easy way to execute another program from c++? Basically I'm trying to begin execution of programs in my c:\program files\.. through my program. An example opening notepad.exe from its pathname instead of just calling system(notepad) would be great!
|
# ? Jun 24, 2008 02:54 |
|
FearIt posted:Is there an easy way to execute another program from c++? On Windows, CreateProcess or CreateProcessEx. I'm not sure if the second one is preferred over the first or just has some extra options. On Mac and Linux, fork followed by exec.
|
# ? Jun 24, 2008 03:07 |
|
JoeNotCharles posted:On Windows, CreateProcess or CreateProcessEx. I'm not sure if the second one is preferred over the first or just has some extra options. I'm having trouble understanding all the arguements is there anyway I could get an example of CreateProcess?
|
# ? Jun 24, 2008 03:16 |
|
|
# ? Apr 29, 2024 07:57 |
|
FearIt posted:I'm having trouble understanding all the arguements is there anyway I could get an example of CreateProcess? Have you tried Googling "CreateProcess example"? (I highly recommend avoiding the Windows API as much as possible and using higher-level libraries like .NET or Qt, since in almost all cases the API is so much better that you'll save hours and hours of headache in exchange for an extra half hour of setup time. CreateProcess is one of the prime examples. In Qt you'd use the QProcess class for this, for instance. But if you've already started something changing to a new language or framework for this one feature doesn't make any sense.)
|
# ? Jun 24, 2008 03:23 |