I have the following code and get a compiling error:
#include <cstddef>
#include <cstdint>
#define CHECK_ALIGN(ptr, alignment) \
do{ \
constexpr size_t status \
= reinterpret_cast<uintptr_t>(ptr) % alignment; \
static_assert(status == 0, "ptr must be aligned"); \
}while(0)
int main(int argc, char** argv) {
char c;
int i;
long l ;
float f;
CHECK_ALIGN(&c, sizeof(c));
CHECK_ALIGN(&i, sizeof(i));
CHECK_ALIGN(&l, sizeof(l));
CHECK_ALIGN(&f, sizeof(f));
return 0;
}
error: conversion from pointer type 'char*' to arithmetic type 'uintptr_t' {aka 'long unsigned int'} in a constant expression
What is the proper type to convert to for those pointer type to do some arithmetic?
CodePudding user response:
status
cannot be constexpr
because the value of ptr is not known at compile time. Also static_assert()
needs to be replaced with assert()
for the same reason.
#include <cstddef>
#include <cstdint>
#include <cassert>
#define CHECK_ALIGN(ptr, alignment) \
do{ \
const size_t status \
= reinterpret_cast<uintptr_t>(ptr) % alignment; \
assert(status == 0); \
} while(0)
int main(int argc, char** argv) {
char c;
int i;
long l ;
float f;
CHECK_ALIGN(&c, sizeof(c));
CHECK_ALIGN(&i, sizeof(i));
CHECK_ALIGN(&l, sizeof(l));
CHECK_ALIGN(&f, sizeof(f));
return 0;
}
Godbolt: https://godbolt.org/z/GrWdE3sGK
Alternatively you could use constexpr
expressions like this
#include <cstddef>
#include <cstdint>
#define CHECK_ALIGN(value, alignment) \
static_assert(alignof((value)) % alignment == 0, #value "must be aligned");
int main(int argc, char** argv) {
char c;
int i;
long l ;
float f;
CHECK_ALIGN(c, sizeof(c));
CHECK_ALIGN(i, sizeof(i));
CHECK_ALIGN(l, sizeof(l));
CHECK_ALIGN(f, sizeof(f));
return 0;
}
Godbolt: https://godbolt.org/z/fMfY3P9bd