|
So I've had this question regarding const-qualifying a function. Basically I have a class that contains a mutex and a function Lock(scoped_ptr<CTraits>). that allows a client to grab the mutex. The function takes as an argument a scoped pointer, in which it returns a traits object that will automatically release the mutex when it falls out of scope. My question regards whether the Lock() function should be qualified as const or not. What if I have separate LockForRead and LockForWrite functions that provide access to an underlying ReadWriteLock instead?
|
# ? Nov 22, 2011 21:25 |
|
|
# ? Jun 6, 2024 17:24 |
|
I guess my real question was "What on earth is an 'invalid' pointer if it's not just a non-dereferencable one." What an oddly narrow guarantee.
|
# ? Nov 22, 2011 23:34 |
|
shodanjr_gr posted:My question regards whether the Lock() function should be qualified as const or not. What if I have separate LockForRead and LockForWrite functions that provide access to an underlying ReadWriteLock instead? Make neither const. Locking a class moves it from an "unlocked" state to a "locked" state. This kills the constness. Or make both const, since locking for write and releasing it doesn't actually modify the object in any significantly different way from locking for read and releasing it.
|
# ? Nov 22, 2011 23:46 |
|
GrumpyDoctor posted:I guess my real question was "What on earth is an 'invalid' pointer if it's not just a non-dereferencable one." What an oddly narrow guarantee. Hardware can be weird. A "valid" pointer is one that won't crash your program just by existing. As an example, some hardware platforms have separate registers for pointers and data - a platform like that could check that any pointers have sane values when they get loaded into a pointer register, and raise a processor exception if they don't. The spec guarantees that producing a pointer to one-past-the-end of an array won't cause such a trap - but makes no such guarantees about pointers further away then that. As a less esoteric example, it's guaranteed that a pointer one-past-the-end of an array won't have overflowed around to something close to zero.
|
# ? Nov 22, 2011 23:51 |
|
To relate it to a similar concept, think about C++ iterators -- the semantics of end() are just like the semantics of p + N for a buffer of length N. The iterator end() is valid, clearly, since the method exists and returns an object, but dereferencing it would result in undefined behavior.
|
# ? Nov 23, 2011 01:39 |
|
shrughes posted:Make neither const. Locking a class moves it from an "unlocked" state to a "locked" state. This kills the constness. Well those are the two options that I've been torn over however I was wondering if there is a concensus/convention on this.
|
# ? Nov 23, 2011 03:52 |
|
shodanjr_gr posted:Well those are the two options that I've been torn over however I was wondering if there is a concensus/convention on this. My preferred style of API is to have the lock acquisition object itself be the thing which has the API for making modifications. So instead of having code:
code:
code:
In such a case, naturally a WriteLockHolder would have to take a non-const thing as its argument. Whether a ReadLockHolder would take a const thing or not is situational. If it helps you out with a real problem with const correctness that would prevent mistakes from being made, go for it.
|
# ? Nov 23, 2011 04:41 |
|
GrumpyDoctor posted:I guess my real question was "What on earth is an 'invalid' pointer if it's not just a non-dereferencable one." What an oddly narrow guarantee. There's no concept of a "valid" pointer in the standard(s). There is a concept of undefined behavior. It is undefined behavior to perform pointer arithmetic that would give a result pointing outside the object containing the base pointer, except to point immediately after it. It is also undefined behavior to dereference a pointer that does not point at an object, except that assignments into valid storage are magic. This is a ridiculously useful property for optimization, because without it you have to assume that any array access of unknown index might touch any object whose address has escaped.
|
# ? Nov 23, 2011 08:30 |
|
Well there is the Core Language Issue 523:quote:523. Can a one-past-the-end pointer be invalidated by deleting an adjacent object? So the behavior is maybe "under-specified"?
|
# ? Nov 23, 2011 15:21 |
|
I've run into a #include issue, I'm not sure how to fix it. I keep getting the 'Multiple definition of ..." error when I place my header file 'draw.h' inside of 'gameCore.h', stating that I already have it included inside of 'main.cpp'. Except it's not included in main.cpp. But when I throw 'draw.h' inside of 'gameCore.cpp', everything works fine, but then I can't include 'draw.h' in any other files or the 'Multiple Definition of ...' error pops back up. I'm not sure how to go about fixing this, and yes I am using header guards.
|
# ? Nov 23, 2011 20:35 |
|
Do you have any non-inline, non-template functions defined in draw.h? Because that would cause you to have a function defined in more than one compilation unit which would confuse the linker.
|
# ? Nov 23, 2011 20:45 |
|
I'd never heard of an inline function until now, just did some reading up on them. Yeah, I have 2 non-inline functions defined in draw.h. So, if I'm understanding everything correctly, I just need to make them inline functions, or stick them into a template?
|
# ? Nov 23, 2011 20:57 |
Princess Kakorin posted:I'd never heard of an inline function until now, just did some reading up on them. Yes either that, or move them to a separate compilation unit.
|
|
# ? Nov 23, 2011 21:14 |
|
nielsm's suggestion is most likely the one you should be taking. Unless there's some particular reason for you to be defining the function as inline, you should be PROTOTYPING it in the header file, then DEFINING it in exactly 1 seperate .cpp file. If you define functions in a header and use "inline" to get rid of the linker errors that would otherwise occur, what you've done here is make every compilation unit that includes that header will then have the definition of that function as a dependency. lets say you have project named "qux" with three cpp files (foo.cpp, bar.cpp, and baz.cpp) which all include 1 header file (header.h). When you compile for the first time, the preprocesser will textually insert the contents of header.h into each of the .cpp files, giving you three separate compilation units. these compilation units will then be compiled to object files -- lets call them foo.o, bar.o, and baz.o. then, the linker links all three .o files together to get your file executable, "qux". If header.h contains an function (int bap(int p1 ,int p2)) definition that isn't declared inline , when it comes to the linking stage, the linker will see that this function exists in all 3 compilation units and won't know which one to pick -- there needs to be exactly one definition of each function for the linker to properly resolve all references to a particular function. If you mark it inline, then compiler treats it specially -- it can actually sub the body of the function in at every location that it is called, or, if it judges this is a bad idea, it can tell the linker that even though it's defined in more than one unit, they're all the same anyway and the linker can just go ahead and throw away all but one copy. The problem with this is that what if you want to make some kind of change to the implementation of bap? something that doesn't change the parameters or return value, but maybe optimizes the way the function works a little bit? If you have the function defined in the header, then to alter the definition you have to alter the header. then, your build system (make, or visual studio, or whatever) will be forced to regenerate foo.o, bar.o, and baz.o -- even though functionally, nothing changed about them. What is much better is to either create a new cpp file, or to move the definition of bap into one of the existing .cpp files -- say, foo.cpp. Now, if you need to alter bap in a way that doesn't change the function's interface, the other object files using the interface will not need to be regenerated. Doing this right will give you much faster builds.
|
# ? Nov 23, 2011 21:37 |
Using inline also risks you defining two different functions with the same name and not noticing. If foo.cpp includes abc.h and bar.cpp includes def.h, and both abc.h and def.h define a function void florb(int), but the two definitions are different, different things will happen depending on whether florb() is marked inline: If it's not, the linker will complain as it should. If it is marked inline, the linker will pick one of the two different implementations and use that, resulting in one of foo.cpp or bar.cpp calling the wrong florb(). Inline functions carry that risk.
|
|
# ? Nov 23, 2011 21:56 |
|
I had a similar problem when I recently got into C++. Basically, external linkage is your friend. Qualify the prototypes in your header with extern, and put the definitions in a cpp file. like so: code:
Edit: er.. just realized I may have been confusing this with a similar but different problem. It won't hurt anything to have the extern keyword there, but it turns out the keyword is not needed for function declarations. Colonel Taint fucked around with this message at 01:18 on Nov 24, 2011 |
# ? Nov 24, 2011 01:01 |
|
Thinking about this problem in terms of external linkage really doesn't make any sense here, as you're within a single compilation module. Getting into the habit of blithly using extern when you don't actually want identifiers shared between modules could get you into trouble when you start working on larger programs.
|
# ? Nov 24, 2011 02:25 |
|
I assume you mean because of the increased probability of naming collisions? If it's anything more than a small C++ project, it's probably a good idea to consider using namespaces. In any case it seems more reasonable to me to move the functions to a separate compilation unit than making the functions inline for the purpose of avoiding multiple definitions.
|
# ? Nov 24, 2011 16:45 |
|
Hi thread! I was working in C# in my last job, my first programming role in the games industry after doing a bunch of games testing. I got made redundant at the beginning of the year and am finding there are plenty of roles I would otherwise go for that require C++ skills, and annoyingly, a role I had a phone interview for and was told wanted me in for an in-person interview, ended calling back after a month of silence to tell me they wanted C++ now. The problem may also be how I learned C#, on the job researching the solutions to problems as I came to them, which resulted I think in holes in my knowledge or just not knowing terminology. I keep booking up on C# itself, but I think going back to basics on OOP might be good for me. So I'm looking to get a recognised C++ qualification of some kind. I can't magic up loads of professional experience but I think it would help me a lot to show I know it. I've found a bunch of 10-12 week evening classes of a couple of hours a week, though obviously I want to find work an move out of my parent's place, so would rather not be tied down. I know that I might be able to get a discount for being unemployed though. I think ideally I want to do a course that takes up the whole day for a few days, or something I can do online that I can get feedback for and some certificate/grade/qualification at the end. Can anyone suggest anything? I live in the UK if it matters, Chichester specifically, but can travel elsewhere to study short-term if needed. I have a bunch of family in London I might be able to stay with. Or do you think such a plan is pointless, and I should just read the sites and books in the OP and self-teach?
|
# ? Nov 26, 2011 13:19 |
|
I don't get what is up with people's idea that to learn some CS thing, they should take a course. Especially when that thing is a programming language! I know that my general attitude to somebody who took a course in C++ after college because he wanted to learn the language would be, How did that course make you not suck at programming? I certainly won't think that such-and-such person is going to be non-craptastic at C++ after a mere 10-12 weeks. You'd be much better off in my mind and the mind of any company worth working for if you taught it yourself and wrote some frakking code in C++. If they're unsure of your ability (and they will be, no matter what is on your resume, even if you won the Nobel prize in C++) they'll have you do some kind of test, i.e. make such-and-such application in C++, or do this problem on the whiteboard, or whatever. To get a job you'll need to not suck at C++, hopefully. To get interviewed, the best thing to do is to have evidence of having used C++ in some non-trivial non-retarded way on your resume. When they see "B.A. took a course in C++" they'll (hopefully) think you're some shmuck who sucks at programming so bad he signed up for a course in a programming language and then bragged about it on his resume. When they see "B.A. wrote some ______ thing in C++" they'll (if they're not HR drones or something) think you're an actual programmer who can write actual code. Of course you're in the UK and from what I can tell employers there might possibly be insane, so YMMV, wait and see what tef or Fib or qntm have to say.
|
# ? Nov 26, 2011 14:33 |
|
My impression is that certifications are mostly good for jobs at companies large enough and incompetent enough that the person evaluating your CV doesn't actually understand what the job will involve. If I did have a certification in C++, I wouldn't list it on my CV, because it signals the wrong thing; wanting to appear to know C++, rather than actually knowing C++. There are many good books about C++, many good blog posts, etc. You can teach yourself. If you want a more well-rounded education in software engineering and computer science, check out some of the free material on http://www.cl.cam.ac.uk/teaching/1112/ or http://ocw.mit.edu/. And yeah, write some frakking C++. P.S. Don't do games, flee games, games is a terrible industry.
|
# ? Nov 26, 2011 14:55 |
|
I remember when I applied for a job at some small game company after graduating college. They wanted to pay hourly and they wanted to pay $19 per hour. Hahaha no.
|
# ? Nov 26, 2011 14:59 |
|
shrughes posted:I remember when I applied for a job at some small game company after graduating college. They wanted to pay hourly and they wanted to pay $19 per hour.
|
# ? Nov 26, 2011 15:44 |
|
shrughes posted:I remember when I applied for a job at some small game company after graduating college. They wanted to pay hourly and they wanted to pay $19 per hour. Same story for me but for less than that, at a THQ studio, and I foolishly took the job. roomforthetuna posted:That's better than entry-level with one of the big evil companies, where they'll pay a salary that looks like the equivalent of about $25 an hour, but then demand you work 80 hour weeks with no overtime pay. The joke at this particular studio (which is no longer a part of THQ) was that some of the salaried employees made less than those who were payed hourly because pretty much every week was at least a 60-70 hours. Basically the game industry is mostly poo poo.
|
# ? Nov 26, 2011 18:49 |
|
It appears that arrays and array accesses don't work how I think they work in C. I have a text file with each line in it containing a string of 32 ones and zeros. What I'm trying to do is load them in an array to operate on them later. Seems I can read them to my storage array, print out the value immediately after reading it in, and everything seems fine. But when I make the same call to access the array only a couple lines down, something goes terribly wrong. I've been banging my head against the wall trying to figure it out but that doesn't seem to be helping much. Any sort of nudge in the right direction would be immensely helpful. Here's the problem code, if anything more specific like the input file is needed I can provide one. http://pastebin.com/8c4LsZHY
|
# ? Nov 26, 2011 21:47 |
|
HipsLikeCinderella posted:It appears that arrays and array accesses don't work how I think they work in C. I have a text file with each line in it containing a string of 32 ones and zeros. What I'm trying to do is load them in an array to operate on them later. You're only incrementing i by 1 in the loop, even though you are reading more than 1 byte every iteration, so you are stomping over old data with every read. Also, why is program defined as a 2d array if you aren't using it like one?
|
# ? Nov 26, 2011 22:33 |
|
The1ManMoshPit posted:You're only incrementing i by 1 in the loop, even though you are reading more than 1 byte every iteration, so you are stomping over old data with every read. Thanks, that helped a lot. I was using a 2d array for some functionality I haven't implemented yet, but seems when I take away the second pair of brackets the program won't compile. Good thing I'll be using them anyway?
|
# ? Nov 27, 2011 01:58 |
|
One final question while we're on the topic: Now that I have all the ones and zeros stored contiguously in an array (in char format), I'm trying to operate on substrings using the strncpy function but it's not working. I don't know much about C/C++ IDEs so I'm just using tcc to compile and when it gets to the strncpy line, it just stops there. If I comment it out everything works but obviously that's not an option. Here's the code (and pastebin): code:
|
# ? Nov 27, 2011 18:41 |
|
Hello again, friends. I was given a Binary Search Tree class example from my professor, and despite my best attempts to understand it fully (even with contacting him, it's an all online class), I'm not getting it. Here's part of the class, and a few lines from the example program that I can't wrap my head around.code:
code:
I have a feeling there's something here that I'm completely missing but I've spent quite some time trying to understand it and when I think I've gotten it, something else changes my view. Thanks in advance. I really have nowhere to turn, and it's not like I can just look at other BST examples because our exams are always problems based off this code.
|
# ? Nov 27, 2011 18:46 |
|
HipsLikeCinderella if you are running gcc on the command line it should spit out an error if there is some sort of syntax error. Otherwise I need more info on what tok is defined as to diagnose the error. Good Will Punting, Yes, the root is being modified because the insert function takes the pointer by reference not by value. You can learn more about the differences between pass by reference and value here http://www.cplusplus.com/doc/tutorial/functions2/.
|
# ? Nov 27, 2011 19:05 |
|
Yeah, I figured it was something like that and I know about ref/value but was confused by the fact that "root" doesn't appear to be passed into the private function via the public by reference. Upon execution of the third "Insert", does root then point to that lastly inserted value (50 in my example)?
|
# ? Nov 27, 2011 19:13 |
|
delta534 posted:HipsLikeCinderella if you are running gcc on the command line it should spit out an error if there is some sort of syntax error. Otherwise I need more info on what tok is defined as to diagnose the error. Sorry, tok is a char pointer, i.e., the declaration is "char* tok" It is null before the strncpy call. Let me know if you need any other info, I can post the entirety of the source code (it's not very long) if you need it.
|
# ? Nov 27, 2011 19:30 |
|
Good Will Punting posted:Yeah, I figured it was something like that and I know about ref/value but was confused by the fact that "root" doesn't appear to be passed into the private function via the public by reference. Good Will Punting posted:Upon execution of the third "Insert", does root then point to that lastly inserted value (50 in my example)? No the insert function follows the tree to the first empty node and inserts there. So it would only change on the first insert. HipsLikeCinderella posted:Sorry, tok is a char pointer, i.e., the declaration is "char* tok" Tok should be allocated before use. Strncpy does not allocate the space for you.
|
# ? Nov 27, 2011 19:41 |
|
delta534 posted:No the insert function follows the tree to the first empty node and inserts there. So it would only change on the first insert. Is "nodePtr = newnodePtr;" not the line that modifies root on this first insert? Won't this line have to execute upon every call to insert due to the recursive nature of the function? Maybe I just have a poor understanding of how recursion works in this case but I'm still pretty lost.
|
# ? Nov 27, 2011 20:30 |
|
Good Will Punting posted:Is "nodePtr = newnodePtr;" not the line that modifies root on this first insert? Won't this line have to execute upon every call to insert due to the recursive nature of the function?
|
# ? Nov 27, 2011 21:48 |
|
roomforthetuna posted:You are correct that the line will execute at the end of the recursion, but when it executes, the nodePtr passed to the function won't be a reference to root except the first time it is called. Each recursion has a different nodePtr, being a reference to the branch of tree. Ohhh, so when this nodePtr is modified, it isn't a reference to root anymore, it actually has nothing to do with root, it's an entirely separate pointer passed in. Got it. That took entirely way too long for me to understand. Once again, thanks for the help! I'd be lost without you folks.
|
# ? Nov 27, 2011 22:32 |
|
Can anyone recommend a CSV-parser function/library that has no problem chewing through gigabyte size files without loading the whole thing into memory? I'm tinkering around with my own but it seems to me that this problem should be solved by now. Thanks.
|
# ? Nov 28, 2011 14:48 |
|
I'm a complete beginner to C, so I've attempted to start writing a command-line dice roller. My question is with regard to number randomness. What I've written seems random enough, but I'm not sure if it's a "proper" way to go about this. There's a plethora of info regarding this problem, but none of it is particularly concise for a beginner or explains how to properly use it. Below is my code, and then the results of how many times a number appeared based on D20 rolls. code:
01 : 154 02 : 135 03 : 138 04 : 171 05 : 162 06 : 128 07 : 145 08 : 140 09 : 152 10 : 142 11 : 123 12 : 152 13 : 151 14 : 120 15 : 159 16 : 139 17 : 146 18 : 135 19 : 150 20 : 136
|
# ? Nov 28, 2011 21:01 |
|
That's fairly reasonable, in that you seeded the rng with the number of nanoseconds, with the goal of avoiding reseeding the RNG the next time you run the program with the same value. Your choice to use rand() % x is good enough for small values of x for recreational purposes. If you wanted to be anal you should take into account that RAND_MAX + 1 is probably not a multiple of x. (This requires calling rand() more than once, on occasion.) The idea of seeding a random number generator and using it exactly once is indeed kind of wonky, part of me says you should read some bytes off of /dev/urandom (if on a UNIX system) instead. But relax.
|
# ? Nov 28, 2011 21:35 |
|
|
# ? Jun 6, 2024 17:24 |
|
What are the usual reasons for why program would change its behavior based on whether or not I cout a float point value or not? That is the results of my computation seem to depend on that, and its confusing me why printing out one of my variables makes any difference.
|
# ? Nov 29, 2011 03:24 |