2016-12-15 14 views
1

Код:Могу ли я наложить указатели следующим образом?

unsigned char array_add[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 

... 

if ((*((uint32_t*)array_add)!=0)||(*((uint32_t*)array_add+1)!=0)) 
{ 
... 
} 

Я хочу, чтобы проверить, если массив все равны нулю. Поэтому я, естественно, подумал о том, чтобы указать адрес массива, который также является адресом первого члена, на неподписанный тип int 32, поэтому мне нужно будет сделать это дважды, так как это 64-разрядный 8-байтовый массив. Проблема в том, что она была успешно скомпилирована, но программа вылетает каждый раз здесь.

Я запускаю свою программу на 8-битном микроконтроллере cortex-M0.

Как я ошибаюсь?

+1

Прекратите писать такой код! Это похоже на вызов неприятностей; Учитывая, что приведения ссылаются на неопределенное поведение. Почему вы не используете 'uint32_t [2]? – Olaf

+1

И Cortex-M0 не является 8-битным процессором! – Olaf

+0

Почему вы не используете указатель? unsigned char * pt = array_add; if ((* (pt)! = 0) || (* (pt + 1)! = 0)) – dante

ответ

-3

Я не уверен, но если массив имеет 8 байт, то просто назначить базовый адрес для long long переменной и сравнить его с 0. Это должно решить проблему проверки, если массив все 0.

Редактировать 1 : После комментария Олафа я бы сказал, что замените long long на int64_t. Однако почему вы не простой цикл для итерации массива и проверки. 8 символов - это все, что вам нужно сравнить.

Редактировать 2: Другим подходом может быть ИЛИ все элементы массива, а затем сравнивать с 0. Если все равны 0, то OR будет равна нулю. Я не знаю, будет ли CMP быстрой или OR. Пожалуйста, обратитесь к документам Cortex-M0 для точного требования к циклам процессора, однако я ожидаю, что CMP будет медленнее.

+0

'long long' не гарантированно сработал 64 бита! Единственное, что верно в OP, это использование типов фиксированной ширины. – Olaf

+0

Стр. 28 из n1570.pdf говорит, что длинный длинный имеет минимальный диапазон, который требует 64 бит. Пожалуйста, обратитесь ко мне в место, где говорится, что 'long long' не гарантированно будет 64 бит. Я пропустил что-то еще в спецификации? – user902384

+2

Вы уже указали соответствующую информацию! Прочтите внимательно! – Olaf

2

Теоретически это может сработать, но на практике есть вещь, которую вы не рассматриваете: выровненные обращения к памяти.

Если uint32_t требует выравненного доступа к памяти (например, 4 байта), то литейному массив unsigned char, который имеет 1 требование выравнивания байта к uint32_t* производит указатель на массив выровненного uint32_t.

По documentation:

Там нет поддержки для выровненных доступов на процессоре Cortex-M0. Любая попытка выполнить операцию с неравнозначным доступом к памяти приводит к исключению HardFault.

На практике это просто опасно и хрупкий код, который вызывает неопределенное поведение в определенных обстоятельствах, как указывал Олафа и лучше объяснить here.

+1

Код также нарушает эффективное правило типа, таким образом вызывает UB (из которого выравнивание является ** одной проблемой **, другие включают оптимизацию компилятора). – Olaf

1

Чтобы проверить несколько байтов, как только код мог использовать memcmp().

Как быстро это зависит в большей степени от компилятора, так как оптимизирующий компилятор может просто испускать код, который делает быстрый 8-байтовый анализ сразу (или 2 4-байтовых). Даже memcmp() может быть не слишком медленным на 8-битном процессоре. Профилирование кода помогает.

Позаботьтесь о микрооптимизации, так как они слишком часто неэффективно используют время кодеров для значительных оптимизаций.

unsigned char array_add[8] = ... 
const unsigned char array_zero[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 
if (memcmp(array_zero, array_add, 8) == 0) ... 

Другой метод использует union. Будьте осторожны, если не считать, что add.arr8[0] является самым или наименее значимым байтом.

union { 
    uint8_t array8[8]; 
    uint64_t array64; 
} add; 

// below code will check all 8 of the add.array8[] is they are zero. 
if (add.array64 == 0) 

В целом, сосредоточиться на написание коды четкой и запасли такие небольшие оптимизации для самых отдельных случаев.