Я пытаюсь принудить препроцессор к выполнению какой-то математики для меня, поэтому константа распространяется на встроенную сборку. Вот уменьшенный случай:Как заставить const-распространение через встроенную функцию?
inline
unsigned int RotateRight(unsigned char value, unsigned int amount)
{
COMPILE_ASSERT(((unsigned char)(amount%32)) < 32);
__asm__ ("rorb %1, %0" : "+mq" (value) : "I" ((unsigned char)(amount%32)));
return value;
}
Код выше зависит от процессора конкретной функциональности, и я в порядке с ним (его собственно шаблоном специализацией на x86/x64 Linux, когда GCC доступен). "I"
ограничение говорит, что интегральное значение должно быть между [0,31]
включительно.
Вызывающие кода будет выглядеть следующим образом:
byte b1 = RotateRight(1, 1);
byte b2 = RotateRight(1, 31);
RotateRight(1, 31)
происходит от криптографов (его поведение не определенно в C/C++, потому что байты могут вращаться только в диапазоне [0,7]
). Я могу освободиться от ограничений C/C++, используя ASM. И так как сумма сдвига известна во время компиляции, я бы хотел, чтобы она сокращалась во время компиляции; и я хотел бы получить версию rorb
с использованием сгенерированного моментально-8.
Без кода COMPILE_ASSERT
код компилируется, но я не уверен, распространяется ли константа. То есть, это может быть вызвано неожиданным уменьшением (% 32
). С COMPILE_ASSERT
код не компилируется.
$ make validat1.o
g++ -DNDEBUG -g2 -O3 -march=native -pipe -c validat1.cpp
In file included from simple.h:10:0,
from filters.h:6,
from files.h:5,
from validat1.cpp:6:
misc.h: In function ‘T CryptoPP::rotlFixed(T, unsigned int) [with T = unsigned char]’:
misc.h:940:43: error: ‘y’ cannot appear in a constant-expression
CRYPTOPP_COMPILE_ASSERT(((unsigned char)(y%32)) < 32);
^
misc.h:72:85: note: in definition of macro ‘CRYPTOPP_COMPILE_ASSERT_INSTANCE’
_COMPILE_ASSERT_INSTANCE(assertion, instance) static CompileAssert<(assertion)>
Я знаю, что я не должен использовать #define
, а ++ встроенные функции C являются ответом. Но я чувствую, что страдаю от разъединения.
Как заставить компилятор распространять значение, которое включает в себя значения const
?
Или, если используется неправильный инструмент COMPILE_ASSERT
(const
), как мне настроить тест, чтобы я мог проверить, что используется версия немедленной версии rorb
?
Связанный, это проект C++ 03. Он не использует Boost, не использует Cmake, не использует Autotools и т. Д.
Сумма сдвига ограничена на C и C++, поскольку аппаратное обеспечение маскирует счетчик сдвига. Использование сборки не меняет этого. –
@Bo - согласен, но я не связан неопределенным поведением C/C++. Если я уменьшу константу во время компиляции или поместим величину сдвига в CX, я получаю сокращение до 5-ти младших разрядов бесплатно. И его хорошо определены в ASM, и не подлежат удалению, как в C/C++. – jww
Мой компилятор MinGW говорит, что * x * не определено (при возврате оператора). Это нормально? – stgatilov