Skip to main content
We’ve updated our Terms of Service. A new AI Addendum clarifies how Stack Overflow utilizes AI interactions.
Rename: mallocarray()
Source Link
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>


#define mallocs(ptr, nmemb) (                               \
{                                                           \
        __auto_type     ptr_    = (ptr);                    \
                                                            \
        *ptr_   = mallocs__mallocarray((nmemb), sizeof(**ptr_));       \
                                                            \
        !(*ptr_);                                           \
}                                                           \
)


inline
void    *mallocs__*mallocarray(ptrdiff_t nmemb, size_t size);


inline
void    *mallocs__*mallocarray(ptrdiff_t nmemb, size_t size)
{

    if (nmemb < 0)
        goto ovf;
    if (nmemb > (PTRDIFF_MAX / (ptrdiff_t)size))
        goto ovf;

    return  malloc(size * nmemb);
ovf:
    errno   = EOVERFLOW;
    return  NULL;
}

I named mallocarray() after the BSD extension reallocarray()

#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>


#define mallocs(ptr, nmemb) (                               \
{                                                           \
        __auto_type     ptr_    = (ptr);                    \
                                                            \
        *ptr_   = mallocs__((nmemb), sizeof(**ptr_));       \
                                                            \
        !(*ptr_);                                           \
}                                                           \
)


inline
void    *mallocs__(ptrdiff_t nmemb, size_t size);


inline
void    *mallocs__(ptrdiff_t nmemb, size_t size)
{

    if (nmemb < 0)
        goto ovf;
    if (nmemb > (PTRDIFF_MAX / (ptrdiff_t)size))
        goto ovf;

    return  malloc(size * nmemb);
ovf:
    errno   = EOVERFLOW;
    return  NULL;
}
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>


#define mallocs(ptr, nmemb) (                               \
{                                                           \
        __auto_type     ptr_    = (ptr);                    \
                                                            \
        *ptr_   = mallocarray((nmemb), sizeof(**ptr_));     \
                                                            \
        !(*ptr_);                                           \
}                                                           \
)


inline
void    *mallocarray(ptrdiff_t nmemb, size_t size);


inline
void    *mallocarray(ptrdiff_t nmemb, size_t size)
{

    if (nmemb < 0)
        goto ovf;
    if (nmemb > (PTRDIFF_MAX / (ptrdiff_t)size))
        goto ovf;

    return  malloc(size * nmemb);
ovf:
    errno   = EOVERFLOW;
    return  NULL;
}

I named mallocarray() after the BSD extension reallocarray()

optimize; use C99 inline
Source Link

After finding that the code above can only be called once in a function, I improved it making use of aan static inline and __label__. Now there is the possibility to call the function or the macro, depending on your preferences (both can be called multiple times):

#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>


#define mallocs(ptr, nmemb) (                               \
{                                                           \
        __label__   ret_;                                   \
    __auto_type    __auto_type ptr_    = (ptr);                        \
        int         err_;                                   \
                                                            \
        err_    = 0;                                        \
        if (ptr_ == NULL) {                                 \
                errno   = EINVAL;                           \
                err_    = EINVAL;                           \
                goto ret_;                                  \
        }                                                   \
                                                            \
        *ptr_   = mallocs__((nmemb), sizeof(**ptr_));       \
        if (!(*ptr_))                                       \
                err_    = errno;                            \
ret_:                                                       \
        err_;    !(*ptr_);                                           \
}                                                           \
)


static inline    
void    *mallocs__(ptrdiff_t nmemb, size_t size);


static inline    
void    *mallocs__(ptrdiff_t nmemb, size_t size)
{

    if (nmemb < 0)
        goto ovf;
    if (nmemb > (PTRDIFF_MAX / (ptrdiff_t)size))
        goto ovf;

    return  malloc(size * nmemb);
ovf:
    errno   = EOVERFLOW;
    return  NULL;
}

After finding that the code above can only be called once in a function, I improved it making use of a static inline and __label__. Now there is the possibility to call the function or the macro, depending on your preferences (both can be called multiple times):

#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>


#define mallocs(ptr, nmemb) (                               \
{                                                           \
        __label__   ret_;                                   \
        __auto_type ptr_    = (ptr);                        \
        int         err_;                                   \
                                                            \
        err_    = 0;                                        \
        if (ptr_ == NULL) {                                 \
                errno   = EINVAL;                           \
                err_    = EINVAL;                           \
                goto ret_;                                  \
        }                                                   \
                                                            \
        *ptr_   = mallocs__((nmemb), sizeof(**ptr_));       \
        if (!(*ptr_))                                       \
                err_    = errno;                            \
ret_:                                                       \
        err_;                                               \
}                                                           \
)


static inline   void    *mallocs__(ptrdiff_t nmemb, size_t size);


static inline   void    *mallocs__(ptrdiff_t nmemb, size_t size)
{

    if (nmemb < 0)
        goto ovf;
    if (nmemb > (PTRDIFF_MAX / (ptrdiff_t)size))
        goto ovf;

    return  malloc(size * nmemb);
ovf:
    errno   = EOVERFLOW;
    return  NULL;
}

After finding that the code above can only be called once in a function, I improved it making use of an inline. Now there is the possibility to call the function or the macro, depending on your preferences (both can be called multiple times):

#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>


#define mallocs(ptr, nmemb) (                               \
{                                                           \
        __auto_type     ptr_    = (ptr);                    \
                                                            \
        *ptr_   = mallocs__((nmemb), sizeof(**ptr_));       \
                                                            \
        !(*ptr_);                                           \
}                                                           \
)


inline 
void    *mallocs__(ptrdiff_t nmemb, size_t size);


inline 
void    *mallocs__(ptrdiff_t nmemb, size_t size)
{

    if (nmemb < 0)
        goto ovf;
    if (nmemb > (PTRDIFF_MAX / (ptrdiff_t)size))
        goto ovf;

    return  malloc(size * nmemb);
ovf:
    errno   = EOVERFLOW;
    return  NULL;
}
rename
Source Link
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>


#define mallocs__mallocs(ptr, nmemb) (  (                             \
{                                                           \
        __label__   ret_;                                   \
        __auto_type ptr_    = (ptr);                        \
        int         err_;                                   \
                                                            \
        err_    = 0;                                        \
        if (ptr_ == NULL) {                                 \
                errno   = EINVAL;                           \
                err_    = EINVAL;                           \
                goto ret_;                                  \
        }                                                   \
                                                            \
        *ptr_   = mallocsmallocs__((nmemb), sizeof(**ptr_));         \
        if (!(*ptr_))                                       \
                err_    = errno;                            \
ret_:                                                       \
        err_;                                               \
}                                                           \
)


static inline   void    *mallocs*mallocs__(ptrdiff_t nmemb, size_t size);


static inline   void    *mallocs*mallocs__(ptrdiff_t nmemb, size_t size)
{

    if (nmemb < 0)
        goto neg;ovf;
    if (nmemb > (PTRDIFF_MAX / (ptrdiff_t)size))
        goto ovf;

    return  malloc(size * nmemb);
neg:
ovf:
    errno   = EOVERFLOW;
    return  NULL;
}
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>


#define mallocs__(ptr, nmemb)   (                           \
{                                                           \
        __label__   ret_;                                   \
        __auto_type ptr_    = (ptr);                        \
        int         err_;                                   \
                                                            \
        err_    = 0;                                        \
        if (ptr_ == NULL) {                                 \
                errno   = EINVAL;                           \
                err_    = EINVAL;                           \
                goto ret_;                                  \
        }                                                   \
                                                            \
        *ptr_   = mallocs((nmemb), sizeof(**ptr_));         \
        if (!(*ptr_))                                       \
                err_    = errno;                            \
ret_:                                                       \
        err_;                                               \
}                                                           \
)


static inline   void    *mallocs(ptrdiff_t nmemb, size_t size);


static inline   void    *mallocs(ptrdiff_t nmemb, size_t size)
{

    if (nmemb < 0)
        goto neg;
    if (nmemb > (PTRDIFF_MAX / (ptrdiff_t)size))
        goto ovf;

    return  malloc(size * nmemb);
neg:
ovf:
    errno   = EOVERFLOW;
    return  NULL;
}
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>


#define mallocs(ptr, nmemb) (                               \
{                                                           \
        __label__   ret_;                                   \
        __auto_type ptr_    = (ptr);                        \
        int         err_;                                   \
                                                            \
        err_    = 0;                                        \
        if (ptr_ == NULL) {                                 \
                errno   = EINVAL;                           \
                err_    = EINVAL;                           \
                goto ret_;                                  \
        }                                                   \
                                                            \
        *ptr_   = mallocs__((nmemb), sizeof(**ptr_));       \
        if (!(*ptr_))                                       \
                err_    = errno;                            \
ret_:                                                       \
        err_;                                               \
}                                                           \
)


static inline   void    *mallocs__(ptrdiff_t nmemb, size_t size);


static inline   void    *mallocs__(ptrdiff_t nmemb, size_t size)
{

    if (nmemb < 0)
        goto ovf;
    if (nmemb > (PTRDIFF_MAX / (ptrdiff_t)size))
        goto ovf;

    return  malloc(size * nmemb);
ovf:
    errno   = EOVERFLOW;
    return  NULL;
}
move line
Source Link
Loading
added 16 characters in body
Source Link
Loading
explain
Source Link
Loading
__
Source Link
Loading
Fix bug; use static inline
Source Link
Loading
Rollback to Revision 2
Source Link
Loading
added 101 characters in body; added 6 characters in body
Source Link
Loading
Fix bug: sizeof; deleted 1 character in body; added 13 characters in body
Source Link
Loading
Source Link
Loading