One year of C
> no actions need to happen on destructionso... you like never free, never fclose, never munmap, never pthread_join, never unlock mutexes, never close network connections or what ?Also, all of your protoypes such as    sg_pipeline sg_alloc_pipeline() {

should really be    sg_pipeline sg_alloc_pipeline(void) {

since the first one can actually be called with any number of arguments (in C, not in C++).Note also that C doesn't have return-value-optimization, hence all your struct-returning functions can possibly cause a call to memcpy (won't happen when compiled in C++ mode of course) and will generally lead to much more binary bloat than the traditional C way of passing outputs as arguments.
e.g. given this trivial code in foo.c:    typedef struct _foo
    {
        int x;
        float foo, bar;
        char z[1024]; // change this to 10024 to get a memcpy! 
    
    } foo;
    
    void do_stuff_to_foo(foo*);
    
    foo blah()
    {
        foo f;
        do_stuff_to_foo(&f);
        return f;
    }

A disassembly after compilation with gcc -std=c99 -O3 gives    blah:
    .LFB0:
	pushq	%rbp
	movq	%rdi, %rbp
	pushq	%rbx
	subq	$1064, %rsp
	movq	%fs:40, %rax
	movq	%rax, 1048(%rsp)
	xorl	%eax, %eax
	movq	%rsp, %rbx
	movq	%rbx, %rdi
	call	do_stuff_to_foo@PLT
	movq	(%rsp), %rax
	leaq	8(%rbp), %rdi
	movq	%rbp, %rcx
	andq	$-8, %rdi
	movq	%rbx, %rsi
	subq	%rdi, %rcx
	movq	%rax, 0(%rbp)
	movq	1028(%rbx), %rax
	subq	%rcx, %rsi
	addl	$1036, %ecx
	movq	%rax, 1028(%rbp)
	shrl	$3, %ecx
	rep movsq
	movq	1048(%rsp), %rdx
	xorq	%fs:40, %rdx
	jne	.L5
	addq	$1064, %rsp
	movq	%rbp, %rax
	popq	%rbx
	popq	%rbp
	ret


The same thing built with g++ -O3 gives    _Z4blahv:
	pushq	%rbx
	movq	%rdi, %rbx
	call	_Z15do_stuff_to_fooP4_foo@PLT
	movq	%rbx, %rax
	popq	%rbx
	ret

While clang (in C mode) goes for a memcpy:    blah:                                   # @blah
	pushq	%r14
	pushq	%rbx
	subq	$1048, %rsp             # imm = 0x418
	movq	%rdi, %rbx
	movq	%fs:40, %rax
	movq	%rax, 1040(%rsp)
	movq	%rsp, %r14
	movq	%r14, %rdi
	callq	do_stuff_to_foo@PLT
	movl	$1036, %edx             # imm = 0x40C
	movq	%rbx, %rdi
	movq	%r14, %rsi
	callq	memcpy@PLT
	movq	%fs:40, %rax
	cmpq	1040(%rsp), %rax
	jne	.LBB0_2
	movq	%rbx, %rax
	addq	$1048, %rsp             # imm = 0x418
	popq	%rbx
	popq	%r14
	retq