Странное выравнивание массива по умолчанию в Clang или LLVM (emscripten) - PullRequest
0 голосов
/ 29 октября 2018

Я столкнулся с любопытной проблемой с портом javascript моей программы на C (я считаю, что он использует компилятор clang и llvm). Похоже, что доступ к памяти с помощью указателя int* принудительно выравнивается и приводит к неисправности.

(код в C++, для интерпретатора BASIC, и это часть, которая хранит данные в переменной массива)

short offset = getArrayOffset(symbol); // base offset of given BASIC array

// highest (15th) bit of offset is array type flag really
// now we determine array element size (byte or 4-byte int)
char b = (offset & 0x8000) ? 1 : sizeof(numeric);

// multiply size by requested index and add it to get real offset
offset = (offset & 0x7FFF) + b * idx;

// now this offset is added to the pointer of the end of variables area
// and so "p" should point precisely to wanted element
char* p = ((char*)(void*)vars) + sizeof(varHolder) * numVars + offset;

if (b > 1) {  // and depending on the element type
    *((numeric*)(void*)p) = value; // *** we write "numeric" (i.e. int)
} else {
    *((unsigned char*)(void*)p) = (value & 0xFF); // or single byte
}

( ссылка на точную точку в источнике)

Теперь магия такова: varHolder - это структура из 6 байтов, поэтому, когда у меня есть numVars=1 (определена только переменная этого массива), и выводится разница между vars и p, это 6. Однако целочисленное значение в строке, отмеченной ***, сохраняется в памяти на два байта ниже!

То же самое с idx=1 - разница между адресами составляет 10, но значение сохраняется, начиная со смещения 8.

Более того, если определена другая переменная (таким образом, numVars становится 2, а разница vars и p становится делимой на 4) - проблема, похоже, исчезает.

Так что мне любопытно узнать, есть ли какое-либо выравнивание по умолчанию для небайтовых указателей. Я еще не смог воспроизвести его с помощью онлайн-компиляторов clang, извините: (

Тем временем хранятся элементы байтового массива (другая ветка if, кажется, работает отлично).

...