2016-11-29 2 views
0

Я этажном что VisualStudio 2015 настаивает на содействие WORD (unsigned short) к unsigned int когда только WORD значениям участвует только в битовых манипуляциях. (т. е. продвигает 16 бит до 32 бит при выполнении 16 бит | 16 бит).Как избежать интегрального продвижения для поразрядных операций

например.

// where WORD is a 'unsigned short' 
const WORD kFlag = 1; 
WORD old = 2; 
auto value = old | kFlag; // why the blazes is value an unsigned int (32 bits) 

Кроме того, есть ли способ, чтобы получить 0x86 для WORD|WORD встроенных функций? Я, конечно же, не хочу платить (16-> 32 | 16 ->) -> 16. Также этот код не должен потреблять больше, чем несколько 16-разрядных регистров, а не несколько 32-битных регистров.

Но использование реестра действительно просто в стороне. Оптимизатор может делать все, что угодно, если результаты для меня неотличимы. (т. е. он не должен изменять размер видимым образом).

Основная проблема для меня в том, что использование флагов | kFlagValue приводит к более широкой сущности, а затем перекачивание этого в шаблон дает мне ошибку несоответствия типа (шаблон довольно длинный, чем я хочу здесь, но точка - это два аргумента, и они должны совпадать по типу или быть тривиально конвертируемыми, но не из-за этого автоматического правила увеличения размера).

Если бы я имел доступ к «консервативной обработки битов набора функций», то я мог бы использовать:

 flag non-promoting-bit-operator kFlagValue 

Для достижения своих целей.

Я полагаю, что мне нужно написать это, или использовать броски повсюду, из-за этого неудачного правила.

В этом случае C++ не следует продвигать. Это был плохой выбор языка.

+0

Если выход этой функции настолько важен для общего выполнения вашей программы, то, во что бы то ни стало, отбросить там какой-нибудь ассемблер и помочь компилятору сделать это правильно. В противном случае, зачем беспокоиться о том, что в колбасе, если оно все еще на вкус? –

+0

Потому что это нарушает типы. C++ расширяет то, что НИКОГДА не должно быть шире. 16-разрядное значение, которое является или ORed и ANDed с другими 16-битными значениями, НИКОГДА не будет переполняться, а результаты будут на 100% безопасным 16-битным значением, которое может быть сохранено в ABI. Я не хочу, чтобы язык произвольно продвигал вещи для скорости способами, которые генерируют видимые побочные эффекты, когда ни один из них не нужен (если он хочет сделать это как невидимую для меня оптимизацию, это хорошо, но это имеет видимые последствия, заставить мой код изменить) :( – Mordachai

+1

Логические операции, подмножество арифметических операций, конвертировать операнды, которые меньше, чем 'int', в' int' – doug

ответ

1

Почему именно value повышен для большей категории? Поскольку спецификация языка говорит, что это (16-разрядный unsigned short будет преобразован в 32-разрядный int). 16-разрядные операционные системы на x86 фактически налагают штраф за соответствующие 32-битные (из-за кода префикса), поэтому 32-разрядная версия может работать быстрее.

+0

Ударьте мне это - небольшие операции на более крупных процессорах, как правило, дороже. –

+0

Это должно быть 'int', а не' unsigned', если спецификация должна соблюдаться (в среде OP).«Prvalue целочисленного типа, отличного от bool, char16_t, char32_t или wchar_t, чье целочисленное преобразование ранг (4.13) меньше ранга int, можно преобразовать в prvalue типа int, если int может представлять все значения тип источника, в противном случае исходное prvalue может быть преобразовано в prvalue типа unsigned int. " – krzaq

+0

Я не забочусь о знаке акции, но сам продвижение. Я вижу, что есть +/- продвижение, но операторы бит просто раздражают и заставляют меня посыпать мой код бессмысленными операторами литья. – Mordachai

Смежные вопросы