Что на самом деле делает GCC __attribute__((mode(XX))?

Это возникло из вопроса, заданного ранее сегодня по поводу библиотек bignum и специальных хаков gcc для языка C. В частности, использовались эти два объявления:

typedef unsigned int dword_t __attribute__((mode(DI)));

В 32-битных системах и

typedef unsigned int dword_t __attribute__((mode(TI)));

В 64-битных системах.

Я предполагаю, что, учитывая, что это расширение языка C, не существует способа достичь того, чего он достигает в текущих (C99) стандартах.

Итак, мои вопросы просты: верно ли это предположение? И что эти утверждения делают с основной памятью? Я думаю, что в результате у меня есть 2*sizeof(uint32_t) вместо dword в 32-битных системах и 2*sizeof(uint64_t) для 64-битных систем, я прав?


person Community    schedule 30.12.2010    source источник


Ответы (2)


Это позволяет вам явно указать размер для типа, не завися от семантики компилятора или машины, например, размер «long» или «int».

Они довольно хорошо описаны на этой странице.

Цитирую с той страницы:

QI: Целое число, ширина которого равна наименьшей адресуемой единице, обычно 8 бит.

HI: Целое число, в два раза больше, чем целое число в режиме QI, обычно 16 бит.

SI: целое число, в четыре раза превышающее целое число в режиме QI, обычно 32 бита.

DI: целое число, в восемь раз превышающее целое число в режиме QI, обычно 64 бита.

SF: значение с плавающей запятой, такое же широкое, как целое число в режиме SI, обычно 32 бита.

DF: значение с плавающей запятой, такое же широкое, как целое число в режиме DI, обычно 64 бита.

Итак, DI по сути является sizeof(char) * 8.

Дальнейшее объяснение, включая режим TI, можно найти здесь (возможно, лучше, чем первая ссылка, но обе приведены для ознакомления).

Таким образом, TI по сути является sizeof(char) * 16 (128 бит).

person Matthew Iselin    schedule 30.12.2010
comment
Как раз то, что мне было нужно, +1. Я так понимаю, нет стандартного способа обойти это? то есть объявить, скажем, 128-битный тип? В его текущем использовании мы можем dword = word << 1 безопасно и легко; Я бы предпочел не заменять это функцией и т. Д., Если я могу помочь. - person ; 30.12.2010
comment
@Ninefingers: в ​​GCC вы можете использовать __int128, я думаю: gcc.gnu.org/onlinedocs/ gcc/_005f_005fint128.html. - person Matthew Iselin; 30.12.2010
comment
@Ninefingers: GCC поддерживает типы расширений __int128_t и __uint128_t (по крайней мере, на 64-битных платформах, не уверен насчет 32-битных целей) - person Stephen Canon; 30.12.2010
comment
как насчет __attribute__((mode(SD))) ? - person haelix; 24.10.2014
comment
@haelix то же, что и SF, но для парного разряда? - person berkus; 26.08.2017

@haelix Только что прочитал этот вопрос, и я тоже попытался понять это. Насколько я читал: вы можете найти определения в [gcc/gcc/machmode.def] в исходном дереве GCC. Для «SD» это должно быть:

    /* Decimal floating point modes.  */ 
DECIMAL_FLOAT_MODE (SD, 4, decimal_single_format);

и «DECIMAL_FLOAT_MODE» говорит:

     DECIMAL_FLOAT_MODE (MODE, BYTESIZE, FORMAT);
declares MODE to be of class DECIMAL_FLOAT and BYTESIZE bytes
wide.  All of the bits of its representation are significant.
person CoryXie    schedule 14.02.2015