|
Brecht posted:But, frankly, I don't know why this compiles. My understanding of dynamic_cast is that it works up and down the inheritance hierarchy, but not sideways. Is that wrong? Is it really able to do arbitrary casting regardless of inheritance ancestry? quote:Otherwise, if v points (refers) to a public base class sub-object of the most derived object, and the type of the most derived object has a base class, of type T, that is unambiguous and public, the result is a pointer (an lvalue referring) to the T sub-object of the most derived object.
|
# ? Sep 5, 2011 21:14 |
|
|
# ? Jun 7, 2024 19:32 |
|
Plorkyeran posted:(C++03 §5.2.7.8)
|
# ? Sep 5, 2011 22:01 |
|
roomforthetuna posted:Which is to say, I think Sorry, I had to catch some sleep, but yeah this is basically what I was getting at. In my breakdown of the problem, parts 2 and 4 were identical - and I broke down the regex to try in show that in your solution, you had two different things for those parts.
|
# ? Sep 6, 2011 02:47 |
|
My problem is that I need to pass the type information dynamically. In your examples you are still giving it the type at compile time. Let me show you what works so long as I am referring to the object by it's final type:code:
code:
As far as I can tell, I cannot use dynamic_cast on there with a dynamic type_info argument. Say, I could do dynamic_cast<IStuff> and be fine, but again, as a template argument that is getting sorted out somewhat at compile time. I want to be able to call dynamic_cast<a type_info variable here>, or perhaps more relevant would be dynamic_cast(type_info, pointer).
|
# ? Sep 6, 2011 05:53 |
|
For those specific examples, it's trivial: just template the function (and optionally get a better return type in the process):code:
code:
|
# ? Sep 6, 2011 06:27 |
|
You could never do a proper dynamic_cast to a dynamically-specified type — the result would necessarily be dependently typed, and C++ doesn't do runtime dependent typing. Three more alternatives on top of what Plorkyeran suggested: 1. Add a virtual method whose purpose is to dynamic_cast down to a specific type, and pass a member-function-pointer for that method around instead of a type_info&. Obviously, the standard implementation would return null, and the target class would override that to stop returning null. This has the advantage of being amazingly faster than an actual dynamic_cast, with the disadvantage of bloating your vtables and requiring a new method for every target type. 2. Shadow the type system with some sort of "this is my dynamic type" field. Again, massively faster than dynamic_cast because casts are just equality or range tests, but this time it requires bloating the object instead of the vtable. Generally slightly faster than #1 (test+branch instead of call+test+branch), but doesn't necessarily play well with multiple inheritance. 3. Write non-portable code. dynamic_cast is implemented with a runtime function; you can always call that function yourself. Of course, it's a different function on different platforms, but for almost every UNIX-y platform (including MacOS/iOS) it's a function called __dynamic_cast documented in the Itanium ABI. I don't know know off-hand what the function is in MSVC.
|
# ? Sep 6, 2011 07:03 |
|
Anything that requires I resolve it at compile-time won't work; ultimately this code is serving like a library or runtime for another language--in this case, Python. Fun fact: Boost's Python bindings seem to handle type_info fine, so I can actually call that As() method in Python. Ultimately I can skirt past this problem because it came up while writing some intermediate code, and I think in the final implementation I won't even do those kind of lookups. However, I was generally just frustrated to find that C++ didn't have a direct ability to do this. I have been getting used to generics in other languages so I think they spoiled me.
|
# ? Sep 6, 2011 07:45 |
|
That ABI spec is one incredibly informative link - thanks for that. Do similar documents exist for x86 and x64? By the way Rocko the problem you're describing is the basis for COM's QueryInterface system. Paniolo fucked around with this message at 08:33 on Sep 6, 2011 |
# ? Sep 6, 2011 08:30 |
|
Paniolo posted:By the way Rocko the problem you're describing is the basis for COM's QueryInterface system.
|
# ? Sep 6, 2011 14:08 |
|
From the book on Inline Member Functions: "Inline member functions are compiled differently than other functions, in the executable code, inline functions aren't "called" in the conventional sense. In a process known as inline expansion, the compiler replaces the call to an inline function with the code to the function itself. This means that the overhead needed for a conventional function call isn't necessary for an inline function and can result in improved performance*" "*Because inline functions cause code to increase in size, they can decrease performance on systems that use paging.* So, I'm going to assume that using this technique on a Windows machine is a no-no? Do other operating systems use paging? What is the modern (My book is from 2004) take on this? edit: I'm going to take a partial guess and assume that concerns over performance isn't something to worry over so much these days but I will still like to create high-performance code in the future.
|
# ? Sep 6, 2011 14:26 |
|
Orange_Lazarus posted:From the book on Inline Member Functions: read this, especially 9.3. Pretty much every OS (e: that you're likely to run into) uses paging. The rule of thumb with inline functions is to use them only when the function is extremely short. TasteMyHouse fucked around with this message at 15:01 on Sep 6, 2011 |
# ? Sep 6, 2011 14:55 |
|
Inline is just a suggestion to the compiler anyways, it doesn't have to actually inline it.
|
# ? Sep 6, 2011 15:44 |
|
The compiler is also allowed to inline things that aren't declared as such if link-time inlining is enabled. What usually ends up happening is that whether a function is declared inline or not has far more to do with where it's allowed to be defined (because of template stuff) than any kind of performance concern.
|
# ? Sep 6, 2011 17:32 |
|
Rocko Bonaparte posted:Anything that requires I resolve it at compile-time won't work; ultimately this code is serving like a library or runtime for another language--in this case, Python. Fun fact: Boost's Python bindings seem to handle type_info fine, so I can actually call that As() method in Python.
|
# ? Sep 6, 2011 18:26 |
|
Plorkyeran posted:With boost.python the types which will be exposed to python must be known at compile time (and explicitly exposed). You can trivially construct a mapping from type_info to predicate function for all of the types you're exposing to python at the same time as you're registering them with boost.python.
|
# ? Sep 6, 2011 19:46 |
|
Orange_Lazarus posted:From the book on Inline Member Functions: The relevant section of the C++ FAQ Lite is: quote:There are no simple answers: You have to play with it to see what is best. Do not settle for simplistic answers like, "Never use inline functions" or "Always use inline functions" or "Use inline functions if and only if the function is less than N lines of code." These one-size-fits-all rules may be easy to write down, but they will produce sub-optimal results. There's no easy way to know without profiling it. Generally, trust the compiler, then, when you know you have a problem with certain functions being inlined or certain functions not being inlined (because you profiled it), make a decision one way or another.
|
# ? Sep 6, 2011 19:48 |
|
Paniolo posted:That ABI spec is one incredibly informative link - thanks for that. Do similar documents exist for x86 and x64? Despite its name, the Itanium C++ ABI is actually cross-platform; it's basically a generic set of rules for implementing the runtime features of C++ in terms of whatever the C rules are for a platform. The decision of whether to use it is more about the platform vendor than the underlying architecture. Microsoft had their own ABI before the Itanium ABI was written, so Win32 uses something substantially different; Win64 is closer but still definitely its own thing. But, for example, the MacOS, Linux, and BSD x86/x86-64 platforms all use the Itanium ABI.
|
# ? Sep 6, 2011 23:44 |
|
Thanks for the replies, all were very helpful. I'm going to read the FAQ in it's entirety eventually. Anyways onto my next problem: I'm more than half way through the book and I have to admit my current understanding of a lot of the practice code is muddled. Don't laugh but here's what I think is going on with the code I'm currently working with. code:
I keep telling myself that once I've digested the book, I would move onto creating my own code and learning SDL through trial and error. I'm not sure this is the best strategy anymore. Any suggestions? Sephiroth_IRA fucked around with this message at 02:54 on Sep 7, 2011 |
# ? Sep 7, 2011 02:50 |
|
There's a little bit of confusion of terms here. "Pass-by-reference" can indeed refer to passing a pointer to some data around, but since there are actually special types in C++ called "references" it's probably best to just talk of passing pointers around.
|
# ? Sep 7, 2011 03:07 |
|
Orange_Lazarus posted:
That code didn't have a 'delete' in it at all, which is not good. And two, your comments say "creates an instance of the InventoryItem class" but don't acknowledge that this instance is deleted when it goes out of scope because it's a local variable. I don't know if that's something that you understand or not, but if you're going to overcomment something, remarking on the creation of a thing without mentioning its deletion is a lot like the new/delete divide. In that specific code, since the char array is new'd in the class constructor, it should probably be equally deleted in the destructor. Of which there isn't one. Though really since it's supposed to be a C++ example, it would make more sense for that string to be stored in a std::string rather than a char array, in which case you would need neither to explicitly allocate nor deallocate it. Hopefully the very next thing in the book went on to say "but that was horrible and we should have deleted it, here's how." Your book is teaching you the same horrible "C but with classes" that I learned, and I don't recommend learning that way. Learning C first then proper C++ with standard templates and everything afterwards makes a lot more sense - or skipping C and then going back to learn about that lower-level stuff later might make even more sense. But spludging it together is horrible and took me years to get over.
|
# ? Sep 7, 2011 03:22 |
|
Oh god. That's depressing. Maybe I should just start with a new book. Yeah, after about 750 pages I'm just now learning about classes (with about 3-4 hundred pages left) I've noticed that other books start on classes/oop way earlier. Unless I grab a new text my strategy now is to focus on the new poo poo during my first 2 hours of work (AKA "Chill Time") and then work on the practice problems / creative sections (Starting all the way back at chapter 1) an hour or more each night.
|
# ? Sep 7, 2011 03:45 |
|
roomforthetuna posted:Two comments on your code there - one, generally for every time you use a 'new' you should have a corresponding 'delete' RAII is probably the single most useful thing about C++ and it's best to understand it early. OneEightHundred fucked around with this message at 04:20 on Sep 7, 2011 |
# ? Sep 7, 2011 03:54 |
|
OneEightHundred posted:Or better yet, use auto_ptr/shared_ptr so the app doesn't leak memory every time you forget a delete or miss an exception. RAII is great, but auto_ptr is deprecated and broken - you should typically be using unique_ptr instead.
|
# ? Sep 7, 2011 11:13 |
|
brosmike posted:RAII is great, but auto_ptr is deprecated and broken - you should typically be using unique_ptr instead. This is useful, I didn't know about unique_ptr before. Speaking of, does anyone have a good reference for learning about the new things in C++0x. Other than go learn boost, I guess?
|
# ? Sep 8, 2011 05:23 |
|
Rainbow Pony Deluxe posted:This is useful, I didn't know about unique_ptr before. Speaking of, does anyone have a good reference for learning about the new things in C++0x. Other than go learn boost, I guess? If you want an overview of what new features exist, the Wikipedia article is a good starting point. One of the lead Standard Template Library developers at Microsoft, Stephan T. Lavarej, has a very well-done video series on the STL that covers several (though not all) of the more useful new features. All of the videos are good, but if the new C++0x stuff is what you're most interested in you might want to focus on the smart pointer, rvalue, and algorithm/functor videos. He occasionally delves into implementation details that are specific to Microsoft's STL implementation, but most of the information in the introductory series is fairly platform agnostic (there is also an "advanced" series that is much more MSVC specific). I don't know of any truly great centralized resources on all of the new features, unfortunately - the final spec was only approved less than a month ago. In particular, I don't think there are any good books that go through the new features yet (and as I recall, Stephan commented the same on a few of those videos - he's probably a pretty definitive source on the topic).
|
# ? Sep 8, 2011 06:21 |
|
Why in the name of god does Sun Studio let this code compile?code:
|
# ? Sep 9, 2011 21:25 |
|
My dumb guess would be that it's related to that boost::shared_ptr has an actual operator bool() (rather than operator unspecified-bool-type()) when compiling with suncc and the compiler is doing some bogus implicit conversions. Does it still segfault if you comment out the reset?
|
# ? Sep 9, 2011 21:42 |
|
Plorkyeran posted:My dumb guess would be that it's related to that boost::shared_ptr has an actual operator bool() (rather than operator unspecified-bool-type()) when compiling with suncc and the compiler is doing some bogus implicit conversions. Does it still segfault if you comment out the reset? Ahh, good catch, no it doesn't. We're trying to convert a particularly nasty piece of our code from using raw pointers to smart pointers, because we keep loving up and leaking/double deleting. And by "we're trying to convert" I mean "I'm trying to convert" because I'm a stupid punishment glutton and oh god this sucks
|
# ? Sep 9, 2011 21:45 |
|
C++ macro trickery... I made some logging macros a long time ago that look like:code:
#define SOMEDEBUG( ... ) BEGIN_TRACE_LEVEL(SomeDebug, 3) END_TRACE_LEVEL( __VA_ARGS__ ) and then sprinkle your code with SOMEDEBUG("This happened"); and only if the SomeDebug variable was >= 3 would it print. The intention was though that people could expand on it and do things like: code:
Is there a way to make a macro that is basically #if 0 and #endif? IE: From one macro to the next nothing is compiled / in scope? EDIT:: I posted the question on StackOverflow as well and while I was doing so thought of one way around it... code:
Hughlander fucked around with this message at 15:43 on Sep 10, 2011 |
# ? Sep 10, 2011 14:58 |
|
I saw that question, it's pretty bad to bypass braces and use macros, your IDE is going to go ape. I've gone with the following for long trace sections: code:
code:
http://code.google.com/p/openpgm/source/browse/trunk/openpgm/pgm/include/impl/messages.h The branch hinting works incredibly well here, the mask check is cheap and the code will be moved out of the way so the optimum case runs efficiently. MrMoo fucked around with this message at 17:21 on Sep 10, 2011 |
# ? Sep 10, 2011 17:18 |
|
Any Qt Creator users here? Is there any way to have the autocomplete show the function/attribute's documentation like Visual Studio and Eclipse do? And ideally also the argument's documentation? I googled and googled and I can't find anything about it. Are there any plugins that add this, even if they're commercial? VS has spoiled me rotten, I can't stand having to alt-tab to documentation (or looking it up for that matter) anymore. Primitive Qt Creator autocomplete: Informative VS autocomplete (notice how I not only get the function's documentation, but also its signature):
|
# ? Sep 10, 2011 20:17 |
|
MachinTrucChose posted:Any Qt Creator users here? Well you're comparing a C++ IDE to a C# IDE in those screenshots. Intellisense for Visual C++ is a lot closer to the qt creator screenshot.
|
# ? Sep 11, 2011 06:57 |
|
MrMoo posted:I saw that question, it's pretty bad to bypass braces and use macros, your IDE is going to go ape. DevStudio 2008 with Visual Assist handles it well actually. Much better than the old style I replaced it with. quote:The branch hinting works incredibly well here, the mask check is cheap and the code will be moved out of the way so the optimum case runs efficiently. Not all that well on the PS3 unfortunately. This code base is probably dead when this project ships so I'm just going to fix it for now and not import it into the next project. It was a good experiment but too many issues.
|
# ? Sep 12, 2011 05:24 |
|
I'm writing a program dealing with matrices. I have to create structs that hold the values inside the matrices and the maximum sum across the matrix's row. Then, I have to write functions to multiply 2 matrices and compute this maximum value. I've gotten all the code figured out, except for one small problem. The functions to calculate the maximum sum across a row must be void functions. The paramater is a pointer directing the function to where the values inside of the corresponding matrix begins. My function populates the matrix correctly and stores this value as matrix1.maxRow (or whatever the name of the matrix is). If I print matrix1.maxRow inside of the function, it is correct. However, when I call this function inside my main() function and then try to print matrix1.maxRow, it doesn't output the correct value. I know the function works correctly, because if I change it from a void function to a double, I can set a variable equal to the function when I call it, and print this. However, there must be some way to achieve the same goal using a void function. Can anyone point me in the right direction? edit - Does the fact that this setMaxRow function must be of the void type mean that the only way to have this print correctly is to make this printing part of the function itself? That's the only solution I've been able to come up with. Jort fucked around with this message at 19:47 on Sep 12, 2011 |
# ? Sep 12, 2011 19:39 |
|
It sounds like you're making a copy of the matrix rather than actually passing it by pointer. Can you post the actual signatures of the functions you're using?
|
# ? Sep 12, 2011 19:41 |
|
code:
|
# ? Sep 12, 2011 19:51 |
Jort posted:
This line: matrix44 matrix1 = *m44; allocates a new matrix44 object with auto-storage and copies the matrix pointed to by the function argument into it. If you make any changes to the new matrix1 object created here they won't be reflected in the one passed in, because they are distinct objects, and the new one only exists inside the function.
|
|
# ? Sep 12, 2011 19:59 |
|
if you want something that has the same convenience factor as that (i.e. you don't need to keep using * to get at the matrix), you can use a reference:code:
In fact, if you have the ability to change the function signature, it'd be easier to just pass the matrix by reference (though opinions differ on whether this is actually good practice): code:
|
# ? Sep 12, 2011 20:05 |
|
TasteMyHouse posted:if you want something that has the same convenience factor as that (i.e. you don't need to keep using * to get at the matrix), you can use a reference: This was exactly what I was trying to do. Thanks!
|
# ? Sep 12, 2011 20:14 |
|
|
# ? Jun 7, 2024 19:32 |
|
pseudorandom name posted:IRC is a relatively unpopular and poorly specified protocol, and to my knowledge, nobody has made an IRC library. libpurple is probably the closest thing to an IRC library, but it comes at IRC from an instant messaging perspective, and has to contort IRC to fit that worldview. libircclient is a simple IRC library for C based on function callbacks. The other libraries I'm aware of are usually for languages other than C or C++, like ChatCore. IRC and related protocols are so poorly specified that the "official" CTCP document isn't even adhered to by servers and clients (e.g., nobody sends more than one CTCP message per line). Client authors have to find these things out on their own because documentation of what's in conventional use takes more effort than it should to gather.
|
# ? Sep 12, 2011 20:46 |