Archived

This topic is now archived and is closed to further replies.

Alternative to memcpy in C++?

This topic is 5083 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Guest Anonymous Poster
maybe because it copies BYTES *duh*

Share this post


Link to post
Share on other sites
If you do want something else (i.e. type safety) use std::copy from <algorithm>.

Enigma

Share this post


Link to post
Share on other sites
std::copy should ALWAYS be prefered to memcpy unless speed is of great important and you are copying POD types

Share this post


Link to post
Share on other sites
quote:
Original post by Puzzler183
Just use memcpy. Seriously, why would you want something else?

Because direct memory manipulation undermines the type system. You should strive to avoid use of memcpy and friends.

Share this post


Link to post
Share on other sites
Hello The C modest god,

I will take issue with what SabreMan said about not using memcpy.

"Because direct memory manipulation undermines the type system."

Type of system is exactly why you should use memcpy and its friends. And what C/C++ program that does anything complex doesn''t use some were direct memory manipulation?

memcpy is perfectly fine to use and should be use over most other methods for the biggest reason of all.
Every C/C++ compiler has a memcpy as part of it standard C library.
And as since it is part of the standard C library it is Cross Platform.

Now it can be true that the implementation of memcpy can vary, it is for the most part fine to use and should get the same results no matter what type of system your on.

Now if you want to get a little better performance then there are memcpy like functions that use MMX or other instruction sets to achieve greater speed.

Lord Bart

Share this post


Link to post
Share on other sites
Write copy constructors for your classes and use std::copy. It will copy the data correctly instead of just doing a bitwise copy. This is partly what SabreMan means by not undermining the type system.

If you have POD types that are no more than C-style structures then std::copy will be doing what memcpy does anyway.

[edited by - petewood on February 16, 2004 9:46:37 AM]

Share this post


Link to post
Share on other sites
quote:
Type of system is exactly why you should use memcpy and its friends. And what C/C++ program that does anything complex doesn''t use some were direct memory manipulation?


He said "type system", not "type of system".

Share this post


Link to post
Share on other sites
Opps,
Ok I see my misunderstanding, my mistake, sorry SabreMan.

type system (type safetly(checking) system) vs type of system (implementation on a system), I inserted "of" when reading it.

Anyway be very careful of the std::copy method.
Remember std::copy must work for all std container classes and as such must loop trough all elements.

I believe it breaks down into a loop of assignments which is great when dealing with classes/structs, which is good and has type saftly in it.

But if your just going to copy memory around (ie texture, array data, etc) memcpy is going to do it faster then the looping assignment of each data element.

With memcpy you loose type safety but gain speed, and since the programmer is god to the program he should know when to use ethier method and understand the good and the bad of his choice.

Lord Bart


[edited by - lord bart on February 16, 2004 10:27:10 AM]

Share this post


Link to post
Share on other sites
AFAIK there''s no reason that std::copy with pointers to primitives (at the very least) cannot itself call memcpy as a specialization.

Share this post


Link to post
Share on other sites
if you''re looking for speed using asm.

and if you''re uberleet reinvent-the-wheel type, write it in asm, and then implement the type safety that std::copy includes...that''s what i did...ugh...nightmares for about two years....

Share this post


Link to post
Share on other sites
quote:
Original post by Lord Bart
With memcpy you loose type safety but gain speed


The first half is right the second half isn't necessarily right.

[edited by - petewood on February 16, 2004 11:15:29 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by DrPizza
AFAIK there''s no reason that std::copy with pointers to primitives (at the very least) cannot itself call memcpy as a specialization.



That is the problem, specialization it can''t!
std:copy does not have the info needed in order to determine if it can specialize to a memcpy. It is a templated function and is made as generic as possible to work with all std container classes and arrary of classes/structures or primitives.
How is it to know it was passed only primitives?
So the only hope it has to work with all things passed to it is to do a loop with assignment on each element.

Lord Bart

Share this post


Link to post
Share on other sites
quote:
Original post by Lord Bart
That is the problem, specialization it can''t!


Yes it can, using template specialization. If you want proof, try compiling an example program under gcc. You''ll find that memcpy and std::copy run at exactly the same speed (at least for floats, I didn''t try it on anything else).

Enigma

Share this post


Link to post
Share on other sites
quote:
Original post by Lord Bart
std:copy does not have the info needed in order to determine if it can specialize to a memcpy.

The compiler has the information, and the Standard Library implementer can use that information to create specialisations of memcpy.
quote:

It is a templated function and is made as generic as possible to work with all std container classes and arrary of classes/structures or primitives.
How is it to know it was passed only primitives?

I don''t want the comedic value of your posts to be completely removed, but perhaps come back when you''ve learned about template specialisation.

Share this post


Link to post
Share on other sites
quote:
Original post by Cipher3D
and if you''re uberleet reinvent-the-wheel type, write it in asm, and then implement the type safety that std::copy includes

What do you mean `implement the type safety''? If you are talking about laborious manual adherence to a set of conventions, then that is not what is usually meant by type-safety, as its only as certain as the assurance that the convention is always followed. In turn, an assurance that the convention is always followed is only as certain as the mechanism used to ensure that the convention is always followed. See the problem? For this to actually work, you have to use asm to implement a compiler for a language which is type-safe, and then write programs in that language, in which case you are not `writing it in asm''.

If you''re going to make such an argument, you may aswell just use memcpy and invent a convention that you never use it in a manner which violates type-safety. But then you need that assurance. This is what I mean by `undermines the type-system''. I''m not saying you will necessarily violate the type-system, I am saying you can''t be sure your programs are type-safe, since you''re disabling the assured mechanisms for reporting violations.

Share this post


Link to post
Share on other sites
quote:
Original post by Lord Bart
That is the problem, specialization it can''t!

You are wrong.

quote:
std:copy does not have the info needed in order to determine if it can specialize to a memcpy.

Of course it does.

quote:
It is a templated function and is made as generic as possible to work with all std container classes and arrary of classes/structures or primitives.

It is precisely through being a function template that it knows enough.

quote:
How is it to know it was passed only primitives?

Because it can see the types being used. It can see, for example, that the input range is defined by pointers to primitives and likewise the output range.

quote:

So the only hope it has to work with all things passed to it is to do a loop with assignment on each element.

Be quiet.

Share this post


Link to post
Share on other sites
Hello SabreMan,

I know about template specialization, but then that is a hassel unto it self.
Yes you can go right ahead and create your own specialization of copy for floats/ints (primitives) but then it is not part of the std template copy.
I haven’t every seen a std::copy template specialization for primitives, maybe there is one, but on the systems I seen std::copy on there is none.
It is up to the programmer to do it.

I don''t realy use gcc (at work it is DEC,SUN and MS compilers, though we been trying to push for use of gcc).
If the gcc compiler can correctly make a template specialization to use memcpy for primitives, well that is another reason to ask agian we start to use it.

Now that brings up porting, depending on how your compiler creates templates you might have to do some extra work to make sure your use the specialization and not the std::copy. (DEC compiler is real bad about template instantiations)

So I guess if not using gcc compiler, start to use it , otherwise loop with assignment of each element would be what you get unless your compiler can do what gcc can.
That is why I said be careful of std::copy.
Or create your own specialization copy for that primitive.

Lord Bart

Share this post


Link to post
Share on other sites
quote:
Original post by DrPizza
quote:
Original post by Lord Bart
That is the problem, specialization it can't!

You are wrong.

quote:
std:copy does not have the info needed in order to determine if it can specialize to a memcpy.

Of course it does.

quote:
It is a templated function and is made as generic as possible to work with all std container classes and arrary of classes/structures or primitives.

It is precisely through being a function template that it knows enough.

quote:
How is it to know it was passed only primitives?

Because it can see the types being used. It can see, for example, that the input range is defined by pointers to primitives and likewise the output range.

quote:

So the only hope it has to work with all things passed to it is to do a loop with assignment on each element.

Be quiet.




Hello DrPizza,

I never said it could not be specialized, I guess what I should have said is this.
The std::copy in algorithm does not have specialization templates for primatives.

Yes I poorly worded post for your other points and you are correct, and I agree .

I was trying to say is if you just included algorithm and use the copy that is in it you would only get the std:copy that does loop and assignments. Unless your using gcc, which looks like it can create the specialization usinf memcpy automatically.

So unless your compiler is real good(gcc seems to be) or you create your own specialization template for the primitive you want, you should get the loop and assignment std::copy if you include algorithm, right?

Lord Bart


[edited by - lord bart on February 16, 2004 1:07:31 PM]

Share this post


Link to post
Share on other sites
It''s not up to the compiler; it''s up to the library implementation.

g++''s implementation uses memmove() if it can, though it is actually wrong to do this. std::copy() is allowed to clobber things in overlapping ranges; there''s std::copy_backward() to deal with overlapping ranges -- that should use memmove().

Share this post


Link to post
Share on other sites
quote:
Original post by SabreMan
The compiler has the information, and the Standard Library implementer can use that information to create specialisations of memcpy.
I wonder...

That works alright for primitives, but what about PODs? AFAIK, there is no way for a regular programmer to determine at compile-time if a class has a non-trivial copy-constructor, but the compiler can make this kind of deduction. Is a Standard Library implementation allowed to make use of internal info given by the compiler to transform a std::copy(some_pod) into a mem_cpy?

Or perhaps, are there compilers smart enough to recognize a for loop that copies every member of every object one by one (if the copy constructor is inlined in the std::copy), and turn that into a mem_cpy?

Cédric

Share this post


Link to post
Share on other sites