Jump to content

  • Log In with Google      Sign In   
  • Create Account


We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.

Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


Member Since 09 Dec 1999
Offline Last Active Yesterday, 11:59 PM

#5124791 "Wrapping"? Why is it not called "trimming"?

Posted by SiCrane on 19 January 2014 - 01:22 AM

It is actually guaranteed to behave this way for unsigned types. For signed types, overflow is UB, though on any system you'll encounter today it will probably either wrap around (2's complement) or saturate (most DSPs?).

That's not quite right. Specific behavior depends on language. In C++ with unsigned integer destination types, the result is always the least integer modulo congruent to the source integer modulo 2^n where n is the number of bits in the destination type. For a signed integer type, if the source integer value can be represented by the destination type, the value is unchanged. However, if not the result is implementation defined, not undefined.

C acts a lot like C++, other than weird wording in the standard; however, if the destination is a signed type and the original value cannot be represented in the destination type, the result can be an implementation defined value or an implementation defined signal can be raised.

C# on the other hand, for narrowing conversions that cannot be represented in the destination type, the result depends on whether or not overflow detection is enabled. If so, a narrowing conversion for an integer value that cannot be represented in the destination type will throw a System.OverflowException. If overflow checking isn't on, the result always consists of discarding the most significant bits of the source.

#5124747 "Wrapping"? Why is it not called "trimming"?

Posted by SiCrane on 18 January 2014 - 06:46 PM

Actually, I've rarely heard of an integer conversion to a smaller type as "wrapping". Much more common is referring it to as a "narrowing" conversion.

#5121547 Can I do this with a Window Handle?

Posted by SiCrane on 05 January 2014 - 09:17 PM

The answer is maybe. You can use an HWND as an argument to GetDC() which will give you a device context to the client area of the window, which can be used to render to the client area. However, not every HWND has a client area, and even if there is a client area that doesn't mean that the window won't immediately wipe whatever you drew and draw something else over it as part of its rendering process.

#5121418 ? operator

Posted by SiCrane on 05 January 2014 - 11:07 AM

That's the notation for a nullable type.

#5120834 Sorting (mathematical) vectors in list

Posted by SiCrane on 02 January 2014 - 09:43 PM

The purpose of all this is to decrease a bottleneck I have with quickly searching a grid for the existence of an entity. I decided to insert the integer coordinates of the entities I'm interested in into a sorted list so I can do a binary search on the data (O(log n)) instead of having to traverse it (O(n)). The list has well over a thousand entries, so hope this will be more effective.

In that case you may want to consider a hash container rather than a sorted list.

#5120730 Sorting (mathematical) vectors in list

Posted by SiCrane on 02 January 2014 - 11:34 AM

Yes, that looks right. Note that while this is a valid comparison for the purposes of sorting, it may not be a particularly meaningful sort. In particular when used with floating point numbers, it may not be useful for search.

#5120621 Sorting (mathematical) vectors in list

Posted by SiCrane on 01 January 2014 - 11:10 PM

You can sort vectors with a lexicographic sort. Ex:
template <class T>
inline bool operator<( const Vector2<T>& lhs, const Vector2<T>& rhs )
    if (lhs.x < rhs.x) return true;
    if (lhs.x > rhs.x) return false;
    return lhs.y < rhs.y

#5120412 Cannot override virtual methods

Posted by SiCrane on 31 December 2013 - 09:15 PM

Inside a base class constructor virtual member functions are bound against the base class version. In order to call the derived class version you need to do so outside the scope of the base class constructor.

#5119853 Class inheritance?

Posted by SiCrane on 29 December 2013 - 10:27 AM

Another option is to load the enemy data from a data file. Then the constructor only needs to know the name of the file (or index into an archive, etc.).

#5119216 Problem with gets() and scanf in C.

Posted by SiCrane on 25 December 2013 - 02:51 PM

scanf("%d") tells the program to get the standard input and load what's there as an integer and then leave the rest in the buffer. That means if your input is something like "9\n" then it just grabs the 9 but leaves the \n in the buffer. So when gets() comes along it sees the \n in the buffer and then decides it's done because gets() reads standard input until it sees a \n. One way to handle this is to use gets() to read the line that contains the number into a character array and then use sscanf() to parse that character array. Usual caveats about buffers sizes and error handling with C I/O apply.

#5117181 C++ D3DXVECTOR3 insertion operator

Posted by SiCrane on 15 December 2013 - 04:16 PM

Your code, as posted, works for me on MSVC 2012.
#include <iostream>
#include <d3dx9.h>

struct ModelData {
   int type;
   D3DXVECTOR3 position, size, rotation;
std::ostream& operator<<(std::ostream& os, const D3DXVECTOR3& vector) {
   os << vector.x << 'x' << vector.y << 'x' << vector.z;
   return os;

std::ostream& operator<<(std::ostream& os, const ModelData& data) {
   os << data.type << ' ' << data.position << ' ' << data.rotation << ' ' << data.size << std::endl;
   return os;

int main(int, char **) {
  ModelData m = { 0, D3DXVECTOR3(1, 1, 1), D3DXVECTOR3(2, 2, 2), D3DXVECTOR3(3, 3, 3)};
  std::cout << m;

  return 0;
This produces "0 1x1x1 3x3x3 2x2x2" as output. Try to produce a minimal code example that demonstrates your problem.

#5117031 Unique_ptr and emplace_back.

Posted by SiCrane on 14 December 2013 - 11:52 PM

So, looking at my code, seems like it calls new, then fully constructs the unique_ptr(which wraps the new'd object safely) then internally it forwards that temporary unique_ptr and constructs the internal version using the move constructor, which is why it's safe. Least I think? Maybe I'm wrong there.

That's pretty much what happens here.

Assuming I am correct that means that behavior wise it is essentially not really any different from just calling push_back with the same line, right? Since it would call the move constructor for the unique_ptr in both cases.

That's right.

EDIT: Assuming that assumption is correct, does that mean just passing new Client to the vector would be unsafe? Since if the vector throws the new'd memory would be lost to the void?

It would be unsafe in the general case. However, if the vector's capacity is greater than its size, then you're guaranteed not to have a reallocation for emplace_back(). So if you call reserve() first then you could emplace_back() without the temporary safely.

#5116973 Unique_ptr and emplace_back.

Posted by SiCrane on 14 December 2013 - 06:29 PM

std::unique_ptr's constructor cannot throw an exception (unless templated with a deleter that can throw, but doing so is a violation of the unique_ptr template argument requirements). However, emplace_back() can throw an exception when allocating memory for the vector, so you still have two potential throw points. 


Function calls are sequence points. All side effects of expressions that are used as arguments to that function call must be completed before the function call begins (unless such expressions involve other threads). In this case, that means that the result of the new expression must be known before the call to emplace_back begins. emplace_back() gives the exception guarantee that if an exception is thrown by anything other than a copy constructor, a move constructor, assignment operator or move assignment operator then there are no effects. std::unique_ptr will not throw for any of those unless you do something silly like make your Client's destructor throw. So if there is a memory allocation exception, nothing will happen to the vector and your temporary std::unique_ptr will clean up your new'd pointer as part of its destruction. 

#5116403 Why "double declare" classes? (Lack of better terminology)

Posted by SiCrane on 11 December 2013 - 10:43 PM

Well, most languages have evolved so that you don't actually need to do that. Ex C# has had the var keyword since 3.0 and C++11 introduced the use of the auto keyword to implicitly define a type.

#5113515 What is the reason for making the leading entries all ones in a echelon form?

Posted by SiCrane on 01 December 2013 - 11:41 AM

It comes from the definition of row echelon form: what you get when you've finished the first part of Gaussian elimination. The people saying that the leading terms all need to be one are saying that you aren't really done with that first part until you've gotten the coefficients to one.