Skip to content

Instantly share code, notes, and snippets.

@imaami
Created July 9, 2023 21:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save imaami/552127d1d9b22ecd0c4e4158fd17c196 to your computer and use it in GitHub Desktop.
Save imaami/552127d1d9b22ecd0c4e4158fd17c196 to your computer and use it in GitHub Desktop.
Testing optimization levels
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define stringify_(x) #x
#define stringify(x) stringify_(x)
#if defined __GNUC__ && !defined __clang__
# define ligma_gcc(...) _Pragma(stringify_(GCC __VA_ARGS__))
#else
# define ligma_gcc(...)
#endif
#define force_inline __attribute__((always_inline)) static inline
/**
* @brief dstr stands for dumb string.
*/
typedef struct dstr
{
_Alignas(char *) union
{
struct __attribute__((packed))
{
union {
char *ptr; //!< String pointer.
char const *view; //!< String view.
};
unsigned int size; //!< Total heap allocation size.
};
char arr[sizeof(char *) + sizeof(unsigned int)]; //!< Array.
};
unsigned int len; //!< String length excluding the null terminator.
} dstr;
#define dstr_get(s_) (__typeof__((s_)->arr[0]) *) \
{ !dstr_is_pointer(s_) ? (s_)->arr : (s_)->ptr }
#define is_char_array(x) \
_Generic((__typeof__(x) *){0}, \
char (*)[sizeof(x)]: 1, \
char const (*)[sizeof(x)]: 1, \
default: 0)
#define is_string_literal(x) \
__builtin_choose_expr(is_char_array(x), __builtin_constant_p(x), 0)
#define safe_string_literal(lit, what) \
__builtin_choose_expr( \
is_string_literal(lit) && sizeof(lit) <= sizeof(what), \
lit, "")
#define make_dstr_view_from_literal(src) \
__builtin_choose_expr( \
sizeof(src) <= sizeof(((dstr *)0)->arr), \
(dstr){.arr = {safe_string_literal(src, ((dstr*)0)->arr)}, \
.len = sizeof(src) - 1u}, \
(dstr){.view = src, .size = 0u, .len = sizeof(src) - 1u})
#define make_dstr_view_from_array(src) \
__builtin_choose_expr( \
sizeof(src) <= sizeof(((dstr *)0)->arr), \
make_dstr_from_small_string(src, sizeof(src) - 1u), \
(dstr){.view = src, .size = 0u, .len = sizeof(src) - 1u})
#define make_dstr_view(src) \
__builtin_choose_expr( \
is_string_literal(src), \
make_dstr_view_from_literal(src), \
__builtin_choose_expr( \
is_char_array(src), \
make_dstr_view_from_array(src), \
make_dstr_view_from_decay(src, strlen(src))))
force_inline dstr
make_dstr_from_small_string (char const *const src,
size_t len)
{
dstr d = {.arr = {0}, .len = (unsigned)len};
__builtin_memcpy(&d.arr[0], src, len);
return d;
}
force_inline dstr
make_dstr_view_from_decay (char const *const src,
size_t len)
{
ligma_gcc(diagnostic push)
ligma_gcc(diagnostic ignored "-Wstringop-overflow")
return !len || len > UINT_MAX - 1u
? (dstr){0}
: len < sizeof(((dstr *)0)->arr)
? make_dstr_from_small_string(src, len)
: (dstr){.view = src, .size = 0u, .len = (unsigned)len};
ligma_gcc(diagnostic pop)
}
force_inline bool
dstr_is_empty (dstr const *s)
{
return !s->len;
}
force_inline bool
dstr_is_array (dstr const *s)
{
return s->len && s->len < sizeof s->arr;
}
force_inline bool
dstr_is_pointer (dstr const *s)
{
return s->len >= sizeof s->arr;
}
force_inline bool
dstr_owns_memory (dstr const *s)
{
return dstr_is_pointer(s) && s->size;
}
force_inline void
dstr_init (dstr *s)
{
s->ptr = NULL;
s->size = 0u;
s->len = 0u;
}
force_inline void
dstr_fini (dstr *s)
{
if (dstr_owns_memory(s))
free(s->ptr);
dstr_init(s);
}
void test (void)
{
dstr s = make_dstr_view("short string");
puts(dstr_get(&s));
dstr_fini(&s);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment