|
mracer posted:Ok, more of a Visual Studio question. Whats the best way to step thru code with many macros. you know #define functions. This will work if adst is an array, but not if it's a pointer (and not if it's an array that's degraded to a pointer in the current scope). First off, you should use memcpy() or std::copy (if C++), because they're generally optimized beyond what you're going to write. But if you want to debug this, I would suggest putting printfs/couts/however you log in the macro itself. code:
|
# ¿ Feb 17, 2008 09:11 |
|
|
# ¿ Apr 25, 2024 14:03 |
|
Entheogen posted:when i do a left shift, does the left most bit get sent to some carry register? on x86 machines, what would be the name of it? If this isn't really performance-critical (like you're trying to avoid a couple more instructions and a jump per shift), I would go for the sure-fire cross-platform approach and check if the highest (or lowest for right shift) bit is set, and if so, bitwise-or it on to the lowest(/highest) bit of the result of the shift.
|
# ¿ Feb 17, 2008 09:54 |
|
Lexical Unit posted:Let's say that now I want to make my container exception safe. I'm not sure where I can find information on what parts of the STL are exception safe (and at what level). If anyone can recommend a book or website that would help in this area please do. I have Sutter's Exceptional C++, just not on hand at the moment, so if that's good enough just let me know. I can go re-read it now that most of it isn't over my head. From the horse's mouth: http://www.research.att.com/~bs/3rd_safe.pdf
|
# ¿ Feb 22, 2008 01:38 |
|
Space Duck posted:I haven't touched C++ in a couple of years, so maybe I'm just missing something obvious, but this has me stymied. Is eventLog of type Log or Log&? If it's Log, does Log's assignment operator work normally, so that if one is copied, the copy has the same log file open? Do you have one QueueRunner object or several?
|
# ¿ Feb 22, 2008 23:07 |
|
Itaipava posted:I thought the same thing, but I don't think it can be Log&. If it were the case, wouldn't eventLog -have- to be assigned to log in the constructor's initialization list? Yeah, you're right about the reference assignment. He should be doing that anyway, though.
|
# ¿ Feb 22, 2008 23:43 |
|
Ari posted:The question comes up pretty often as to the de facto library of books for learning various programming languages and concepts. In my experience reading threads discussing them and reading several of the books named, I think the general goon consensus is that Eckel's Thinking in C++ is the best one to pick up C++. But why are you learning both C and C++ at once? Also Koenig's Accelerated C++: http://www.amazon.com/Accelerated-Practical-Programming-Example-Depth/dp/020170353X
|
# ¿ Feb 26, 2008 17:33 |
|
Red Oktober posted:I'm currently getting started in C, by using it to write a compiler of sorts (its for an assignment). I'd suggest taking this opportunity to learn about working without an IDE, especially since you're getting started with C. IDEs tend to abstract away a lot of important details about the C/C++ compilation model, which may come back to bite you later. I would say to find a text editor that you like -- TextMate seems to be the favorite on OS X for just about everyone except the Vim users, or Vim if you want to be a real programmer^H^H^H^H^H^H^H^H^H^H^H^H^H^H^H^H^H^H^H^H^H learn Vim. Then learn to use gcc and make, enough to write a simple Makefile.
|
# ¿ Mar 1, 2008 04:44 |
|
I say make and not autotools (or a better build system like CMake, SCons, or Boost.Jam) because it's simple and you're more likely to run into that, at least in the C/C++ world, than something else. For a simple project with a few source files, a Makefile would look like this: code:
|
# ¿ Mar 1, 2008 18:58 |
|
HB posted:What about a project with 40 source files and multiple targets? He's just getting started, I doubt that's going to happen. At any rate, I think one of the reasons you should use make is to learn when you shouldn't
|
# ¿ Mar 1, 2008 21:12 |
|
tef posted:Also, calloc() initializes memory to 0, while the contents of memory returned by malloc() are unspecified. Other than that, though, they're equivalent.
|
# ¿ Mar 5, 2008 01:23 |
|
GT_Onizuka posted:Oh wow, that certainly helped out quite a bit. I'm getting some errors, but they seemed to be related to the libraries. Considering how old things are, I suppose I shouldn't be too surprised. Thanks again, I'm almost on my way! It looks like either the headers are out of date with the libraries you're linking in (unlikely), or you're not linking in the library correctly.
|
# ¿ Mar 6, 2008 22:03 |
|
Incoherence posted:erase takes an iterator parameter. You probably want alphabet.erase(alphabet.begin()+j). Why is it this hard? Because the STL is weird. Because iterators are better. Why? 'Cos.
|
# ¿ Mar 9, 2008 17:18 |
|
Thug Bonnet posted:No, that's what I'm asking! I'm just kind of curious, honestly. But how would the program know "where it is" in memory, how large it is, etc. Also, I assume it's not necessarily contiguous.. That depends on the OS. Also, these will be logical addresses, relative to the page table for your application, so they're basically meaningless outside, unless you can run in kernel mode or something. But yeah, it's not going to be contiguous, you'll have different segments for the actual program code, static data, stack, and the free store. edit: crap, I missed that page 6 existed, ignore me.
|
# ¿ Mar 11, 2008 01:15 |
|
xobofni posted:Really stupid question here about pointers in C. There's two issues here, one that addresses your immediate problem and one that will clear some things up for you. In the first case, what's happening is you're declaring an array of char (actually, an array of 12 chars), and filling it with 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '\0'. In the second case, you're taking a pointer and assigning it the address of a string literal which the compiler embedded into the executable somewhere. Generally, those string literals are in read-only segments of memory. The second point is that pointers and arrays are not the same thing: http://c-faq.com/aryptr/
|
# ¿ Mar 11, 2008 21:55 |
|
Mr VacBob posted:If you're debugging an optimized program, the debug info is probably wrong and giving you nonsense answers. This. Try it with optimizations off, or try printing the values you need instead of trusting the debugger, if you need those optimizations for debugging.
|
# ¿ Mar 13, 2008 04:50 |
|
Hyphen-ated posted:I am using VC++ 2005 express. I have sections of code that are #if'ed out sometimes. When editing this code, VC++ decides to gray it out and disable "go to definition" and friends in the context menu. This makes it more difficult to edit this code, which does actually get compiled sometimes. I would like it to treat all code as live code regardless of whether it looks like it will be compiled. Visual Assist can handle this, and it's Go To Definition isn't retarded like VS's is. Of course it's also money.
|
# ¿ Mar 19, 2008 04:47 |
|
Drx Capio posted:It can't. The compiler MUST know the size of One in order to compile Two. It can be done with a level of indirection, though: It's dumb, but what it was suggesting was: code:
|
# ¿ Mar 27, 2008 01:23 |
|
floWenoL posted:Honestly that's not a very large project; have you tried building one of Firefox, KDE, or OpenOffice lately? Anyway, the issue is not the from-scratch build time, but the one-line-header change build time and from making sure that that isn't approximately equal to the from-scratch build time. On my last project (about 1.5M lines of C++), cleaning up headers reduced our full build from about 4 hours to about 20 minutes, and reduced the frequency of full builds from about once a day on average to about once a week on average. Incremental builds were still about 5 minutes, mostly because of linking, but when you have that much code that needs to be statically linked, there's not much you can do about link times. Most of this was due to the braindead way that the Unreal Engine generates headers from script classes -- all script classes belong to a "package," which is just a directory containing each of those script classes. For a package such as "Engine," there are about 100 script classes. Instead of generating one header for each of these, stock UE3 generates "EngineClasses.h" with all the declarations in one place (presumably so they don't have to worry about those pesky "dependencies" everyone keeps going on about). So you can guess how many C++ files include EngineClasses.h. We changed the script compiler so it generated a header for each class, and then started including only the headers necessary for each C++ file. That alone reduced our build times by about 90%. YMMV, obviously.
|
# ¿ Mar 28, 2008 00:34 |
|
6174 posted:I've got a template function in which I'm doing a comparison like: Since numeric_limits<T>::is_signed is a compile-time constant, you should be able to make use of SFINAE to make one specialization for signed types and another for unsigned types. Otherwise, you can just turn off that warning with a #pragma around that block or for that file on the command line, but I'm pretty sure SFINAE is the proper way to do it. Concepts would make this easier.
|
# ¿ Apr 11, 2008 19:55 |
|
That Turkey Story posted:Oh my lord... I hope that isn't what he was using std::vector for! To be fair std::vector is a really dumbass name, WTG Bjarne.
|
# ¿ Apr 25, 2008 00:31 |
|
SintaxError posted:I could be wrong, but I don't think your remove function should be declared/defined as const. Yes, although the node_count = node_count - 1; shouldn't compile like this anyway. But yeah, remove shouldn't be const.
|
# ¿ Apr 28, 2008 23:53 |
|
Avenging Dentist posted:It is an issue. I'm assuming the "converting NULL to double" error occurs at return NULL; in your code. That's bad because NULL isn't a valid value for non-pointer, non-integral types. It's performing an implicit conversion from a pointer (integer) type to the type of the elements in your list. Think about what would happen if there is no such conversion... If you can change the signature of the function, I would return a bool instead of a T. There is no generic "bad" value for all types in C++. However, since your function already takes the element to remove, the caller already knows what element will be removed, and returning it is redundant. I would return true if the element was found and removed, and false otherwise.
|
# ¿ Apr 29, 2008 01:09 |
|
KaeseEs posted:If it's an option, replace cout with cerr while debugging (STDERR is unbuffered). Otherwise, look up setbuf(3). Sending std::flush or std::endl (flush with newline) to an output stream will also flush its buffer.
|
# ¿ Apr 30, 2008 17:36 |
|
vanjalolz posted:Pointer and int are usually the same size though... NEVER assume this. You have no idea how many times this comes up. If you want your code to compile on 64-bit, DO NOT ever assume this. Like, ever. Ever.
|
# ¿ May 1, 2008 16:35 |
|
Smackbilly posted:I could certainly consolidate timeout handling into one thread, but that would make the code messier and more complicated, so I'm inclined to avoid that unless there is a good reason to do it. It doesn't, really. All you need is a list of packets you have sent out but not received ACKs for yet. When you receive an ACK, remove that packet from the list. Also keep track of the last sent time and resend it every so often. Also, you can average the total round trip time of the last, say 10 packets, and use that as the timeout interval, to avoid sending to frequently or not frequently enough depending on network conditions.
|
# ¿ May 24, 2008 03:38 |
|
Zombywuf posted:Why are you emulating TCP? TCP is not always necessary.
|
# ¿ May 25, 2008 18:17 |
|
HB posted:Lots of games using UDP with a very thin reliable layer on top of it. It can be tweaked to better match their traffic patterns (small packets, no bulk transfers, compensation for loss at the application layer) than TCP. TCP is way, way, way overkill for most applications. For most applications, it doesn't matter, because the hit you take for using TCP isn't big enough to worry about. There are some applications, games being one of them, where most of the time, you want to reduce bandwidth as much as possible and not waste processing time in the OS doing more checking than you need. Also, many network protocols are not stream-oriented, which leads to building a "message" structure analogous to the underlying packet structure inside the TCP stream, which is in turn on top of the packet structure. I don't have any idea if a reliable UDP layer is the right tool for Smackbilly's protocol, but he apparently has no control over it. But it's not "emulating TCP" any more than an RDBMS is "emulating a hash table".
|
# ¿ May 26, 2008 05:13 |
|
floWenoL posted:On the other hand, it introduces an invalid value (kNumWhatever) that is treated like a valid value. Plus GCC on overly paranoid settings will complain if you do this: code:
But you should be putting default: blocks in switch anyway.
|
# ¿ Jun 5, 2008 17:00 |
|
chutwig posted:Okay, I understand my first mistake; forgetting that the pointer is its own type with a different size from what it points to. 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.
|
# ¿ Jun 13, 2008 00:58 |
|
slovach posted:It's pretty simple actually. Looks like at least some browsers (Safari at least) treat & p i ) ; as & p i ;, which should render as the pi symbol.
|
# ¿ Jun 24, 2008 08:13 |
|
floWenoL posted:What do you guys think of this? There's some stylistic issues I don't agree with that people have been arguing about for 30 years (wtf uses 2 spaces) but other than that I think it's pretty sane. Some day I'll post the tale of mustDeref() and make you all converts.
|
# ¿ Jun 30, 2008 02:48 |
|
Avenging Dentist posted:Also the "no using in .cc files" rule is laffo. That's pretty much the only place you should have using declarations. I understand it. They also say to eschew abbreviations in naming. using declarations are just abbreviations, really. I'm not saying I particularly like it, but I don't really have an opinion.
|
# ¿ Jun 30, 2008 03:18 |
|
That Turkey Story posted:Well put.
|
# ¿ Jun 30, 2008 08:44 |
|
ZorbaTHut posted:Real-world numbers tend to follow a power distribution, and in power-distribution-land, that extra bit increases your number's range by a piddling 3%. That's usually not anything worth mentioning. You have absolutely no understanding of what you're talking about. edit: OK, I think it's just phrased badly and you're talking about power distribution. I thought you were actually arguing that adding bits to a number increased the range of values the number could store linearly instead of exponentially. more falafel please fucked around with this message at 21:23 on Jul 2, 2008 |
# ¿ Jul 2, 2008 17:45 |
|
ZorbaTHut posted:It would be hard for me to disagree with more points here And it's a bad example, because the simpler, more correct solution would be to use iterators, in which case you would have had to go way out of your way to introduce a bug like that. ZorbaTHut posted:It's just not something that ever comes up - I consider this to be well within the bounds of "this never happens". It's those subtle bugs -- like the ones that can be easily introduced by using offsets instead of iterators, that make "this never happens" turn into "But I never thought that would happen". Every simple programming error that can be made, will probably be made, often by you. Use a simpler and less error-prone solution where possible. ZorbaTHut posted:And even if it does, I'd say a better solution would be to use a longer signed type, like "long" (which will be 64-bit on virtually any sane system where .size() can be 1<<31) I'm not aware of any 32-bit system in which long is 64-bit, is that what you're saying? "ZorbaTHut posted:or "long long" (which will be 64-bit and which is nearly part of C++), not an unsigned type, for the same power-distribution reasons I mentioned beforehand. Well, "long long" technically isn't a part of C++. Compilers/runtimes in general can deal with it, but 64-bit long long on 32 bit systems generally means software manipulation, which is significantly slower. But the real problem here is that you're saying "adding 1 more bit to make sure you don't overflow/underflow is silly, you should add 32 bits." It is silly to add one bit, but just extending that to 32 bits is almost as silly -- it's a variation of throwing hardware at the problem, when the problem only exists because you're not using the correct method in the first place. ZorbaTHut posted:Also, saying "if you write it correctly, it always works! " is kind of meaningless, because obviously it'll work if you write it correctly. What I'm getting at here is that unsigned variables make it much easier to introduce subtle unexpected bugs, thereby either reducing the chance that you'll write it correctly or increasing the amount of effort and time it takes to write it correctly (take your pick) while signed variables avoid a small but significant class of errors. What he's saying is that using the correct approach means that your chance of not writing it correctly is decreased. Use signed ints for ints that will always be in a particular range that can be negative, use unsigneds for ints that will always be in a particular nonnegative range, and don't use ints when there's a more appropriate and less error-prone abstraction available to you.
|
# ¿ Jul 3, 2008 08:57 |
|
Entheogen posted:oh ok, i see what you are saying. even though macro is replaced by pre-compiler with whatever it is defined to, if data is a function call it will be evaluated 15 times. Yes, the preprocessor does text substitution only. It's not compiling or optimizing anything.
|
# ¿ Jul 7, 2008 15:49 |
|
Entheogen posted:how exactly does one link statically instead of dynamically in c++? Depends on your build environment. The headers have absolutely nothing to do with how the library is linked. Look at it this way: each translation unit (for all intents and purposes, a .cpp file after the preprocessor is done with it) you compile defines a set of exported symbols, like main, MyCoolFunction, etc. There's also a set of symbols it references that are not defined in that translation unit: strcpy, SomeLibraryFunction, etc. Each translation unit is compiled into an object file, usually .o or .obj. The linker's job is to take several object files (and static libraries, which are just collections of object files, .lib or .a generally), resolve the symbols referenced and defined in them, and cram them all together into an executable where all the symbols reference the correct code/data. When you link against a static library, all the code and data from that library referenced by your program gets copied into the executable. When you link against a dynamic library, the linker generates a little routine that runs before main that loads the dynamic library through the OS and resolves the referenced symbols in that library with the ones in the program. So I guess in a roundabout way, yes, when you link against a .lib, that's static linking, and all the code you use in that .lib file ends up in your executable.
|
# ¿ Jul 17, 2008 18:25 |
|
Avenging Dentist posted:Pointers are very important, since they allow objects to have other-than-lexical scope. If you make an object on the stack in a function and return a reference to it, that object will get destructed when the function returns. It's also necessary for dynamically-sized data. Yes. Pointers are also necessary for referencing objects that may be invalid, since they can be NULL, and references (for any defined behavior) can't be. Also, references can not be reseated to refer to a different object - once they're defined they point at that object forever until they go out of scope. That said: you should use references over pointers whenever feasible. http://www.parashift.com/c++-faq-lite/references.html#faq-8.6 (As an aside, you would probably benefit from reading large portions of the C++ FAQ Lite, as well Scott Meyer's Effective C++) quote:I don't use "design patterns" as such for any of my projects. Granted, a design-pattern nerd will probably look at my code and say "oh well this is a clear example of design pattern X", but I just write code in whatever way I find to be most elegant. The most important part of the Gang of Four Design Patterns book is the prologue, where it says that the purpose of the book is to create a common language for talking about patterns that "naturally occur" in object-oriented programming. In other words, every competent programmer will, at some point, decide that they need something like the Strategy pattern, but instead of describing exactly how they accomplish it in code, they can say "I use something like the Strategy pattern here." Design patterns are NOT a set of idioms for you to put in your programs. I would even advise against specifically referring to the classes that implement things like design patterns by their pattern name (for instance, don't call your classes FooStrategy and BarStrategy). For one thing, it adds little information: the code you're writing should make it pretty obvious that you're using something like Strategy. But the main problem is that it will lead to a tendency to write code that conforms more closely to the Go4 book than to your actual problem. Again, the usefulness of design patterns comes from the fact that it lets programmers talk about solutions to design problems with a common language -- not a starting-off point where you just fill in the details. If you try to do this, you'll end up with patternitis and over-engineer everything about your program. In other words, you'll end up as a Java programmer. quote:God yes. This isn't Java, and it makes no sense to have a class that can't actually be instantiated. Use a namespace if you need to encapsulate all the functions, or just leave them global if you don't care. Again, don't overthink it. The main reasons you use classes are for associating code with the data it operates on, encapsulating that data (implementation details) and hiding it behind the interface, and polymorphism. If you don't need any of these, then the only reason you're putting things in a class is so they're not in the global namespace. Ok, then put them in a namespace. If you don't want clients to be able to call certain functions directly (what you would put private in a class), then put them in the anonymous namespace so they won't be visible outside the file they're defined in. Classes are a tool that C++ programmers have. They're a very powerful tool, but they're by no means the only tool. quote:They do add overhead, in that a function that may throw needs to be compiled such that it can "return" at arbitrary points in its execution. Additionally, exceptions require some form of RTTI (run-time type identification) in order to inspect the exception's type when caught. Yeah, there's definitely overhead involved. The biggest problem is that using exceptions in one place in a program essentially means that the rest of the program has to be using RTTI and have exception-handling code compiled in. But generally when you try to solve a similar problem without exceptions, you end up with a half-assed complicated ugly version of exception handling. Unless you're talking about game development (like real AAA-title game development), real-time trading, or something else that needs to be super-loving-fast and use as little memory as possible, just use exceptions. Putting it in perspective: if 1ms doesn't sound like a lot of time, use exceptions.
|
# ¿ Jul 20, 2008 18:55 |
|
Centipeed posted:I've checked out Bjarne's book on C++. It seems comprehensive. I've also taken a look at Thinking in C++. Accelerated C++: http://www.amazon.com/Accelerated-Practical-Programming-Example-Depth/dp/020170353X
|
# ¿ Jul 20, 2008 18:56 |
|
|
# ¿ Apr 25, 2024 14:03 |
|
Entheogen posted:
You don't even need BOOST_FOREACH for this, just use std::for_each. It'll work for anything that has a T::iterator type (and begin(), end() and operator++ on the iterator), and makes way more sense than using the macro version.
|
# ¿ Jul 21, 2008 08:54 |