C++ std::fill and std::fill_n error “error C2679”
Clash Royale CLAN TAG#URR8PPP
C++ std::fill and std::fill_n error “error C2679”
What I'm trying to do:
I'm working in a code which is not mine and I'm trying to refactor this. There I have a struct type object, let's call it MY_STRUCTURE with some parameters inside. In the old version of that code, they are using memset to initialize the structure with 0 in all parameters. So, I've tried to change that memset to a more c++ standard approach which is fill or fill_n.
Also, I should mention... There is not an array, is just an object, so all that I'm trying to do is to initialize that object with 0 everywhere.
The memset approach which is working perfectly fine looks like
this:memset(&MyScruct, 0, sizeof(MyScruct));
What have I tried:
I'm trying to use one of fill and fill_n like this:
std::fill(&MyScruct, &MyScruct+ sizeof(MyScruct), 0);
and also
std::fill_n(&MyScruct, sizeof(MyScruct), 0);
where MyScruct is MY_STRUCT MyScruct
;
MY_STRUCT MyScruct
In both of this cases I'm getting the same error:
error C2679: binary '=' : no operator found which takes a right-hand
operand of type 'const int' (or there is no acceptable conversion)
Do you have any idea why or what's happening here?
fill
fill_n
= 0;
fill
fill_n
It would improve the question to explain what you are trying to achieve
– M.M
Aug 13 at 8:18
What is
MY_STRUCT
?– miradham
Aug 13 at 8:19
MY_STRUCT
It's happening because
fill
is trying to do the equivalent of *&MyScruct = 0;
.– molbdnilo
Aug 13 at 8:24
fill
*&MyScruct = 0;
Try an old good memset.
– ZDF
Aug 13 at 8:24
2 Answers
2
In the original code, memset
will completely ignore the type system and just write bytes to raw memory, trashing whatever was there before (and I have to question whether the "memset approach which is working perfectly fine" actually works fine, or is really undefined).
memset
On the other hand, std::fill
works with the type system, and sets values of the right type. 0
is not a value of the right type (and is not assignable to the type), so you can't "fill" the struct with zeros.
std::fill
0
There is not an array, is just an object
Then you definitely don't want to pass sizeof(MyStruct)
because that says how many objects of the type to "fill". You only have one object, not an array with sizeof(MyStruct)
elements.
sizeof(MyStruct)
sizeof(MyStruct)
sizeof(MyStruct)
is the right argument for memset
because that works with bytes, not objects. You need to tell memset
how many bytes to write. But it's totally wrong for std::fill
and std::fill_n
which count in objects, not bytes (unless by chance sizeof(MyStruct)==1
, but even then it's a bug waiting to happen).
sizeof(MyStruct)
memset
memset
std::fill
std::fill_n
sizeof(MyStruct)==1
I've tried to change that memset to a more c++ standard approach which is fill or fill_n
std::fill
and std::fill_n
are the C++ way to assign new values to a sequence of values, not the C++ version of memset
. The C++ version of memset
is memset
!
std::fill
std::fill_n
memset
memset
memset
If you're not trying to reset the values of the struct, just initialize it, then the correct way is just:
MyStruct s = ;
This is perfectly valid C++ and works in any version, from C++98 up to the latest standard. This is simpler and safer and more readable than using memset
.
memset
"I have to question whether the "memset approach which is working perfectly fine" actually works fine, or is really undefined": could you elaborate on this? It's safe for POD types, right?
– joe_chip
Aug 13 at 9:34
@joe_chip it's safe for trivially-copyable types. All POD types are trivially-copyable. We don't know if the OP's type is a POD though.
– Jonathan Wakely
Aug 13 at 9:52
If the code was written with memset
correctly then there is no reason to change it. fill
is not a substitute for memset
.
memset
fill
memset
In modern C++ it would be bad to design a class to require memset
. However if you are using someone else's class that was designed that way, it is correct to use their class as it was designed.
memset
In modern C++ you would design the class so that value-initialization resets it:
MyScruct = MY_STRUCT;
This code may or may not have the same effect as memset
, depending on the details of MY_STRUCT
.
memset
MY_STRUCT
I've tried already this but is not working because they are not using c++11, I think... they are using c++03.
– Dumitru Vlad
Aug 13 at 8:31
@DumitruVlad i would recommend just not changing the original code.
– M.M
Aug 13 at 8:32
Ok then, thx for the feedback :)
– Dumitru Vlad
Aug 13 at 8:33
how about assigning 0/default values to
MY_STRUCT
members in default constructor? Wouldn't it give same effect as MyScruct = MY_STRUCT;
?– miradham
Aug 13 at 8:37
MY_STRUCT
MyScruct = MY_STRUCT;
@miradham he might not want to change the class definition; and even so, that introduces another possible point of failure (e.g. maybe you forget to set one of the members)
– M.M
Aug 13 at 8:39
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
fill
andfill_n
expect to "fill" an array, as if by doing= 0;
for each element in the array. I am guess you actually want to set each byte of your struct to 0; if so thenfill
andfill_n
are not the right tool– M.M
Aug 13 at 8:18