-
-
Notifications
You must be signed in to change notification settings - Fork 637
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix cChunkMap issues below with coords below y=0 #5397
base: master
Are you sure you want to change the base?
Conversation
Sorry for the delay in reviewing, I was a bit busy - I'll get round to it tomorrow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good generally. I think it might be slightly better though if we created new functions that do this checking, cWorld.SafeBlockTypeMeta or something - otherwise the behaviour of chunks' GBTM and worlds' GTBM functions will be different which could lead to confusion.
@@ -585,6 +595,11 @@ void cChunkMap::SetBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE | |||
|
|||
bool cChunkMap::GetBlockTypeMeta(Vector3i a_BlockPos, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const | |||
{ | |||
if (!cChunkDef::IsValidHeight(a_BlockPos.y)) | |||
{ | |||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a slight concern here that we might end up with use of uninitialised memory as a consequence of this return - idiomatic use of GBTM does not initialise the arguments, and with an early return they are not initialised here either.
I think we should zero them here for safety.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could be wrong, but I think there are other cases where early return does not initialize the arguments; for example, if !Chunk->IsValid()
. I don't entirely understand when a Chunk would be invalid, but that's another case where the arguments will be left uninitialized. Also, most (all?) C++ compilers should zero the values anyway afaik, since they're enums, although I'm not totally sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, we need to add an initialisation to the invalid chunk case as well. Most C++ compilers do zero-initialise variables, but that is non-standard undefined behaviour which we should not rely on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the modus operandi "If the return value is false
, then the out params are uninitialized" is valid. It should just probably be mentioned in the doxy-comment. All the callsites should be doing if (!GetBlockTypeMeta(...)) { return ...; }
so the uninitialized values don't matter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps, is there some marker that would tell the compilers that ignoring the return value of this function is a bad thing?
Should fix #5395 and some other issues. See discussion in #5220. I noticed that lighting the void on fire (using a flint and steel on the side of bedrock at y=0) crashed the server before this PR, but not after. This should fix most other similar issues.