Skip to content

Instantly share code, notes, and snippets.

@matu3ba
Created June 23, 2024 20:48
Show Gist options
  • Save matu3ba/f9088fdaf0d1eaecc07dec21133e5433 to your computer and use it in GitHub Desktop.
Save matu3ba/f9088fdaf0d1eaecc07dec21133e5433 to your computer and use it in GitHub Desktop.
cerberus error ptrtoint_inttoptr.c
cerberus ptrtoint_inttoptr.c
ptrtoint_inttoptr.c:24:16: error: constraint violation: initializing 'void*' with an expression of incompatible type 'usual arithmetic conversions with type [integer promotion of [usual arithmetic conversions with type [integer promotion of [uintptr_t] and integer promotion of [unsigned short]]] and integer promotion of [integer promotion of [uintptr_t]]]'
void * ptr = ((uintptr_t)mem+align_min_1) & ~(uintptr_t)align_min_1;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
§6.7.9#11, sentence 2:
11 The initializer for a scalar shall be a single expression, optionally enclosed in braces. The
initial value of the object is that of the expression (after conversion); the same type
constraints and conversions as for simple assignment apply, taking the type of the scalar
to be the unqualified version of its declared type.
§6.5.16.1#1:
1 One of the following shall hold:112)
-- the left operand has atomic, qualified, or unqualified arithmetic type, and the right has
arithmetic type;
-- the left operand has an atomic, qualified, or unqualified version of a structure or union
type compatible with the type of the right;
-- the left operand has atomic, qualified, or unqualified pointer type, and (considering
the type the left operand would have after lvalue conversion) both operands are
pointers to qualified or unqualified versions of compatible types, and the type pointed
to by the left has all the qualifiers of the type pointed to by the right;
-- the left operand has atomic, qualified, or unqualified pointer type, and (considering
the type the left operand would have after lvalue conversion) one operand is a pointer
to an object type, and the other is a pointer to a qualified or unqualified version of
void, and the type pointed to by the left has all the qualifiers of the type pointed to
by the right;
-- the left operand is an atomic, qualified, or unqualified pointer, and the right is a null
pointer constant; or
-- the left operand has type atomic, qualified, or unqualified _Bool, and the right is a
pointer.
FOOTNOTE.112:
The asymmetric appearance of these constraints with respect to type qualifiers is due to the conversion
(specified in 6.3.2.1) that changes lvalues to ``the value of the expression'' and thus removes any type
qualifiers that were applied to the type category of the expression (for example, it removes const but
not volatile from the type int volatile * const).
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void memset_16aligned(void * ptr, char byte, size_t size_bytes, uint16_t alignment) {
assert((size_bytes & (alignment-1)) == 0); // Size aligned
assert(((uintptr_t)ptr & (alignment-1)) == 0); // Pointer aligned
memset(ptr, byte, size_bytes);
}
// 1. Careful with segmented address spaces: lookup uintptr_t semantics
// 2. Careful with long standing existing optimization compiler bugs pointer to
// integer and back optimizations in for example clang and gcc
// 3. Careful with LTO potentially creating problem 2.
// 4. Consider C11 aligned_alloc or posix_memalign
void ptrtointtoptr() {
const uint16_t alignment = 16;
const uint16_t align_min_1 = alignment - 1;
void * mem = malloc(1024+align_min_1);
// C89: void *ptr = (void *)(((INT_WITH_PTR_SIZE)mem+align_min_1) & ~(INT_WITH_PTR_SIZE)align_min_1);
// ie void *ptr = (void *)(((uint64_t)mem+align_min_1) & ~(uint64_t)align_min_1);
// offset ptr to next alignment byte boundary
// void * ptr = (void *)(((uintptr_t)mem+align_min_1) & ~(uintptr_t)align_min_1);
void * ptr = ((uintptr_t)mem+align_min_1) & ~(uintptr_t)align_min_1;
printf("0x%08" PRIXPTR ", 0x%08" PRIXPTR "\n", (uintptr_t)mem, (uintptr_t)ptr);
memset_16aligned(ptr, 0, 1024, alignment);
free(mem);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment