LINUX.ORG.RU
Ответ на: комментарий от gaa

Да, приоритет не соблюдается, правильно так:

uint16_t var = (highbyte << 8) + lowbyte;

Все получилось, спасибо.

LX ★★
() автор топика
Ответ на: комментарий от Davidov

>А чем плох union?

(Не считая многословности)

Davidov ★★★★
()
Ответ на: комментарий от Davidov

> А чем плох union?

struct { char low, high; } или struct { char high, low; } ? А если вдруг компилятору приспичит выравнивать чары не по байтам, а по два байта, скажем?

const86 ★★★★★
()
Ответ на: комментарий от Davidov

>>Вместо '+' лучше писать '|'

>Интересно, gcc одинаковым образом откомпилирует код?

По-разному (4.3.3). Причём под i386 + превращается в add, а | - в or и общее количество операций одинаковое. А под x86_64 + делается через lea и получается на одну операцию короче...

const86 ★★★★★
()
Ответ на: комментарий от const86

>struct { char low, high; } или struct { char high, low; } ?

Верно, но с другой стороны мы знаем очерёдность байтов в памяти. Если мы записываем данные файл, то это может быть важнее.

>А если вдруг компилятору приспичит выравнивать чары не по байтам, а по два байта, скажем?

А вот это интересный вопрос, да. Похоже, здесь кросплатформенного способа решения нет. Но всегда можно указать __pack__, если речь идёт про gcc.

Davidov ★★★★
()
Ответ на: комментарий от const86

> А если вдруг компилятору приспичит выравнивать чары не по байтам, а по два байта, скажем?

А еще он может прикола ради заменить << на >>.

tailgunner ★★★★★
()
Ответ на: комментарий от LX

>Да, приоритет не соблюдается, правильно так:

>uint16_t var = (highbyte << 8) + lowbyte;

В данном случае разницы нет, но _идеологически_ правильнее так:

(highbyte << 8) | lowbyte;

KRoN73 ★★★★★
()
Ответ на: комментарий от Davidov

>Интересно, gcc одинаковым образом откомпилирует код?

По идее, в первом случае будет add, во втором - or.

KRoN73 ★★★★★
()
Ответ на: комментарий от imp

>((char*)dest)[0] = high; ((char*)dest)[1] = low;

Здравствуйте, взращённые x86 платформой! :)

На PDP, например, ты на этом словишь аппаратное исключение.

KRoN73 ★★★★★
()
Ответ на: комментарий от tailgunner

Пардон, склероз. Это доступ к команде по нечётному адресу - ошибка.

...

Хотя, боюсь (точно уже не помню, давно было), на PDP sizeof(char) всё равно равен двум. Так что нужного эффекта автор кода всё равно не получит :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

> Хотя, боюсь (точно уже не помню, давно было), на PDP sizeof(char) всё равно равен двум

Нет. PDP-11 - очень традиционная машина. Экзотикой была PDP-10.

tailgunner ★★★★★
()
Ответ на: комментарий от Absurd

>В ANSI C89 sizeof(char) всегда равен одному.

Ну, ты понял, что я имел в виду. Речь о том, что char там - два байта.

KRoN73 ★★★★★
()
Ответ на: комментарий от tailgunner

>> А если вдруг компилятору приспичит выравнивать чары не по байтам, а по два байта, скажем?

> А еще он может прикола ради заменить << на >>.

Компиляторы - тоже люди и они тоже умеют шутить :)

const86 ★★★★★
()
Ответ на: комментарий от KRoN73

>Здравствуйте, взращённые x86 платформой! :)

Ну да, на big-endian системах все наоборот, только программист обычно знает под какую систему пишет. На крайняк можно по ifdef 2 варианта поставить. А код можно просто скомпилять и в дебаггере посмотреть работает или нет - чем флейм разводить.

imp ★★
()
Ответ на: комментарий от imp

> код можно просто скомпилять и в дебаггере посмотреть работает или нет - чем флейм разводить.

Лучше написать так, чтобы просто работало. Не умничая.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>> код можно просто скомпилять и в дебаггере посмотреть работает или нет - чем флейм разводить.
> Лучше написать так, чтобы просто работало. Не умничая.


Так неинтересно. Надо ж пальцы погнуть!

gaa ★★
()
Ответ на: комментарий от KRoN73

>Здравствуйте, взращённые x86 платформой!

Дело еще хуже - этого треда не должно быть вообще. Работа с отдельными битами это одна из самых простых вещей которая должна быть подвластна любому программисту.

Absurd ★★★
()
Ответ на: комментарий от josephson

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

josephson ★★
()
Ответ на: комментарий от josephson

>В начальном вопросе топикстартера не оговаривался порядок расположения байт в приёмнике.

Именно. Поэтому вариант с «s = (hb << 8) | lb» формально корректный, а вариант с memset - нет.

Я уже не говорю про то, что в варианте с присваиванием переменная может сохраниться в регистре, что положительно скажется на оптимизации.

KRoN73 ★★★★★
()
Ответ на: комментарий от mv

>>Песец, сколько перлов в треде. Как страшно жить...

вопрос только в том - а НАФИГА? ;-) память экономим?

deadman ★★
()
Ответ на: комментарий от LX

> Да, приоритет не соблюдается, правильно так:
> uint16_t var = (highbyte << 8) + lowbyte;

> Все получилось, спасибо.


А вот что по этому рецепту получилось у меня:

$ cat a.cpp
#include <stdio.h>
int main() {
char high = 0x55;
char low = 0x88;
short result = (high << 8) | low;
return !printf("result = %x\n", 0xffff & result);
}
$ g++ ./a.cpp
$ ./a.out
result = ff88

А вовсе не 5588.

Действительно, что ни рецепт - то пёрл.

alexsaa
()
Ответ на: комментарий от imp

> Ну да, на big-endian системах все наоборот, только программист обычно знает под какую систему пишет. На крайняк можно по ifdef 2 варианта поставить. А код можно просто скомпилять и в дебаггере посмотреть работает или нет - чем флейм разводить.

Ага, а сколько потом будет обсуждений по поиску глюков этого чудесного продукта на других платформах, автора уже не интересует.

alexsaa
()
Ответ на: комментарий от alexsaa

мать вашу! програмёры, блин!

char -- в данном случае -- 8 bit. посему и high << 8 == 0, всегда!

а вот если заменить char на int или short -- то и будет вам щастье.

beastie ★★★★★
()
Ответ на: комментарий от beastie

Гы, а пёрлов всё больше ;-)

>мать вашу! програмёры, блин!

>char -- в данном случае -- 8 bit. посему и high << 8 == 0, всегда!


#include <stdio.h>
int main() {
char high = 0x55;
printf ("%s\n", high << 8 == 0 ? "programmers blin" : "epic fail");
return 0;
}

alexsaa
()
Ответ на: комментарий от alexsaa

#include <stdio.h>
int main() {
char high = 0x55;
printf("%s\n", (char)(high << 8) == 0 ? "programmers blin" : "epic fail");
return 0;
}

Ы?

beastie ★★★★★
()
Ответ на: комментарий от alexsaa

в общем, alexsaa, не позорься. в printf у тебя вышло неявное приведении типов к int, который является в сях типом по умолчанию.

beastie ★★★★★
()
Ответ на: комментарий от beastie

я не согласен с тем, что "(high << 8) == 0" и "((char)(high << 8)) == 0" - одно и то же. /* Необязательные скобки я здесь расставил для ясности. */

alexsaa
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.