[C++] Got rid of memset's in constructors#5938
Conversation
now POD-typed arrays are zero-initialized and class-typed arrays are default-initialized
|
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed (or fixed any issues), please reply here with What to do if you already signed the CLAIndividual signers
Corporate signers
ℹ️ Googlers: Go here for more info. |
| { | ||
| (void)padding0__; | ||
| (void)padding1__; | ||
| (void)padding2__; |
There was a problem hiding this comment.
Do we still need these void casts?
There was a problem hiding this comment.
unfortunately, yes
otherwise, compiler (clang 10.0) says something like
In file included from flatbuffers/tests/test.cpp:39:
flatbuffers/build/tests/arrays_test_generated.h:71:10: error: private field 'padding0__' is not used [-Werror,-Wunused-private-field]
int8_t padding0__; int32_t padding1__;
There was a problem hiding this comment.
Can we make a FLATBUFFERS_UNUSED() macro or something to better give intent to why we are using (void)?
|
@googlebot I signed it! |
|
CLAs look good, thanks! ℹ️ Googlers: Go here for more info. |
src/idl_gen_cpp.cpp
Outdated
| // for each object in array it: | ||
| // * sets it as zeros for POD types (integral, floating point, etc) | ||
| // * calls default constructor for classes/structs | ||
| init_list += field_name + "()"; |
There was a problem hiding this comment.
I would move init_list += field_name out of the conditional, and just have the "()" : "(0)" part in a ternary conditional.
There was a problem hiding this comment.
ok, i'll move field_name out
but it seems like if-else construction allows this case-specific comment to be more readable than in ternary conditional, what do you think?
init_list += (IsStruct(field->value.type) || IsArray(field->value.type))
// this is either default initialization of struct
// or
// implicit initialization of array
// for each object in array it:
// * sets it as zeros for POD types (integral, floating point, etc)
// * calls default constructor for classes/structs
? "()"
: "(0)";versus
if (IsStruct(field->value.type) || IsArray(field->value.type)) {
// this is either default initialization of struct
// or
// implicit initialization of array
// for each object in array it:
// * sets it as zeros for POD types (integral, floating point, etc)
// * calls default constructor for classes/structs
init_list += "()";
} else {
init_list += "(0)";
}There was a problem hiding this comment.
Either is fine with me, with a slight preference for the ternary.
| { | ||
| (void)padding0__; | ||
| (void)padding1__; | ||
| (void)padding2__; |
There was a problem hiding this comment.
Can we make a FLATBUFFERS_UNUSED() macro or something to better give intent to why we are using (void)?
|
Can anybody help me with this Visual Studio build errors? It looks like Visual Studio just wants to tell, that behaviour in this place changed from incorrect to correct (link). But due to warning-as-error setting build is failing. Maybe I can somehow suppress this particular warning? https://ci.appveyor.com/project/google-admin/flatbuffers/builds/33204251/job/d535rfh8x87kyv1n |
|
@bakinovsky-m yes, sounds like we can disable that warning: https://docs.microsoft.com/en-us/previous-versions/1ywe7hcy(v=vs.140)?redirectedfrom=MSDN Sadly, that would mean this at the start of a generated code file: And this at the end: Though frankly, I'd also be ok with just sticking this in As for |
|
Another possible solution: struct Foo {
int arr[10];
#ifdef _MSC_VER
__pragma(warning(disable : 4351)); // C4351: new behavior: elements of array 'array' will be default initialized
#endif
Foo() : arr()
{}
}; |
|
@vglavnyy yeah, but having that in each and every struct is a bit cluttered to read.. |
|
Also, this is a warning given by VS2013, and the description says that this constructor didn't always cause zero-init in previous versions.. but we also still compile for VS2010! So in theory, it could not work there, and not give us zero-init. I guess our unit-test will catch that if that is case? Like I said, I'd be fine to do it globally in |
|
The CI fail you just got is |
|
Ok, awesome, thanks! |
* [C++] removed array's memsets from struct parametrized constructor now POD-typed arrays are zero-initialized and class-typed arrays are default-initialized * [C++] memset -> zero/default initialization in default constructor * [C++] Struct-type and array default initialization * [C++] Newly generated tests * [C++] forgotten test * [C++] curly brace by code style * [C++] test if memory is 0's after placement new * [C++] memory leak fix * [C++] simplifying and non-dynamic memory in test * [C++] code cleanup * [C++] disable old-compiler warning * [C++] windows build fix (try) * [C++] debug-new win build fix
* [C++] removed array's memsets from struct parametrized constructor now POD-typed arrays are zero-initialized and class-typed arrays are default-initialized * [C++] memset -> zero/default initialization in default constructor * [C++] Struct-type and array default initialization * [C++] Newly generated tests * [C++] forgotten test * [C++] curly brace by code style * [C++] test if memory is 0's after placement new * [C++] memory leak fix * [C++] simplifying and non-dynamic memory in test * [C++] code cleanup * [C++] disable old-compiler warning * [C++] windows build fix (try) * [C++] debug-new win build fix
Fixes #5930
There was a std::memset's in constructors of structs. GCC 10.1 failed to compile arrays_test_generated.h because of those memsets on array of non-trivial type NestedStruct
In this new code: