|
Jan posted:The compiler most likely optimises the empty constructor call anyway. You're mostly losing terseness and clarity for... no advantage at all.
|
# ? Sep 16, 2010 02:57 |
|
|
# ? Jun 3, 2024 11:50 |
|
Dooey posted:Removing the dustructor doesn't change my performance problems I did say that it wouldn't. About that: your profiler is almost certainly misleading you; line-based profilers are often not terribly precise, because optimization can do terrible things to line tables. You *are* profiling an optimized build, right? I would suggest looking at the assembly and seeing if there's anything fishy going on. Dooey posted:Does having an empty destructor like that actually change anything relative to leaving out the destructor? Yes. Classes with non-trivial copy constructors or non-trivial destructors must be passed and returned indirectly, i.e. by passing a pointer to a temporary. User-declared destructors are automatically non-trivial (*), even if they're defined empty inside the class definition. So passing a Point<float> to a function means always passing it in memory instead of potentially in registers. (*) Note to C++0x pedants: shut up.
|
# ? Sep 16, 2010 02:59 |
|
Dooey posted:The constructors and destructors for Point: code:
|
# ? Sep 16, 2010 04:04 |
|
C99 to C++, what is the best way to convert strict aliasing safe casting? Common code code:
code:
code:
MrMoo fucked around with this message at 04:37 on Sep 16, 2010 |
# ? Sep 16, 2010 04:34 |
|
Similar question on stack overflow, http://stackoverflow.com/questions/346622/opinions-on-type-punning-in-c Looks like these are the only two strict aliasing safe options, the memcpy is shorter and may be optimised out in GCC as it does in C99 usage.
|
# ? Sep 16, 2010 05:38 |
|
Hoo boy. Learning C++. I'm trying to create a Named Pipe Going off some examples, I'm doing something like code:
quote:argument of type "const char *" is incompatible with parameter of type "LPCWSTR" 1) Why the discrepancy between the docs saying I need a LPCTSTR, and VS2010 saying I need a LPCWSTR? 2) Do I seriously need an 11-line function to convert from a std:string to a std::wstring so I can do mywstring.c_str()?
|
# ? Sep 16, 2010 16:35 |
|
epswing posted:Hoo boy. Learning C++. 1) The key difference between LPCTSTR and LPCWSTR is the W, meaning wide char (short * vs char *), because it is encoded in UCS-16 I believe. The simplest solution is to actually switch to the ASCII versions of the API. Unless you really need unicode, then you just need to suffer. You simply need to not define UNICODE before you include windows.h, i.e. code:
litghost fucked around with this message at 16:42 on Sep 16, 2010 |
# ? Sep 16, 2010 16:39 |
|
Thanks litghost. Where should I be doing #undef UNICODE? Does this have anything to do with anything? quote:#error directive: Please use the /MD switch for _AFXDLL builds c:\program files (x86)\microsoft visual studio 10.0\vc\atlmfc\include\afxver_.h 81 3 Also when I hover over CreateNamedPipe in my project I see #define CreateNamedPipe CreateNamedPipeW, and when I hover over the project I'm using as an example, I see #define CreateNamedPipe CreateNamedPipeA. What's the difference, and should I care?
|
# ? Sep 16, 2010 17:07 |
|
epswing posted:Also when I hover over CreateNamedPipe in my project I see #define CreateNamedPipe CreateNamedPipeW, and when I hover over the project I'm using as an example, I see #define CreateNamedPipe CreateNamedPipeA. What's the difference, and should I care?
|
# ? Sep 16, 2010 17:30 |
|
epswing posted:Does this have anything to do with anything? That is a different problem. You need to select the Multithreaded DLL runtime when building against AFX, or at least that is what I glean from the error message (/MD is the flag for the Multithreaded DLL runtime). Make sure the /MD flag is present in your compiler flags. epswing posted:Also when I hover over CreateNamedPipe in my project I see #define CreateNamedPipe CreateNamedPipeW, and when I hover over the project I'm using as an example, I see #define CreateNamedPipe CreateNamedPipeA. What's the difference, and should I care? The above poster is correct, but behind the scenes is the following code: code:
litghost fucked around with this message at 17:42 on Sep 16, 2010 |
# ? Sep 16, 2010 17:39 |
|
Ok, I'm on board, but where should I be doing #undef UNICODE? If I put it at the top of the cpp file which contains CWinApp theApp; (which I assume to be the entry point of the app), or at the top of stdafx.h, I still get quote:Error 1 error C2664: 'CreateNamedPipeW' : cannot convert parameter 1 from 'const char *' to 'LPCWSTR' e: I'd like to know how to figure out which file I need to edit, just as much as I'd like to know which file I need to edit. epswing fucked around with this message at 17:59 on Sep 16, 2010 |
# ? Sep 16, 2010 17:56 |
|
Before you go the route of unnecessarily stripping unicode support from your app, this code should work:code:
|
# ? Sep 16, 2010 18:22 |
|
I love you, RJ. Also, I typically recommend just using the W versions instead of those dumb macros.
|
# ? Sep 16, 2010 18:36 |
|
I'm on the fence about just Getting Things Working followed by worrying about unicode support, versus trying to get over the hump of trying to make unicode work from the get-go. I'd like to try the latter, but it might take too long for me to understand how to do things properly. For example, to create my pipe, now the constructor takes a wstring instead of a string, so when I create the object now it's something like pipe(L"MyPipeName"). Easy enough, but now this means to concat two strings, I can't just do "one" + "two", it needs to be code:
code:
quote:Error 1 error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::wstring' (or there is no acceptable conversion) I feel like I'm sliding into something from which even light cannot escape.
|
# ? Sep 16, 2010 18:37 |
|
std::wcout
|
# ? Sep 16, 2010 18:41 |
|
epswing posted:Ok, I'm on board, but where should I be doing #undef UNICODE? Don't explicitly #undef UNICODE, just change your character set to "Use Multi-Byte Character Set" in your Project Properties > Configuration Properties > General page.
|
# ? Sep 16, 2010 19:07 |
|
epswing posted:I feel like I'm sliding into something from which even light cannot escape. That's totally a fair concern; it's kindof like const-correctness in that it's easy to do the right thing from the start, but if you have a ton of Unicode-incorrect code it's annoying to retroactively fix things. Although I would note that it's always easier to retroactively fix things when you have less code (i.e. right now) than when you have more (i.e. when you get around to fixing your Unicode bugs in five years). The nice thing is that getting things right is pretty easy if the libraries you're using support it properly, and Windows and the STL both do. In the STL, you basically just have to put 'w' before every type that's normally defined in terms of 'char' (strings, streams, etc.). In the Windows API, it's a 'W' suffix, or you can use the unsuffixed name and rely on the macro.
|
# ? Sep 16, 2010 19:30 |
|
epswing posted:Easy enough, but now this means to concat two strings, I can't just do "one" + "two", it needs to be
|
# ? Sep 16, 2010 19:50 |
|
The is one annoying flaw in the C++ wide string stuff, though: The standard exception types only use char-based strings, making them even more limited in usefulness.
|
# ? Sep 16, 2010 20:38 |
|
Plorkyeran posted:You can't do that even with non-wide strings, and return L"\\\\.\\pipe\\" + this->pipeName; works exactly the same as it would with no L and pipeName a std::string. This doesn't sound too bad, actually.
|
# ? Sep 16, 2010 21:53 |
|
C# has these neat IsConnected and IsMessageComplete properties of PipeStreams, making it easy to delimit messages that are larger than BUFFER_SIZE:code:
I've created a named pipe in C++ using CreateNamedPipe, and I'm looping over ReadFile in the same manner. Is there any way I can accomplish the same thing, or do I have to send some kind of control character to indicate the end of one message and the beginning of another? I could use while (bytesRead == BUFFER_SIZE) to indicate there's more data in the message (which of course doesn't work if the message is exactly BUFFER_SIZE). Edit: might as well paste the code so y'all can have a chuckle, right? code:
epswing fucked around with this message at 16:34 on Sep 17, 2010 |
# ? Sep 17, 2010 16:19 |
|
What's a message and how does the .NET class determine what differentiates messages?
|
# ? Sep 17, 2010 16:43 |
|
Mustach posted:What's a message I should have clarified. On the client (sending) side, assuming a buffer size of 16, I want to send a message, and do something with it on the server side. code:
* right here is where my control character(s) would go, to break out of the inner loop Mustach posted:and how does the .NET class determine what differentiates messages? I don't know, but thinking about it now, their PipeStream abstraction must be sending control characters under the hood. epswing fucked around with this message at 16:55 on Sep 17, 2010 |
# ? Sep 17, 2010 16:52 |
|
Let me simplify my question. Say I have two programs connected by a pipe. I wish to send some xml/json/etc data from one program to the other. The receiving program needs to do something with this bundle of data, which I'll call a "message". The receiving program loops over ReadFile, filling a buffer with whatever comes down the pipe. In the case that a message is larger than the buffer, and is split across several calls to ReadFile, how would you (A) accumulate and put together the message (which you need to do before processing it) and (B) differentiate between messages? Am I thinking about this entirely the wrong way?
|
# ? Sep 17, 2010 19:21 |
|
epswing posted:Let me simplify my question. Say I have two programs connected by a pipe. I wish to send some xml/json/etc data from one program to the other. The receiving program needs to do something with this bundle of data, which I'll call a "message". The receiving program loops over ReadFile, filling a buffer with whatever comes down the pipe. For my things, I like to start each message with a message size, so you know how much data you need to accumulate. Since I do games, I don't want to block, I make my sockets or pipes state-machines with states "connecting", "waiting", "partialmessage", "disconnected". Then for each check it goes something like code:
|
# ? Sep 17, 2010 20:42 |
|
epswing posted:how would you (B) differentiate between messages? http://msdn.microsoft.com/en-us/library/aa365467(v=VS.85).aspx posted:If a named pipe is being read in message mode and the next message is longer than the nNumberOfBytesToRead parameter specifies, ReadFile returns FALSE and GetLastError returns ERROR_MORE_DATA. The remainder of the message can be read by a subsequent call to the ReadFile roomforthetuna posted:start each message with a message size Neato, like Content-Length in HTTP. Also, I spin off a thread for reading, which blocks in a loop until there's stuff to read. I think that will work for my purposes.
|
# ? Sep 17, 2010 21:06 |
|
epswing posted:Neato, like Content-Length in HTTP. Having a binary message size header is certainly more efficient and simpler than reading to a delimeter (and easier than HTTP's Content-Length header because with HTTP you still have to read the header itself with delimeters before you can do a big known-size data burst), though data in binary also carries its own can of worms (byte orders if you're not sure you're sticking with one OS/hardware, and it's not good for readability/debugging).
|
# ? Sep 17, 2010 21:39 |
|
And you have to keep in my that whomever is sending the message could be lying about the buffer size.
|
# ? Sep 18, 2010 19:28 |
|
pseudorandom name posted:And you have to keep in my that whomever is sending the message could be lying about the buffer size. vvvv Yeah, I did say you need a way to pre-emptively shut a blocking thread down if it's threaded. If it's not threaded or blocking, per my pseudocode, then a lack of data can't cause a hang. That's not just an issue with false sizes though, it's also an issue with clients crashing, and just as much of a problem either way if you use delimeters (malicious client can stop sending data without sending a delimeter). roomforthetuna fucked around with this message at 21:00 on Sep 18, 2010 |
# ? Sep 18, 2010 19:48 |
|
It might cause your program to hang if it promises to send two bytes but only sends one!!
|
# ? Sep 18, 2010 20:04 |
|
Quick question: where do I learn about templates and their uses? Beyond the typical "let's make a template so a class can work with multiple types of scalars!" example you get at the end of most C++ books, I mean. The "Other recommended books" list in the op lists "C++ Templates: The Complete Guide", is that what I should get or are there better resources? For background, I like to think of myself as a not-completely-incompetent C++ programmer, but I'm clueless when it comes to templates beyond the very basics. I'm currently using a package which makes heavy use of them in ways that make absolutely no sense to me and which might as well be powered by magic and the devil himself. I'd like to fix that.
|
# ? Sep 18, 2010 22:26 |
|
Modern C++ Programming by Alexandrescu does all kinds of cool template gimmicks!!
|
# ? Sep 18, 2010 22:38 |
|
YeOldeButchere posted:Quick question: where do I learn about templates and their uses? Beyond the typical "let's make a template so a class can work with multiple types of scalars!" example you get at the end of most C++ books, I mean. The "Other recommended books" list in the op lists "C++ Templates: The Complete Guide", is that what I should get or are there better resources? That's a great book, C++ Template Metaprogramming is also very good, and if you want to read up on templates and generic programming in practice you can check out The Boost Graph Library, especially if you have an interest in graph theory. Despite the latter being about a specific library, you can learn a lot from its design as it's one of the greatest C++ libraries in existence and also entirely template-based.
|
# ? Sep 18, 2010 22:48 |
|
code:
|
# ? Sep 19, 2010 10:12 |
|
Dooey posted:
No specific C++ experience, but I'm going to go with "no", at least as far as a C++ vector goes. Taking elements out of the middle of a vector requires copying all of the following elements. If you're going to be removing a significant proportion of the elements, you're probably better off copying all of the ones you want to keep to a new vector instead. Even when dealing with a linked-list type structure such as a deque, you should be using an iterator to traverse the list and remove the elements. Jabor fucked around with this message at 10:20 on Sep 19, 2010 |
# ? Sep 19, 2010 10:17 |
|
OK yeah that makes sense. Thanks.
|
# ? Sep 19, 2010 10:20 |
|
Jabor posted:No specific C++ experience, but I'm going to go with "no". Taking elements out of the middle of a vector requires copying all the remaining elements. If you're going to be removing a significant proportion of the elements, you're probably better off copying all of the ones you want to keep to a new vector instead. Or you can walk two iterators through the vector, a writing iterator and a reading iterator that is always >= the writer. Dooey: you might want to use std::remove_if. EdiT: Jabor posted:Even when dealing with a linked-list type structure such as a deque, you should be using an iterator to traverse the list and remove the elements. Just a heads up, a deque is not necessarily a linked list. shrughes fucked around with this message at 10:23 on Sep 19, 2010 |
# ? Sep 19, 2010 10:21 |
|
shrughes posted:Just a heads up, a deque is not necessarily a linked list. As I mentioned, I'm not a C++ guy. Checking the docs again, this is correct. Replace "deque" in my post above with a suitable collection-that-supports-efficient-removals-from-the-middle.
|
# ? Sep 19, 2010 10:44 |
|
Jabor posted:No specific C++ experience, but I'm going to go with "no", at least as far as a C++ vector goes. Taking elements out of the middle of a vector requires copying all of the following elements. If you're going to be removing a significant proportion of the elements, you're probably better off copying all of the ones you want to keep to a new vector instead. You could swap with end() - 1 and then pop_back(), although this does change the order of the elements in the vector.
|
# ? Sep 19, 2010 15:15 |
|
|
# ? Jun 3, 2024 11:50 |
|
Dooey posted:
Replace that for loop with: code:
|
# ? Sep 19, 2010 17:05 |