|
shrughes posted:That code as written is not taking a pointer to that reference parameter. It is assigning the field iColour to the value colour. What is the type of iColour? If it's Colour, then it's getting the value copied in. If it's Colour&, then it is a reference to the object (i.e. a pointer, as far as the CPU and object lifetimes are concerned). Is the insane part the Ball taking the parameter, or the Color taking the parameter? I thought a constructor accepting a reference, and using this to initialize a member reference it keeps, was actually a good way to infer 'this object is non-optional and must be kept alive for the duration of the new object's lifetime'. For example, I usually use constructor reference parameters if some class needs a [something]manager. Usually these will be const, but that isn't always possible. So basically I don't think there's an issue with the Ball part? Of course, taking the address of that reference and using it to initialize a pointer is wrong, because that does muddle up the whole thing.
|
# ? May 7, 2014 21:30 |
|
|
# ? May 26, 2024 10:55 |
|
High Protein posted:I thought a constructor accepting a reference, and using this to initialize a member reference it keeps, was actually a good way to infer 'this object is non-optional and must be kept alive for the duration of the new object's lifetime'. For example, I usually use constructor reference parameters if some class needs a [something]manager. Usually these will be const, but that isn't always possible. So basically I don't think there's an issue with the Ball part? If you're writing classes that take const reference parameters with undocumented lifetime requirements we should probably take things over to the coding horrors thread. e: the class definition is not "documentation"
|
# ? May 7, 2014 21:43 |
|
GrumpyDoctor posted:If you're writing classes that take const reference parameters with undocumented lifetime requirements we should probably take things over to the coding horrors thread. Maybe I/we should be better at explicitly documenting it, but to be honest things like 'const ILogger& logger' or 'ResourceManager& resourceManager' suggest a guarantee of the objects being kept alive, while 'const string& name' does not. Of course deviating from that expectation does require extra documentation. I mean in the color example you obviously expect to not have to keep the color alive.
|
# ? May 7, 2014 21:50 |
|
High Protein posted:Of course, taking the address of that reference and using it to initialize a pointer is wrong, because that does muddle up the whole thing. Whether its saving it as a pointer or a reference is irrelevant since it still requires the object to stay alive. But passing the parameter as a pointer and not a reference at least gives a hint that there's some lifetime issues going on here.
|
# ? May 7, 2014 21:54 |
|
tractor fanatic posted:Whether its saving it as a pointer or a reference is irrelevant since it still requires the object to stay alive. But passing the parameter as a pointer and not a reference at least gives a hint that there's some lifetime issues going on here. True, but when it's passed as a pointer, someone can pass nullptr (which you won't catch until runtime), or someone can actually try to delete it. I guess though you could say that deleting a pointer that was passed in as a param is just an idiotic thing to do and that, if it's what you want, it should be a unique_ptr that's used as a parameter. Of course, when it's not a constructor parameter you have no choice but to use a pointer.
|
# ? May 7, 2014 22:01 |
|
It's alright to pass something around as a T&, with an expectation that the caller is responsible for keeping the referent object alive "forever", if that's all basically obvious from T. For example, if you're writing a server, and T is a class that represents a client session, then (1) you should probably make that class formally non-copyable (or at least not publicly copyable), (2) the session itself should probably be uniquely owned somewhere, and (3) once you've committed to both of those decisions, there's really no harm in passing it around as T& instead of T*, because everybody knows that SomeRandomHelperClass/Function isn't actually going to copy the session. In contrast, if T is some value type that really does get copied all over the place, then taking it by reference is just asking for problems.
|
# ? May 7, 2014 22:24 |
|
This is a problem I was going back and forth on recently. Suppose you write a library with two classes A and B, where each B references an A and requires that it stick around at least as long as the referencing object:C++ code:
Or, you make A a Pimpl-style thin wrapper around something like std::shared_ptr<InternalsOfA>, and then B just copies out the shared_ptr, and then users of the library don't have to worry about anything: B still works if the A goes out of scope or whatever else. I don't know which I prefer. The first aligns more with the "pay for what you use" philosophy, but the second is just nicer to work with at least if the objects involved are fairly large ones and there aren't going to be billions of them all over the place. If the lifetimes of the objects involved aren't performance-critical, it doesn't really make sense to force users of every library to implement their own object dependency system just because they might occasionally have a dependency structure that can be implemented in a super-efficient way. seiken fucked around with this message at 00:19 on May 8, 2014 |
# ? May 8, 2014 00:16 |
|
seiken posted:This is a problem I was going back and forth on recently. Suppose you write a library with two classes A and B, where each B references an A and requires that it stick around at least as long as the referencing object: Because it's a library, would it make sense to have a third class C that owns both A and B objects, and the library user accesses the A and B objects through object C? Basically C becomes a thin wrapper that ensures object A and object B are created and destroyed together. Of course, this may not make sense in the context of your library, though.
|
# ? May 8, 2014 00:25 |
|
contrapants posted:Because it's a library, would it make sense to have a third class C that owns both A and B objects, and the library user accesses the A and B objects through object C? Basically C becomes a thin wrapper that ensures object A and object B are created and destroyed together. I'm not entirely sure what advantage this has over the second solution I discussed. You can ensure A lives long enough without some other class C, and the point is to allow many-to-one relationships, so I don't know what purpose C serves here.
|
# ? May 8, 2014 00:37 |
|
Hey, this is sort of a cross post from the gamedev thread, but I that this part of it would go better in here: Do any of you guys have a good recommendation for a hashtable library for C? I know of GLib, but I don't particularly want to use it because it's a pretty heavy dependency for what I'll be using of it (mostly just data-structures). Failing that, do you guys have any recommendations for implementing my own (especially re: hash functions and size constants)?
|
# ? May 8, 2014 07:22 |
|
Look Around You posted:Do any of you guys have a good recommendation for a hashtable library for C? I know of GLib, but I don't particularly want to use it because it's a pretty heavy dependency for what I'll be using of it (mostly just data-structures). Failing that, do you guys have any recommendations for implementing my own (especially re: hash functions and size constants)? Have you considered using C++ instead?
|
# ? May 8, 2014 07:47 |
|
Deus Rex posted:Have you considered using C++ instead? Yeah, I was planning on it actually, but I don't want to write an RAII wrapper around SDL functions and I can't use C++11 features with SFML because my mac is too old to run OSX v10.8 or 10.9. I'm not comfortable enough with C++ that messing around with it seems appealing unless I'm using the C++11 features that alleviate a lot of the concerns I have when I'm writing it. e: by concerns I mean having to constantly double check a library reference/language FAQ to make sure I'm using the write type/methods or constantly try to compile to make sure my code is being parsed to do what I intended it to do semantically. I'm way more comfortable working in C, I just can't find a good data structure library. Look Around You fucked around with this message at 08:03 on May 8, 2014 |
# ? May 8, 2014 08:00 |
|
Look Around You posted:Hey, this is sort of a cross post from the gamedev thread, but I that this part of it would go better in here: I've never used it in a real project, but I've played with uthash a little, and other than ugliness that comes from C's lack of generics, it was pretty nice.
|
# ? May 8, 2014 08:03 |
|
I'm having trouble understanding why this doesn't work:code:
code:
code:
|
# ? May 8, 2014 17:11 |
|
Paniolo posted:I'm having trouble understanding why this doesn't work: You forgot to make the true check look like decltype(begin(declval<T&>())) for its return type. You're basically passing a type directly to begin otherwise causing it to fail.
|
# ? May 8, 2014 17:58 |
|
seiken posted:I'm not entirely sure what advantage this has over the second solution I discussed. You can ensure A lives long enough without some other class C, and the point is to allow many-to-one relationships, so I don't know what purpose C serves here. My thought was that, if you eventually need multiple objects of class A or B, you can easily add them to class C without having to change the user API. It happens to me a lot due to feature creep. I'm mostly just curious about a non-STL solution. I can't use C++11 at work, and I can't use auto_ptr "in case we move to C++11" because it's deprecated in that standard.
|
# ? May 8, 2014 20:46 |
|
qntm posted:I'm new to C++. I am using a class whose constructor has a reference parameter. I just discovered that inside the constructor, the class actually takes a pointer to this reference parameter and stores that pointer as a member variable. It would be neat to see regions added to C++ in the future because named lifetimes make this a compile-time error in Rust. Rust code:
|
# ? May 8, 2014 22:22 |
|
Look Around You posted:Hey, this is sort of a cross post from the gamedev thread, but I that this part of it would go better in here: Just Use GLib
|
# ? May 9, 2014 01:30 |
|
The compiler is smart enough to prune useless function parameters if I make it obvious that they're not being used, right? I have roughly the following: code:
code:
Paul MaudDib fucked around with this message at 03:54 on May 9, 2014 |
# ? May 9, 2014 03:21 |
|
That's impossible if the function isn't inlined, and not really applicable if it is.
|
# ? May 9, 2014 04:17 |
|
Second-guessing the compiler's register allocation is a trail of tears, IMO. See what the profiler says, I doubt it'll consider the extra caller-saves unused register pressure to be a big issue.
|
# ? May 9, 2014 04:56 |
|
Plorkyeran posted:That's impossible if the function isn't inlined, and not really applicable if it is. Or if it's scoped properly, like a static function.
|
# ? May 9, 2014 04:58 |
|
If the callee doesn't use a parameter, it can immediately drop that value, so that it does not contribute to internal register pressure there. That is a ubiquitous optimization. It will still occupy parameter slots at the point of the call, however, and the callee may still do work unnecessary work computing the argument. If a specific caller knows the exact implementation which will be called, and it can prove that the parameter is unused in that implementation, it can leave the parameter uninitialized and apply DCE to the argument computation. But note that this requires knowing the exact implementation, and being merely semantically equivalent on a high level is not good enough; consider a C++ inline function which is compiled under different optimization settings in different translation units. And again, the parameter will still occupy slots at the point of call, even if those slots are uninitialized/ignored on both sides. Actually eliminating the parameter, so that it does not even temporarily occupy parameter slots, requires being able to prove something about every possible use of the function. More or less, this means that the function must have internal linkage and never have its address taken.
|
# ? May 9, 2014 06:08 |
|
SAHChandler posted:You forgot to make the true check look like decltype(begin(declval<T&>())) for its return type. You're basically passing a type directly to begin otherwise causing it to fail. Hurray for obvious mistakes. Works great now, thanks.
|
# ? May 9, 2014 15:28 |
|
Paul MaudDib posted:
That's undefined behavior if 'validation_data_array' is NULL.
|
# ? May 10, 2014 12:14 |
|
A few questions from a total C++ noob: I'm starting to get comfortable with Python, I use it every day for my sysadmin job, but I've decided to jump into C++ and attempt mediocre game development. I'm going by tutorials on Youtube and snippets here and there from random sites, but it's a massive learning curve. Where can one start? It it smart to jump head first into SDL+OpenGL development? This is where I'm starting. Also, how long does it take to becoming mildly proficient at something like this? And thirdly, is it possible to include compile flags inside my main file, or do I absolutely have no choice but to make a make file?
|
# ? May 12, 2014 01:07 |
|
Megaman posted:A few questions from a total C++ noob: I can't speak confidently to most of those questions, but re: where to start? If you are determined to do game development right away, the Lazyfoo.net tutorials are good, although the kind of code he shows you wouldn't be useful for large projects. This short tutorial series shows you how to set up a state machine, load in resources, do sprite animations, and get a very basic game running, however, you should do some of the lazyfoo tutorials first as the Staniks tutorials expect you to already know SDL basics like creating a window, renderer, etc. If you are baffled by C++ basics, take a look at Accelerated C++, it's a pretty old book but still useful. I just started making games back in february and I don't feel like I'm great at it yet, but I at least feel confident enough to understand most of what people are talking about over in the Game Development Thread. Also, have you considered using Pygame? It's a python wrapper for SDL.
|
# ? May 12, 2014 06:09 |
|
C++ is a very flexible language which allows you to program in a number of different styles--it takes a very long time to become 'proficient'. I wouldn't expect to be making games in C++ any time soon! How long it takes depend a lot on how often you use the language. Compilation flags can't (generally) be incorporated into the source. Many IDEs will allow you to store them in project files, and of course Makefiles work too. For simple programs, even entering them on the command line is fine. If you're using GCC I strongly recommend compiling with -Wall. GCC defaults are rather permissive! I think most of the tutorials you'll find online are rather worthless. I'd just keep referring to the documentation for the STL and any other libraries you'd like to use and keep reading from places like this thread, to blogs, even to StackOverflow and try to get a handle on what the 'best practices' are as you try to complete your project.
|
# ? May 12, 2014 06:12 |
|
Just a possibly dumb question. Why does the following work (http://ideone.com/HKWQGn):C++ code:
z=2 -> my_ref->z=1 z=1 -> my_ref->z=2 b gets destroyed before a. How come I still get valid output when a gets destroyed if the pointer to b got destroyed earlier?
|
# ? May 12, 2014 12:29 |
|
Use-after-free is undefined behavior, not defined-to-be-garbled behavior. It doesn't work, it just doesn't fail in a way that's distinguishable from it working. Valgrind notices that it fails if that helps.
|
# ? May 12, 2014 12:49 |
|
If you did it in debug in Visual C, you should get: z=2 -> my_ref->z=1 z=1 -> my_ref->z=-16843010 as the debug runtime fills freed memory with '0xfe', and '0xfefefefe' is -16843010. In release, it will still be 2, as the C runtime will generally not change freed memory as it is a pointless waste of cycles - it is up to you to make sure memory is initialised after allocation.
|
# ? May 12, 2014 15:19 |
|
You should be using make_unique too btw, instead of newing yourself. Edit: I keep forgetting that is not in C++ 11 but 14...
|
# ? May 12, 2014 15:24 |
|
So I have a C++ book that I've had for a while, and an early chapter covers integer datatypes including signedness vs. unsignedness. It covers what happens when unsigned integers overflow, but then it goes on to say that the equivalent thing happens for signed integers. (i.e. it gives the impression that INT_MAX + 1 will be INT_MIN.) And I know from various other sources that this needn't be the case and that assuming that it is can lead to obscure bugs due to e.g. compiler optimisations that take the opportunity to assume that signed integer overflow won't happen. So I was thinking how would you write a function that you could use when you wanted to add signed integers and reliably get the "wrap around" behaviour that unsigned integer overflow is guaranteed to give. That is, how would you write a function that made the statements about signed integer addition in the book true. Let me check whether this is a solution. Some of it is based on skimming through Stack Overflow pages and other resources. code:
code:
Is there a way to give a name to a specific specialisation of a templated function, such as making signed_int_addition_with_wraparound mean the same thing as signed_integer_addition_with_wraparound<int> (so that you don't have to type the <int> bit everywhere, or even care that it's templated)? (Searching for information on templates is complicated - there is a lot of terminology to keep in mind.) I haven't tested the code I wrote in this post btw, which may be obvious if there are silly syntactical errors or whatever. Hammerite fucked around with this message at 16:23 on May 13, 2014 |
# ? May 12, 2014 18:43 |
|
Hammerite posted:Is there a way to give a name to a specific specialisation of a templated function, such as making signed_int_addition_with_wraparound mean the same thing as signed_integer_addition_with_wraparound<int> (so that you don't have to type the <int> bit everywhere, or even care that it's templated)? (Searching for information on templates is complicated - there is a lot of terminology to keep in mind.) code:
|
# ? May 12, 2014 18:54 |
|
Hammerite posted:Is there a way to give a name to a specific specialisation of a templated function, such as making signed_int_addition_with_wraparound mean the same thing as signed_integer_addition_with_wraparound<int> (so that you don't have to type the <int> bit everywhere, or even care that it's templated)? (Searching for information on templates is complicated - there is a lot of terminology to keep in mind.) You don't have to include the <int> if both arguments actually are ints. Template type arguments are deduced by the compiler for functions and only have to be specified if it's ambiguous.
|
# ? May 12, 2014 19:05 |
|
Megaman posted:Where can one start? It it smart to jump head first into SDL+OpenGL development? This is where I'm starting. Also, how long does it take to becoming mildly proficient at something like this? First off, it'll take a bit to get a handle on C++ development. Compared to something like Python I think C++ tends to be a rather fragmented working environment. There's a ton of legacy baggage in terms of standards, coding styles, and libraries. The C++ specification dates back to '82 and I'd generally describe it as some syntactic sugar on top of C (some stuff isn't, eg generics, but a lot is), which dates all the way back to '72. The actual original standards are pretty basic (targeted at OS-level stuff), so basically everyone implements at least some of the later extensions to some degree, but the availability and strictness of this often varies by compiler and small stuff will frequently break if you use a different compiler. You can definitely use it like Java or Python or another modern high-level language (especially the C++ STL), but you don't have to look at it too hard before the veneer starts peeling off and you're dealing with pointer arithmetic and memory allocation/leaks and other stuff where it's important to have at least a cursory understanding of what's going on at a low level. It's helpful to turn off optimizations when writing/debugging a program, this prevents the compiler from optimizing away variables you want to examine and I think it tends to make errors throw earlier and more helpfully. Debug mode may also help but it has a huge performance impact and sometimes doesn't play nicely with other libraries/extensions. OpenGL is basically the same thing times a billion. The GL standard dates back to the SGI IRIS and OpenGL has been around since 1992, so there's a bunch of slightly different versions out there. In the earlier standards, there was something called the fixed function pipeline that gave you a basic framework to get started, however this was removed in 2009 with the OpenGL 3.1 standard, so a lot of tutorials out on the web are essentially broken (anything involving functions like "glRotate" or "glTranslate" or "glPushMatrix" or "glLoadIdentity"). It's not terribly hard to replicate it if you understand what it did, and you'll be much better off learning the new way, but it's a bit of a barrier to getting started. There's also about a dozen different "helper" libraries to handle the boring plumbing work, everyone uses a slightly different one, all of them are a little different, and half of them haven't been updated in years. I haven't used SDL but it looks like that's what SDL does, so I'd go with that. Apart from the mechanical stuff, it's pretty important to have a grasp on matrix math because computer graphics are basically just a shitload of matrices. Get ready to learn everything you never wanted to know about coordinate space manipulation, you're going to learn all about manipulating them and translating them and nesting them inside other coordinate spaces. It's also probably a good idea to have a basic understanding of the process of rasterizing, which is how you go from a stack of vertex coordinates and transformation/projection matrices to a nice rendered bitmap (the FF pipeline used to do a good chunk of this). This is particularly fragment/vertex shaders (GL Shader Language), which do a lot of the actual work in rasterizing. You should also understand the different components of lighting (ambient/diffuse/specular). Once you have all the rest of that, the secret sauce is mostly just algorithms that let the shaders generate realistic lighting effects in reasonable amounts of time. I'd personally look at Lighthouse3d or someone like that, as well as Nate Robin's demos, which I found to be very straightforward and helpful. It's hard to say how long it will take you to become "mildly proficient" particularly since you're also learning C++ at the same time. Assuming picking up C++ as you go isn't crippling you too bad, maybe 4 hours to get to an OpenGL "hello world", then probably at least 8 solid hours to have a basic working understanding of all the coordinate stuff and the technical stuff? If everything goes right you can display a 2d/3d teapot in no time flat but it'll take a bit to do useful things. When things don't work right, it's pretty easy to get bogged down. Given how much of this is math, shotgun debugging is doomed to failure (even with educated guesses) and you should go look at something working (hello Nate Robin) and see where yours is different. Even after you have the basics there's still tons of fun issues like gimbal lock that'll eventually pop up. Overall it's just a big, big topic and there's lots to learn. Since Python is so great at matrix stuff (see: Numpy) you might even be better off learning OpenGL there and then trying to port what you do over to C++, so at least you know you're fighting C++ syntax instead of bugs in your OpenGL code. I'd start on the simple end of things as much as possible - maybe a 2d game or something like an animated screensaver, and then work your way from there. The deep end is basically as deep as you want to go, game design is something that can take teams of people years to do. If clicking a few of those links made your eyes glaze over, what you want is not OpenGL+SDL but rather a game engine, which will have you working in objects and scripts rather than vertices and shaders. So far I'm a big fan of Unity Engine, which lets you write in C# and Javascript and offers a basic free version to play with. The development environment is great - it's all right there. If you're really wedded to C++, Unreal Engine 4 can be had for the tire-kicking-good price of $20 per month plus 5% of gross revenue if you sell your game (if you just want to play around, pay for a month, download, and cancel). It's definitely more complex and less mature than Unity though. Paul MaudDib fucked around with this message at 01:21 on May 13, 2014 |
# ? May 12, 2014 22:28 |
|
I've been working with C/C++ for a few days now and I'm kinda curious about what compiler I should be using. I started off with MinGW that came stock with Code::Blocks until I found out there were issues and now I'm using MinGW from Sourceforge.
|
# ? May 13, 2014 04:18 |
|
Lemon King posted:I've been working with C/C++ for a few days now and I'm kinda curious about what compiler I should be using. All my experiences with MinGW have ended in tears, and then when I had to use a debugger the tears were of blood. Use MSVC express, drive it from nmake/CMake/gmake/gyp as you choose.
|
# ? May 13, 2014 05:17 |
|
If I'm writing a function that has an array as a parameter, is there any difference betweencode:
code:
|
# ? May 13, 2014 07:05 |
|
|
# ? May 26, 2024 10:55 |
|
In the specific context of a function argument declaration, the second is always compiled as if it were the first. If you're looking for a guideline, the standard always uses the first form in library function declarations. This only applies to the first subscript of the array, so a char[2][2] parameter becomes a pointer to char[2], and not a char **. Gazpacho fucked around with this message at 07:41 on May 13, 2014 |
# ? May 13, 2014 07:36 |