Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions UPGRADING.INTERNALS
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ PHP 8.6 INTERNALS UPGRADE NOTES
zend_fci_consumed_arg(), which allows moving a selected callback argument
instead of copying it in zend_call_function(). Currently only a single
consumed argument is supported.
. Added ZEND_CONTAINER_OF().

========================
2. Build system changes
Expand Down
4 changes: 2 additions & 2 deletions Zend/Optimizer/zend_optimizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ static bool zend_optimizer_ignore_class(zval *ce_zv, const zend_string *filename
if (CG(compiler_options) & ZEND_COMPILE_WITH_FILE_CACHE) {
return true;
}
const Bucket *ce_bucket = (const Bucket*)((uintptr_t)ce_zv - offsetof(Bucket, val));
const Bucket *ce_bucket = ZEND_CONTAINER_OF(ce_zv, Bucket, val);
size_t offset = ce_bucket - EG(class_table)->arData;
if (offset < EG(persistent_classes_count)) {
return false;
Expand All @@ -801,7 +801,7 @@ static bool zend_optimizer_ignore_function(zval *fbc_zv, const zend_string *file
if (CG(compiler_options) & ZEND_COMPILE_WITH_FILE_CACHE) {
return true;
}
const Bucket *fbc_bucket = (const Bucket*)((uintptr_t)fbc_zv - offsetof(Bucket, val));
const Bucket *fbc_bucket = ZEND_CONTAINER_OF(fbc_zv, Bucket, val);
size_t offset = fbc_bucket - EG(function_table)->arData;
if (offset < EG(persistent_functions_count)) {
return false;
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_closures.c
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@ static void zend_create_closure_ex(zval *res, zend_function *func, zend_class_en
/* wrap internal function handler to avoid memory leak */
if (UNEXPECTED(closure->func.internal_function.handler == zend_closure_internal_handler)) {
/* avoid infinity recursion, by taking handler from nested closure */
zend_closure *nested = (zend_closure*)((char*)func - offsetof(zend_closure, func));
zend_closure *nested = ZEND_CONTAINER_OF(func, zend_closure, func);
ZEND_ASSERT(nested->std.ce == zend_ce_closure);
closure->orig_internal_handler = nested->orig_internal_handler;
} else {
Expand Down
4 changes: 2 additions & 2 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -5175,7 +5175,7 @@ static zend_result zend_compile_func_array_map(znode *result, zend_ast_list *arg
opline->lineno = lineno;
opline->extended_value = (2 << 16) | IS_ARRAY;
const zval *fbc_zv = zend_hash_find(CG(function_table), lcname);
const Bucket *fbc_bucket = (const Bucket*)((uintptr_t)fbc_zv - offsetof(Bucket, val));
const Bucket *fbc_bucket = ZEND_CONTAINER_OF(fbc_zv, Bucket, val);
Z_EXTRA_P(CT_CONSTANT(opline->op1)) = fbc_bucket - CG(function_table)->arData;

/* Initialize the result array. */
Expand Down Expand Up @@ -5472,7 +5472,7 @@ static void zend_compile_call(znode *result, const zend_ast *ast, uint32_t type)

/* Store offset to function from symbol table in op2.extra. */
if (fbc->type == ZEND_INTERNAL_FUNCTION) {
const Bucket *fbc_bucket = (const Bucket*)((uintptr_t)fbc_zv - offsetof(Bucket, val));
const Bucket *fbc_bucket = ZEND_CONTAINER_OF(fbc_zv, Bucket, val);
Z_EXTRA_P(CT_CONSTANT(opline->op2)) = fbc_bucket - CG(function_table)->arData;
}

Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ typedef struct zend_enum_obj {

static inline zend_enum_obj *zend_enum_obj_from_obj(zend_object *zobj) {
ZEND_ASSERT(zobj->ce->ce_flags & ZEND_ACC_ENUM);
return (zend_enum_obj*)((char*)(zobj) - offsetof(zend_enum_obj, std));
return ZEND_CONTAINER_OF(zobj, zend_enum_obj, std);
}

void zend_enum_startup(void);
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_fibers.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ static zend_always_inline zend_fiber *zend_fiber_from_context(zend_fiber_context
{
ZEND_ASSERT(context->kind == zend_ce_fiber && "Fiber context does not belong to a Zend fiber");

return (zend_fiber *)(((char *) context) - offsetof(zend_fiber, context));
return ZEND_CONTAINER_OF(context, zend_fiber, context);
}

static zend_always_inline zend_fiber_context *zend_fiber_get_context(zend_fiber *fiber)
Expand Down
28 changes: 28 additions & 0 deletions Zend/zend_portability.h
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,34 @@ char *alloca();
#define ZEND_ELEMENT_COUNT(m)
#endif

#if __cplusplus
extern "C++" {
# include <cstddef>
template<typename T, typename M>
const T* zend_container_of(const M *ptr, size_t offset) {
return reinterpret_cast<const T*>(reinterpret_cast<const char*>(ptr) - offset);
}
template<typename T, typename M>
T* zend_container_of(M *ptr, size_t offset) {
return reinterpret_cast<T*>(reinterpret_cast<char*>(ptr) - offset);
}

# define ZEND_CONTAINER_OF(ptr, Type, member) zend_container_of<Type, decltype(Type::member)>(ptr, offsetof(Type, member))
Copy link
Copy Markdown
Member

@devnexen devnexen May 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was about to say something about the decltype but in another hand it can catch ptr/member mismatches so ...

Copy link
Copy Markdown
Member

@devnexen devnexen May 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

speaking of this, once C++ 20 is recognised widely as minimum, C++20 concepts can help reinforce types contracts here ... we ll see :)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was about to say something about the decltype but in another hand it can catch ptr/member mismatches so ...

Yes, that was the goal. I tested the macro in a standalone C++ file to verify that it handles both const and other types correctly - just like the C23 version does.

If there already is a way to improve the definition right now (e.g. by avoiding two overloads to handle const/non-const), I'm happy to take suggestions. I don't regularly do C++, so while I'm somewhat familiar with what it can offer in theory, I am not comfortable applying that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it s way easier to do such things with C++20 but somewhat doable with older standards. let me think for a moment.

Copy link
Copy Markdown
Member

@devnexen devnexen May 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems doable https://godbolt.org/z/no6MhGase std::conditional_t might have been nice to have but it s a c++14 thing...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the minimum we support is C++17.

Unfortunately your suggestion is taking const-ness from M, not from ptr. Thus https://godbolt.org/z/hh37h6ene doesn't compile.

Given that my current solution works, it's probably not worth spending further time on this.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah my bad you re right :)

}
#elif __STDC_VERSION__ >= 202311L || ZEND_GCC_VERSION
/* typeof is C23 or a GCC extension */
# define ZEND_CONTAINER_OF(ptr, Type, member) \
_Generic( \
ptr, \
const typeof(((Type*)0)->member) *: ((const Type*)((char*)(ptr) - offsetof(Type, member))), \
typeof(((Type*)0)->member) *: ((Type*)((char*)(ptr) - offsetof(Type, member))) \
)
#else
/* Define a variant that does not keep const-ness for older compilers. Mismatches
* are expected to be caught by CI running modern compilers. */
# define ZEND_CONTAINER_OF(ptr, Type, member) ((Type*)((char*)(ptr) - offsetof(Type, member)))
#endif

#ifdef HAVE_BUILTIN_CONSTANT_P
# define ZEND_CONST_COND(_condition, _default) \
(__builtin_constant_p(_condition) ? (_condition) : (_default))
Expand Down
4 changes: 2 additions & 2 deletions Zend/zend_weakrefs.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ static zend_class_entry *zend_ce_weakmap;
static zend_object_handlers zend_weakref_handlers;
static zend_object_handlers zend_weakmap_handlers;

#define zend_weakref_from(o) ((zend_weakref*)(((char*) o) - offsetof(zend_weakref, std)))
#define zend_weakref_from(o) (ZEND_CONTAINER_OF(o, zend_weakref, std))
#define zend_weakref_fetch(z) zend_weakref_from(Z_OBJ_P(z))

#define zend_weakmap_from(o) ((zend_weakmap*)(((char*) o) - offsetof(zend_weakmap, std)))
#define zend_weakmap_from(o) (ZEND_CONTAINER_OF(o, zend_weakmap, std))
#define zend_weakmap_fetch(z) zend_weakmap_from(Z_OBJ_P(z))

static inline void zend_weakref_unref_single(
Expand Down
7 changes: 2 additions & 5 deletions ext/bcmath/bcmath.c
Original file line number Diff line number Diff line change
Expand Up @@ -875,10 +875,7 @@ static int bcmath_number_compare(zval *op1, zval *op2);
#endif
#define CHECK_SCALE_OVERFLOW(scale) (scale > INT_MAX)

static zend_always_inline bcmath_number_obj_t *get_bcmath_number_from_obj(const zend_object *obj)
{
return (bcmath_number_obj_t*)((char*)(obj) - offsetof(bcmath_number_obj_t, std));
}
#define get_bcmath_number_from_obj(obj) ZEND_CONTAINER_OF(obj, bcmath_number_obj_t, std)

static zend_always_inline bcmath_number_obj_t *get_bcmath_number_from_zval(const zval *zv)
{
Expand Down Expand Up @@ -1214,7 +1211,7 @@ static zend_result bc_num_from_obj_or_str_or_long(
bc_num *num, size_t *full_scale, const zend_object *obj, const zend_string *str, zend_long lval)
{
if (obj) {
bcmath_number_obj_t *intern = get_bcmath_number_from_obj(obj);
const bcmath_number_obj_t *intern = get_bcmath_number_from_obj(obj);
*num = intern->num;
if (full_scale) {
*full_scale = intern->scale;
Expand Down
4 changes: 2 additions & 2 deletions ext/curl/curl_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,13 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source);
zend_long php_curl_get_long(zval *zv);

static inline php_curl *curl_from_obj(zend_object *obj) {
return (php_curl *)((char *)(obj) - offsetof(php_curl, std));
return ZEND_CONTAINER_OF(obj, php_curl, std);
}

#define Z_CURL_P(zv) curl_from_obj(Z_OBJ_P(zv))

static inline php_curlsh *curl_share_from_obj(zend_object *obj) {
return (php_curlsh *)((char *)(obj) - offsetof(php_curlsh, std));
return ZEND_CONTAINER_OF(obj, php_curlsh, std);
}

#define Z_CURL_SHARE_P(zv) curl_share_from_obj(Z_OBJ_P(zv))
Expand Down
2 changes: 1 addition & 1 deletion ext/curl/multi.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
zend_class_entry *curl_multi_ce;

static inline php_curlm *curl_multi_from_obj(zend_object *obj) {
return (php_curlm *)((char *)(obj) - offsetof(php_curlm, std));
return ZEND_CONTAINER_OF(obj, php_curlm, std);
}

#define Z_CURL_MULTI_P(zv) curl_multi_from_obj(Z_OBJ_P(zv))
Expand Down
8 changes: 4 additions & 4 deletions ext/date/php_date.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ struct _php_date_obj {
};

static inline php_date_obj *php_date_obj_from_obj(zend_object *obj) {
return (php_date_obj*)((char*)(obj) - offsetof(php_date_obj, std));
return ZEND_CONTAINER_OF(obj, php_date_obj, std);
}

#define Z_PHPDATE_P(zv) php_date_obj_from_obj(Z_OBJ_P((zv)))
Expand All @@ -76,7 +76,7 @@ struct _php_timezone_obj {
};

static inline php_timezone_obj *php_timezone_obj_from_obj(zend_object *obj) {
return (php_timezone_obj*)((char*)(obj) - offsetof(php_timezone_obj, std));
return ZEND_CONTAINER_OF(obj, php_timezone_obj, std);
}

#define Z_PHPTIMEZONE_P(zv) php_timezone_obj_from_obj(Z_OBJ_P((zv)))
Expand All @@ -94,7 +94,7 @@ struct _php_interval_obj {
};

static inline php_interval_obj *php_interval_obj_from_obj(zend_object *obj) {
return (php_interval_obj*)((char*)(obj) - offsetof(php_interval_obj, std));
return ZEND_CONTAINER_OF(obj, php_interval_obj, std);
}

#define Z_PHPINTERVAL_P(zv) php_interval_obj_from_obj(Z_OBJ_P((zv)))
Expand All @@ -113,7 +113,7 @@ struct _php_period_obj {
};

static inline php_period_obj *php_period_obj_from_obj(zend_object *obj) {
return (php_period_obj*)((char*)(obj) - offsetof(php_period_obj, std));
return ZEND_CONTAINER_OF(obj, php_period_obj, std);
}

#define Z_PHPPERIOD_P(zv) php_period_obj_from_obj(Z_OBJ_P((zv)))
Expand Down
2 changes: 1 addition & 1 deletion ext/dba/dba.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ static zend_result dba_connection_cast_object(zend_object *obj, zval *result, in

static inline dba_connection *dba_connection_from_obj(zend_object *obj)
{
return (dba_connection *)((char *)(obj) - offsetof(dba_connection, std));
return ZEND_CONTAINER_OF(obj, dba_connection, std);
}

#define Z_DBA_CONNECTION_P(zv) dba_connection_from_obj(Z_OBJ_P(zv))
Expand Down
2 changes: 1 addition & 1 deletion ext/dom/token_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ static inline dom_token_list_object *php_dom_token_list_from_obj(zend_object *ob

static inline dom_token_list_object *php_dom_token_list_from_dom_obj(dom_object *obj)
{
return (dom_token_list_object *)((char *) obj - offsetof(dom_token_list_object, dom));
return ZEND_CONTAINER_OF(obj, dom_token_list_object, dom);
}

void dom_ordered_set_parser(HashTable *token_set, const char *position, bool to_lowercase);
Expand Down
2 changes: 1 addition & 1 deletion ext/dom/xml_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ typedef struct _dom_object {
} dom_object;

static inline dom_object *php_dom_obj_from_obj(zend_object *obj) {
return (dom_object*)((char*)(obj) - offsetof(dom_object, std));
return ZEND_CONTAINER_OF(obj, dom_object, std);
}

#define Z_DOMOBJ_P(zv) php_dom_obj_from_obj(Z_OBJ_P((zv)))
Expand Down
2 changes: 1 addition & 1 deletion ext/dom/xpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ zend_result dom_xpath_document_read(dom_object *obj, zval *retval)

/* {{{ registerNodeNamespaces bool*/
static inline dom_xpath_object *php_xpath_obj_from_dom_obj(dom_object *obj) {
return (dom_xpath_object*)((char*)(obj) - offsetof(dom_xpath_object, dom));
return ZEND_CONTAINER_OF(obj, dom_xpath_object, dom);
}

zend_result dom_xpath_register_node_ns_read(dom_object *obj, zval *retval)
Expand Down
4 changes: 2 additions & 2 deletions ext/enchant/enchant.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ zend_class_entry *enchant_broker_ce;
static zend_object_handlers enchant_broker_handlers;

static inline enchant_broker *enchant_broker_from_obj(zend_object *obj) {
return (enchant_broker *)((char *)(obj) - offsetof(enchant_broker, std));
return ZEND_CONTAINER_OF(obj, enchant_broker, std);
}

#define Z_ENCHANT_BROKER_P(zv) enchant_broker_from_obj(Z_OBJ_P(zv))
Expand All @@ -67,7 +67,7 @@ zend_class_entry *enchant_dict_ce;
static zend_object_handlers enchant_dict_handlers;

static inline enchant_dict *enchant_dict_from_obj(zend_object *obj) {
return (enchant_dict *)((char *)(obj) - offsetof(enchant_dict, std));
return ZEND_CONTAINER_OF(obj, enchant_dict, std);
}

#define Z_ENCHANT_DICT_P(zv) enchant_dict_from_obj(Z_OBJ_P(zv))
Expand Down
2 changes: 1 addition & 1 deletion ext/fileinfo/fileinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ typedef struct _finfo_object {
} finfo_object;

static inline finfo_object *php_finfo_fetch_object(zend_object *obj) {
return (finfo_object *)((char*)(obj) - offsetof(finfo_object, zo));
return ZEND_CONTAINER_OF(obj, finfo_object, zo);
}

#define Z_FINFO_P(zv) php_finfo_fetch_object(Z_OBJ_P((zv)))
Expand Down
2 changes: 1 addition & 1 deletion ext/gd/gd.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ static zend_function *php_gd_image_object_get_constructor(zend_object *object)

static zend_always_inline php_gd_image_object* php_gd_exgdimage_from_zobj_p(zend_object* obj)
{
return (php_gd_image_object *) ((char *) (obj) - offsetof(php_gd_image_object, std));
return ZEND_CONTAINER_OF(obj, php_gd_image_object, std);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion ext/gmp/php_gmp_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ typedef struct _gmp_object {
} gmp_object;

static inline gmp_object *php_gmp_object_from_zend_object(zend_object *zobj) {
return (gmp_object *)( ((char *)zobj) - offsetof(gmp_object, std) );
return ZEND_CONTAINER_OF(zobj, gmp_object, std);
}

PHP_GMP_API zend_class_entry *php_gmp_class_entry(void);
Expand Down
2 changes: 1 addition & 1 deletion ext/intl/breakiterator/breakiterator_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ typedef struct {
} BreakIterator_object;

static inline BreakIterator_object *php_intl_breakiterator_fetch_object(zend_object *obj) {
return (BreakIterator_object *)((char*)(obj) - offsetof(BreakIterator_object, zo));
return ZEND_CONTAINER_OF(obj, BreakIterator_object, zo);
}
#define Z_INTL_BREAKITERATOR_P(zv) php_intl_breakiterator_fetch_object(Z_OBJ_P(zv))

Expand Down
2 changes: 1 addition & 1 deletion ext/intl/calendar/calendar_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ typedef struct {
} Calendar_object;

static inline Calendar_object *php_intl_calendar_fetch_object(zend_object *obj) {
return (Calendar_object *)((char*)(obj) - offsetof(Calendar_object, zo));
return ZEND_CONTAINER_OF(obj, Calendar_object, zo);
}
#define Z_INTL_CALENDAR_P(zv) php_intl_calendar_fetch_object(Z_OBJ_P(zv))

Expand Down
2 changes: 1 addition & 1 deletion ext/intl/collator/collator_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ typedef struct {
#define COLLATOR_ERROR_CODE_P(co) &(INTL_ERROR_CODE(COLLATOR_ERROR(co)))

static inline Collator_object *php_intl_collator_fetch_object(zend_object *obj) {
return (Collator_object *)((char*)(obj) - offsetof(Collator_object, zo));
return ZEND_CONTAINER_OF(obj, Collator_object, zo);
}
#define Z_INTL_COLLATOR_P(zv) php_intl_collator_fetch_object(Z_OBJ_P(zv))

Expand Down
2 changes: 1 addition & 1 deletion ext/intl/common/common_enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ typedef struct {


static inline IntlIterator_object *php_intl_iterator_fetch_object(zend_object *obj) {
return (IntlIterator_object *)((char*)(obj) - offsetof(IntlIterator_object, zo));
return ZEND_CONTAINER_OF(obj, IntlIterator_object, zo);
}
#define Z_INTL_ITERATOR_P(zv) php_intl_iterator_fetch_object(Z_OBJ_P(zv))

Expand Down
2 changes: 1 addition & 1 deletion ext/intl/dateformat/dateformat_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ typedef struct {
} IntlDateFormatter_object;

static inline IntlDateFormatter_object *php_intl_dateformatter_fetch_object(zend_object *obj) {
return (IntlDateFormatter_object *)((char*)(obj) - offsetof(IntlDateFormatter_object, zo));
return ZEND_CONTAINER_OF(obj, IntlDateFormatter_object, zo);
}
#define Z_INTL_DATEFORMATTER_P(zv) php_intl_dateformatter_fetch_object(Z_OBJ_P(zv))

Expand Down
2 changes: 1 addition & 1 deletion ext/intl/dateformat/datepatterngenerator_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ typedef struct {
} IntlDatePatternGenerator_object;

static inline IntlDatePatternGenerator_object *php_intl_datepatterngenerator_fetch_object(zend_object *obj) {
return (IntlDatePatternGenerator_object *)((char*)(obj) - offsetof(IntlDatePatternGenerator_object, zo));
return ZEND_CONTAINER_OF(obj, IntlDatePatternGenerator_object, zo);
}
#define Z_INTL_DATEPATTERNGENERATOR_P(zv) php_intl_datepatterngenerator_fetch_object(Z_OBJ_P(zv))

Expand Down
2 changes: 1 addition & 1 deletion ext/intl/formatter/formatter_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ typedef struct {
} NumberFormatter_object;

static inline NumberFormatter_object *php_intl_number_format_fetch_object(zend_object *obj) {
return (NumberFormatter_object *)((char*)(obj) - offsetof(NumberFormatter_object, zo));
return ZEND_CONTAINER_OF(obj, NumberFormatter_object, zo);
}
#define Z_INTL_NUMBERFORMATTER_P(zv) php_intl_number_format_fetch_object(Z_OBJ_P(zv))

Expand Down
2 changes: 1 addition & 1 deletion ext/intl/listformatter/listformatter_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ typedef struct {
} ListFormatter_object;

static inline ListFormatter_object *php_intl_listformatter_fetch_object(zend_object *obj) {
return (ListFormatter_object *)((char*)(obj) - offsetof(ListFormatter_object, zo));
return ZEND_CONTAINER_OF(obj, ListFormatter_object, zo);
}
#define Z_INTL_LISTFORMATTER_P(zv) php_intl_listformatter_fetch_object(Z_OBJ_P(zv))

Expand Down
2 changes: 1 addition & 1 deletion ext/intl/msgformat/msgformat_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ typedef struct {


static inline MessageFormatter_object *php_intl_messageformatter_fetch_object(zend_object *obj) {
return (MessageFormatter_object *)((char*)(obj) - offsetof(MessageFormatter_object, zo));
return ZEND_CONTAINER_OF(obj, MessageFormatter_object, zo);
}
#define Z_INTL_MESSAGEFORMATTER_P(zv) php_intl_messageformatter_fetch_object(Z_OBJ_P(zv))

Expand Down
2 changes: 1 addition & 1 deletion ext/intl/rangeformatter/rangeformatter_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ typedef struct {
} IntlNumberRangeFormatter_object;

static inline IntlNumberRangeFormatter_object *php_intl_numberrangeformatter_fetch_object(zend_object *obj) {
return (IntlNumberRangeFormatter_object *)((char*)(obj) - offsetof(IntlNumberRangeFormatter_object, zo));
return ZEND_CONTAINER_OF(obj, IntlNumberRangeFormatter_object, zo);
}

#define Z_INTL_RANGEFORMATTER_P(zv) php_intl_numberrangeformatter_fetch_object(Z_OBJ_P(zv))
Expand Down
2 changes: 1 addition & 1 deletion ext/intl/resourcebundle/resourcebundle_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ typedef struct {
} ResourceBundle_object;

static inline ResourceBundle_object *php_intl_resourcebundle_fetch_object(zend_object *obj) {
return (ResourceBundle_object *)((char*)(obj) - offsetof(ResourceBundle_object, zend));
return ZEND_CONTAINER_OF(obj, ResourceBundle_object, zend);
}
#define Z_INTL_RESOURCEBUNDLE_P(zv) php_intl_resourcebundle_fetch_object(Z_OBJ_P(zv))

Expand Down
2 changes: 1 addition & 1 deletion ext/intl/spoofchecker/spoofchecker_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ typedef struct {
} Spoofchecker_object;

static inline Spoofchecker_object *php_intl_spoofchecker_fetch_object(zend_object *obj) {
return (Spoofchecker_object *)((char*)(obj) - offsetof(Spoofchecker_object, zo));
return ZEND_CONTAINER_OF(obj, Spoofchecker_object, zo);
}
#define Z_INTL_SPOOFCHECKER_P(zv) php_intl_spoofchecker_fetch_object((Z_OBJ_P(zv)))

Expand Down
2 changes: 1 addition & 1 deletion ext/intl/timezone/timezone_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ typedef struct {
} TimeZone_object;

static inline TimeZone_object *php_intl_timezone_fetch_object(zend_object *obj) {
return (TimeZone_object *)((char*)(obj) - offsetof(TimeZone_object, zo));
return ZEND_CONTAINER_OF(obj, TimeZone_object, zo);
}
#define Z_INTL_TIMEZONE_P(zv) php_intl_timezone_fetch_object(Z_OBJ_P(zv))

Expand Down
Loading
Loading