Étant donné un void *
vers un espace de stockage, comment vérifier s'il pointe vers un espace de stockage correctement aligné sans aucun comportement défini par l'implémentation ?
Bien sûr, nous avons std::align
Mais existe-t-il un moyen plus efficace d'y parvenir ?
template <std::size_t alignment>
inline bool is_aligned(void * ptr) noexcept {
std::size_t max = 1u;
return std::align(alignment, 1u, ptr, max);
}
PS : Je dois faire cela d'une manière compatible avec les normes C++, sans dépendre d'aucun hacks spécifiques à la plate-forme (définis par l'implémentation).
PPS : Je m'excuse pour mon anglais (incompréhensible), qui n'est pas ma langue maternelle.
ÉDITER (2018.08.24) : J'ai supprimé le terme "efficace" du titre, et j'ai ajouté des termes supplémentaires pour souligner que je ne veux pas de comportement défini par l'implémentation ou spécifique à la plate-forme.
0 votes
L'important à propos des pointeurs (dans un cas comme celui-ci) est de se rappeler qu'il ne s'agit en fait que de valeurs entières correspondant à une adresse. C'est le traitement qu'en font les compilateurs qui les rend spéciaux. Et puisqu'un pointeur n'est qu'un entier, vous pouvez utiliser les opérateurs bitwise normaux sur eux (avec le casting adéquat bien sûr),
std::intptr_t
est utile ici). Par exemple, pour vérifier si un pointeur est sur une adresse paire, vous pouvez fairereinterpret_cast<intptr_t>(some_pointer) & ~1
.0 votes
Ceci étant dit, étant donné que
ptr
(dans votre exemple) n'est pas lui-même unconstexpr
alors le résultat de tout calcul l'utilisant ne peut pas non plus êtreconstexpr
.2 votes
Notez également que l'alignement est par définition spécifique à une plate-forme et que l'exploitation des valeurs numériques renvoyées par un reinterpret_cast, comme le suggère @Some, est un comportement intrinsèquement non défini ou défini par l'implémentation.
2 votes
Enfin, si vous avez alloué de la mémoire en utilisant
new
onew[]
vous pouvez être certain que la mémoire sera bien alignée pour le type de produit avec lequel vous travaillez. Peut-être pouvez-vous nous éclairer sur le problème que vous essayez de résoudre en vérifiant l'alignement ? Pourquoi avez-vous besoin de le vérifier ?3 votes
@Someprogrammerdude Cela peut être utile lorsque l'on dispose d'un tampon contenant des données brutes arbitraires, et que l'on doit vérifier si certaines parties de ce tampon sont directement accessibles sous la forme d'un certain type d'information.
T
ou si l'on doit utiliserstd::memcpy
pour copier les données respectives de/vers la mémoire tampon avant/après l'accès à ces données en tant que typeT
.3 votes
@Someprogrammerdude avant C++17 c'est seulement vrai pour les types avec un alignement standard, ce n'est pas vrai pour quelque chose comme
struct OveralignedInt { alignas(1024) int i; };
1 votes
@jotik Il est possible d'accéder à des données brutes arbitraires (
char
tampon) comme certainsT
même lorsque les conditions d'alignement sont remplies. Vous devrez commencer la durée de vie de l'objet par un placementnew
d'abord.0 votes
@jotik : Comment auriez-vous un tel tampon à l'adresse suivante temps de compilation ? Le C++ au moment de la compilation ne permet pas ce genre d'astuce. Alors pourquoi votre fonction de détection devrait-elle être
constexpr
?1 votes
@yurikilochek Même pour les types trivialement copiables ?
0 votes
@NicolBolas Je n'étais pas sûr, et c'est pour cela que j'ai utilisé le mot. de préférence .
1 votes
@jotik oui, même pour ceux
0 votes
@yurikilochek Même quand ce n'est pas une
char
mais seulement le stockage alloué par, disons,::operator new(std::size_t)
?0 votes
@jotik oui, de même pour
malloc
. Il n'y a pas d'objet auquel vous pouvez accéder tant que vous ne l'avez pas créé.0 votes
Duplicata possible de Comment déterminer si la mémoire est alignée ? La réponse de @Atlaste est C++ et semble répondre à votre question.
0 votes
@jww Ces deux solutions reposent sur un comportement défini par l'implémentation. J'ai modifié ma question pour insister davantage sur le fait que je ne souhaite pas m'appuyer sur un comportement défini par l'implémentation.