diff --git a/osdep.h b/osdep.h
index cb213e0..51ffab0 100644
--- a/osdep.h
+++ b/osdep.h
@@ -42,10 +42,11 @@ typedef signed int              int_fast16_t;
 
 /* Convert from a base type to a parent type, with compile time
 checking.  */
 #ifdef __GNUC__
-#define DO_UPCAST(type, field, dev) ( __extension__ ( { \
-    char __attribute__((unused)) offset_must_be_zero[ \
-        -offsetof(type, field)]; \
-    container_of(dev, type, field);}))
+#define DO_UPCAST(type, field, dev) ( __extension__ ( { \
+    const typeof(((type *) 0)->field) *__mptr = (dev); \
+    ssize_t __offset = - offsetof (type, field); \
+    char __attribute__((unused)) offset_must_be_zero[ __offset ]; \
+    ((type *) ((char *) __mptr + __offset)); } ) )
 #else
 #define DO_UPCAST(type, field, dev) container_of(dev, type, field)
