Jump to content

  • Log In with Google      Sign In   
  • Create Account

Codarki

Member Since 17 Feb 2004
Offline Last Active Sep 13 2013 07:22 PM

#4961248 How to I pass a variable over to this?

Posted by Codarki on 20 July 2012 - 03:38 AM

The documentation says that 2nd parameter, the void pointer, is application defined value passed to the enum callback.

Try passing a pointer to a struct when you call the enum function, something like:

struct JoysticEnumParams
{
IDirectInputDevice8* context;
IDirectInput8 *DInput;
};



#4960876 Does any interest in the Go language still exist?

Posted by Codarki on 19 July 2012 - 04:23 AM

... operator overloading is a nightmare when reading code, even more than macros:

In general, I have to admit that I’m a little bit scared of language features that hide things. When you see the code
i = j * 5;

… in C you know, at least, that j is being multiplied by five and the results stored in i.
But if you see that same snippet of code in C++, you don’t know anything. Nothing.


If i = j * 5 does something unexpected in C++, that programmer should be fired.

The only way to know what’s really happening in C++ is to find out what types i and j are, something which might be declared somewhere altogether else. That’s because j might be of a type that has operator* overloaded and it does something terribly witty when you try to multiply it. And i might be of a type that has operator= overloaded, and the types might not be compatible so an automatic type coercion function might end up being called

The types are int. Most likely the type information is right next to the expression. If the type of j is not int, and you want to multiply it with 5, then you overload an operator. If the type of i is not int, and it must be assignable from int (or whatever type the j is), then assignment operator must be overloaded. Also, implicit conversions are very commonly avoided.

Now whatever 'witty' C++ example you can imagine (which doesn't do something unexpected, like logging the result over a netword), try to think how you would do the same functionality without operator overloading.

And the only way to find out is not only to check the type of the variables, but to find the code that implements that type, and God help you if there’s inheritance somewhere, because now you have to traipse all the way up the class hierarchy all by yourself trying to find where that code really is, and if there’s polymorphism somewhere, you’re really in trouble because it’s not enough to know what type i and j are declared, you have to know what type they are right now, which might involve inspecting an arbitrary amount of code and you can never really be sure if you’ve looked everywhere thanks to the halting problem (phew!).

Public interface for the types should be enough, no need to check the implementation code.
I'd say if there is inheritance, and overloaded operators for derived and base classes, the design might be shaky.
If you need to know the real derived type of polymorphic variable, you are violating liskov substitution principle and abusing inheritance.

Sure, you can abuse everything in C++ and say 'see the language is bad', you can abuse regular functions by naming them all 'Fred_X' with a number. IMO that doesn't warrant a language that keeps you in safe-jacket. Bad programmers should be fired, and nobody (hopefully) does intentionally cryptic code.

Usually overloaded operators contain the most simple and bugfree code. Using them provides very simple syntax. If they are the cause of unexpected effects or source of bugs, then whoever wrote them is at blame (and should be fired).


#4960861 Is using std::move() necessary?

Posted by Codarki on 19 July 2012 - 03:24 AM

Not only never necessary, but a bad idea on function return (it may inhibit copy elision / RVO)

Seems like you're right.

See also "Moving from lvalues" and "Moving out of functions" here:
http://stackoverflow...11540204/859774

Very good explanation.

return C;
return Matrix©;
These should call the copy constructor (in debug build with all optimizations off)


Ah this was wrong. C++ standard has special rule:


When the criteria for elision of a copy operation are met or would be met save for the fact that the source object is a function parameter, and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue. If overload resolution fails, or if the type of the first parameter of the selected constructor is not an rvalue reference to the object’s type (possibly cv-qualified), overload resolution is performed again, considering the object as an lvalue. [ Note: This two-stage overload resolution must be performed regardless of whether copy elision will occur. It determines the constructor to be called if elision is not performed, and the selected constructor must be accessible even if the call is elided.


This means it will first try to move, and then copy. I wonder if copy constructor has side effects, it might bite someone.


#4960854 Is using std::move() necessary?

Posted by Codarki on 19 July 2012 - 03:07 AM

I'm assuming you have tested this in debug build. I also assume when you say move operator, you mean move assignment operator.

I hope someone will correct me for any mistakes.

Matrix Multiply(const Matrix &A, const Matrix &B)
This will return a temporary copy of a Matrix.

return std::move(C);
return static_cast<Matrix&&>(C);
return Matrix(static_cast<Matrix&&>(C));
Each of these should cast C to rvalue reference (an unnamed temporary) and call the move constructor of Matrix class, and return that instance.

return C;
return Matrix(C);
These should call the copy constructor (in debug build with all optimizations off). See Matt-D's reply below for correction.

Matrix result = Multiply(a, b);
This should call the default constructor, and then move assignment operator with the returned temporary.

Matrix result(Multiply(a, b));
This should call the move constructor with the returned temporary.

In release build all of these should optimize to basically nothing.

edit: Edit in bold.


#4958405 Memory Leak?

Posted by Codarki on 12 July 2012 - 08:16 AM

That can be done more easily

void particleManager::removeEmitter(int emitterNum)
{
    emitters.erase(emitters.begin() + emitterNum);
}

void particleManager::removeEmitter(Emitter *which)
{
    std::vector<Emitter*>::iterator Iter = std::find(emitters.begin(), emitters.end(), which);
    emitters.erase(Iter);
}



#4958326 C++ As First Language

Posted by Codarki on 12 July 2012 - 03:35 AM

While Stroustrup writes very good books, I would never recommend one of his books to a beginning programmer. He usually assumes you already know how to program (in any language) and builds upon this knowledge.

Overall picture I got from the description, excert, and couple of reviews is, that this book is aimed at non-programmers and using modern C++ as the language to teach different aspects of programming. I haven't read it so maybe I'm wrong.

Also this book seems to focus on "classic" C++. It uses some things that are outdated by today's standards and has actually no C++11 content.

Not all C++11 content is aimed at beginners. I'm willing to bet there is heavy use RAII and other best practices.

This book is outdated and not suitable for beginning programmers.

This is published at 2008. Many other suggested books here are from 2000 or so. Can you provide better alternative, which is recent enough to use modern techniques, and aimed at beginners?


#4958303 C++ As First Language

Posted by Codarki on 12 July 2012 - 02:33 AM

So what I really want from you is to tell me which language you prefer most and a good introductory book with it. I will check all the books reviews and see what is better for me.

I prefer C++ and this book looks recent and decent enough:
Programming: Principles and Practice Using C++ by Bjarne Stroustrup http://www.amazon.com/dp/0321543726/?tag=stackoverfl08-20

Also all the best practices and intermediate books from (the beginner books are published around 2000 and might not be that good):
http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list


#4956272 differnt types in c++ map

Posted by Codarki on 06 July 2012 - 03:50 AM

I'm still unsure what you want to do and what is the problem. You are modifying and storing the results back in pData.

Or do you want to return the result some other way? If so, I would just directly create an object and set all the new instances to it, without any type erasure. If you want to erase the concrete type (and treat it through some base), then I have a feeling you'll have to figure out the real type afterwards anyway. You might want to think if you can write generic templates for some of that.


#4956249 Programming Techniques

Posted by Codarki on 06 July 2012 - 02:07 AM

I don't see anything major wrong. You are doing procedural programming, which is fine. I have only couple suggestions (nitpicking really)

- Why not change void EventHandle(int &quit, SDL_Event &event) to int HandleEvent(SDL_Event &event)
- Rename Game() to RunGame()
- Try to be consistent in naming local variables (quit, IMAGE, Texture)
- Return 0 instead of NULL in LoadTexture()
- Declare local variables as late as possible
- Drop the typedef from struct declaration (just struct Screen {...}; )


#4953894 Object oriented programming issue

Posted by Codarki on 29 June 2012 - 03:05 AM

		template <class DATA_TYPE,class INT_TYPE>
		inline Matrix<DATA_TYPE,INT_TYPE> operator *(const Matrix<DATA_TYPE,INT_TYPE>& A,const Matrix<DATA_TYPE,INT_TYPE>& B)
		{
			 Matrix<DATA_TYPE,INT_TYPE> C;
			 Multiply<DATA_TYPE,INT_TYPE>(A,B,C);
			 return C;
		}

Using Multiply() like that might make it more difficult for compiler to perform return value optimization. Why not just return Multiply(A, B);

For operators which are commutative, you can easily use the resource from rvalue reference since it isn't const and it will get thrown away anyway (most likely a temporary is passed in):
template <class DATA_TYPE,class INT_TYPE>
inline Matrix<DATA_TYPE,INT_TYPE> operator +(Matrix<DATA_TYPE,INT_TYPE>&& A, const Matrix<DATA_TYPE,INT_TYPE>& B)
{
    A += B;
    return A;
}
template <class DATA_TYPE,class INT_TYPE>
inline Matrix<DATA_TYPE,INT_TYPE> operator +(const Matrix<DATA_TYPE,INT_TYPE>& A, Matrix<DATA_TYPE,INT_TYPE>&& B)
{
    B += A;
    return B;
}



#4953884 std::vector vs std::unique_ptr

Posted by Codarki on 29 June 2012 - 02:21 AM

I tested with a function that defined a local std::vector, initialized it, and then returned it. Initializing a variable with the result of this function did indeed reference the same memory area, which means there was an implicit move. I wonder how that works (though it did what I wanted).

First, initializing a variable with the result of a function calls the move constructor, which std::vector has.
Second, if the object doesn't have move constructor, RVO (return value optimization) is probably performed by the compiler.


#4904232 Why use non-member functions?

Posted by Codarki on 19 January 2012 - 04:25 AM

So you guys would suggest to implement all functions of the Vector2D class as non-member ones?
This seems very odd to me Posted Image (I'm from the Java/C# section)

Implement as non-member function if it's possible. ADL is great.

The class Directory contains static methodes for managing directories such as removing or creating one.
It's supposed to be a static class, but I'll just implement those functions in a namespace.

I tend to use static methodes, because if I use a lot of namespaces the names tend to get quite ugly and long:

core::math::dot(v1, v2);
core::filesystem::remove("dir");


If v1 and v2 are in core::math namespace, you can rely on the ADL and just call:
dot(v1, v2);

How Non-Member Functions Improve Encapsulation: http://drdobbs.com/184401197


#4880100 Question about Managers

Posted by Codarki on 03 November 2011 - 06:32 AM

... There is nothing wrong with any of these designs, they all work, they all get the task done, and they all make sense. It is all personal preference and people's opinion's when it comes to things like this. Just my 2 cents.

That sounds a bit generalization for me, and I disagree. Generally there is a lot wrong in the design where singletons are used, they do get the job done while being fragile to bugs, and confuse the general solution to a mess. I'd even go further and say it is not just a personal preference but among best known practices to avoid them.

That being said, occasionally they are the best solution, usually for some low-level stuff, rarely for anything high-level.

IMO, this singleton discussion has nothing to do with the discussion about naming of managers (if you ignore those who makes singleton managers).


#4877979 If you could make any game you wanted...

Posted by Codarki on 28 October 2011 - 02:21 PM

MMO of the Earth. Hybrid of Civilization, Sim City and The Sims. With textures from NASA to build on. Add to it all the world-wide issues in the history, economies and what not.

Part 2 would be MMO of universe. Realtime travel, so you'd have to wait a while to get to next star.


#4877905 [RESOLVED]World of Warcraft Image Effect (Spell Cooldown) With Source Code!

Posted by Codarki on 28 October 2011 - 10:47 AM

Think of it as black and white mask for the image. Then create a triangle-fan geometry (minimum of 4 triangles or so) where each outer vertex is weighted linearly, then just rotate with time. The actual triangles can be a lot bigger than the rendertarget.

Or you could calculate angle for each pixel, and shade accordingly.




PARTNERS