You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If some function accepts pointer to z_loaned_type, it's guaranteed that corresponding owned type is not consumed, i.e. the user still have to call z_drop_type on it.
If function accepts pointer to owned type itself, this means that it takes ownership of the object. It should leave the passed object in empty state to avoid double drop or memory leak. Example:
z_owned_config_tconfig;
z_config_new(&config);
z_owned_session_tsession;
z_open(&session, &config);
// config here is consumed, no need to call z_drop_config()z_get(z_loan_session(session), "foo/bar", ...);
z_drop_session(&session);
There is a macro z_move which just takes a pointer to object. I.e. here is the correct way to write the code above:
prototype of "constructor" function (z_config_new) and prototype of function, taking ownership (z_open) are the same: both accepts pointer to z_owned_type_t. Though the semantic is different. z_config_new expects uninitialized memory or object in empty state. It doesn't care about current content of this memory. z_open requires initialized object (in some cases empty state can be allowed too, e.g. for optional parameters)
nothing forces developer to use this z_move macro. But without this macro the code becomes much less clean
Solution
The solution is to introduce two addtional wrapper types z_uninit_type_t and z_moved_type_t and corresponding functions to get these types. Normally no function should accept the pointer to owned object itself because it is ambigious. Instead the constructors should accept pointer to z_unitit_type_t and functions which takes ownership should accept z_moved_type_t.
The example above will look like this in this case:
The library uses concept of
owned
andloaned
types.The owned type
z_owned_type_t
it the object itself. The "owned" structure have the following restrictions:z_drop_type
functionz_null_type
function. Structure in empty state need not to be dropped, though it's safe to call drop on itOperations on the owned structure are performed with pointer to special type
z_loaned_type_t
. This type is returned by functionsIf some function accepts pointer to
z_loaned_type
, it's guaranteed that corresponding owned type is not consumed, i.e. the user still have to callz_drop_type
on it.If function accepts pointer to owned type itself, this means that it takes ownership of the object. It should leave the passed object in empty state to avoid double drop or memory leak. Example:
There is a macro
z_move
which just takes a pointer to object. I.e. here is the correct way to write the code above:This approach have 2 problems:
z_config_new
) and prototype of function, taking ownership (z_open
) are the same: both accepts pointer toz_owned_type_t
. Though the semantic is different.z_config_new
expects uninitialized memory or object in empty state. It doesn't care about current content of this memory.z_open
requires initialized object (in some cases empty state can be allowed too, e.g. for optional parameters)z_move
macro. But without this macro the code becomes much less cleanSolution
The solution is to introduce two addtional wrapper types
z_uninit_type_t
andz_moved_type_t
and corresponding functions to get these types. Normally no function should accept the pointer to owned object itself because it is ambigious. Instead the constructors should accept pointer toz_unitit_type_t
and functions which takes ownership should acceptz_moved_type_t
.The example above will look like this in this case:
or more short with macros
The text was updated successfully, but these errors were encountered: