Mam następujący minimalny kod C11, który definiuje strukturę zawierającą uint16_t (co oznacza, że powinna być wyrównana do 2 bajtów) i chcę rzucić bufor wskaźnik do tej struktury.C11 alignas vs. clang -Wcast-align
Po ostrzeżeniu wszystko zaczęło się głośno narzekać, że wymagania wyrównania struktury nie są spełnione. Dodałem więc do bufora specyfikator C11 alignas
, aby upewnić się, że bufor jest wystarczająco wyrównany, ale to nie zamknęło klang.
Moje pytanie brzmi: czy robię coś nie tak z alignas
? Czy tylko to, że diagnostyka -Wcast-align patrzy tylko na typ argumentów, a nie na ręcznie określone wyrównanie? (Rozumiem, że mogę rzucić do void*
, aby wyciszyć diagnostykę, ale ponieważ ten fragment kodu ma być przenośny, nie chcę wykonywać diagnostyki bocznej, chyba że jestem pewien, że jest fałszywy alarm.)
#include <stdint.h>
#include <stdalign.h>
struct foo {
uint16_t field1;
};
int main(void) {
alignas(struct foo) char buffer[122] = {0};
struct foo *foo = (struct foo*)buffer;
return foo->field1;
}
Opcje kompilatora i komunikat o błędzie: wersja
$ clang -ggdb -O3 foo.c -Weverything -Werror -Wno-c++98-compat -Wno-c11-extensions
foo.c:11:23: error: cast from 'char *' to 'struct foo *' increases required alignment from 1 to 2 [-Werror,-Wcast-align]
struct foo *foo = (struct foo*)buffer;
^~~~~~~~~~~~~~~~~~~~~~~~~
Compiler:
$ clang -v
clang version 3.5.1 (tags/RELEASE_351/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
Selected GCC installation: /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4
Aktualizacja: Nie ma żadnego ostrzeżenia po przesunięciu bufora i jego wyrównania do struktury. Interpretuję to jako wskazówkę, że klang rzeczywiście tylko patrzy na typy tego ostrzeżenia.
#include <stdint.h>
#include <stdalign.h>
struct foo {
uint16_t field1;
};
struct bar {
alignas(struct foo) char buffer[122];
};
int main(void) {
struct bar bar = {{0}};
struct foo *foo = (struct foo*)&bar;
return foo->field1;
}
* A może to po prostu, że -Wcast wyrównać diagnostyczny patrzy tylko na rodzaj argumentów, a nie także na ręczne określone wyrównanie * to także moje przypuszczenie. – ouah
Czy to nie jest - http://stackoverflow.com/a/15912208/1150918 istotne? – Kamiccolo
@Kamiccolo: clang and clang ++ na moim komputerze nie kompiluje żadnej z "poprawnych" wersji tego postu. Komunikat o błędzie to "alignas" atrybut dotyczy tylko zmiennych, elementów danych i typów tagów "i" oczekiwano "; na końcu deklaracji ". – handschuhfach