Форум программистов, компьютерный форум CyberForum.ru

C для начинающих

Войти
Регистрация
Восстановить пароль
 
 
ArtemKolesnikov
23 / 23 / 10
Регистрация: 14.07.2016
Сообщений: 79
#1

Что означает *(uint8_t*)(&pbuf)? - C (СИ)

07.01.2017, 23:14. Просмотров 497. Ответов 22
Метки нет (Все метки)

Всем привет,
C
1
2
uint8_t *pbuf
uint8_t memtype;
Что делается в выражении
C
1
  memtype = *(uint8_t*)(&pbuf);
???
Спасибо.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
likehood
470 / 351 / 117
Регистрация: 25.12.2016
Сообщений: 1,107
Завершенные тесты: 3
08.01.2017, 08:49     Что означает *(uint8_t*)(&pbuf)? #2
Адрес переменной pbuf приводится к типу "указатель на uint8_t", после чего значение по этому адресу записывается в переменную memtype (с неявным преобразованием к типу uint8_t). Иными словами, в memtype заносится адрес переменной, на которую указывает pbuf. Смысл этой конструкции для меня остаётся загадкой.

Добавлено через 9 часов 9 минут
Ещё важно отметить, что преобразование указателя к типу uint8_t происходит с потерей старших байтов, поскольку тип uint8_t - восьмибитный, и адрес в него никак не влезет. Поэтому остаётся неясным, зачем вообще может понадобится такая конструкция.
Fulcrum_013
609 / 694 / 72
Регистрация: 14.12.2014
Сообщений: 5,414
Завершенные тесты: 3
08.01.2017, 09:41     Что означает *(uint8_t*)(&pbuf)? #3
Цитата Сообщение от likehood Посмотреть сообщение
Поэтому остаётся неясным, зачем вообще может понадобится такая конструкция.
К примеру затем чтобы поиметь младшие 8 разрядов адреса. Если это выдрано из какого нибудь менеджера кучи то может быть очень даже актуальной для решения общей задачи операцией.
likehood
470 / 351 / 117
Регистрация: 25.12.2016
Сообщений: 1,107
Завершенные тесты: 3
08.01.2017, 10:11     Что означает *(uint8_t*)(&pbuf)? #4
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
К примеру затем чтобы поиметь младшие 8 разрядов адреса.
В принципе, из кода это понятно. Но, чтобы у читателя не возникало сомнений, я бы назвал переменную memtype как-то по другому. Например, address_low_byte. Тем самым подчеркнув, что мы понимаем, что делаем, и нам действительно нужен только младший байт.
Fulcrum_013
609 / 694 / 72
Регистрация: 14.12.2014
Сообщений: 5,414
Завершенные тесты: 3
08.01.2017, 11:04     Что означает *(uint8_t*)(&pbuf)? #5
Цитата Сообщение от likehood Посмотреть сообщение
Тем самым подчеркнув, что мы понимаем, что делаем, и нам действительно нужен только младший байт.
Не факт что он младший. Это платформозависимо. Может быть как раз и старшим который в данной реализации менеджера кучи определяет тип памяти куда указывает указатель (стек/сегмент данных/сегмент кода/куча/common область и т.п.).
likehood
470 / 351 / 117
Регистрация: 25.12.2016
Сообщений: 1,107
Завершенные тесты: 3
08.01.2017, 12:04     Что означает *(uint8_t*)(&pbuf)? #6
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Не факт что он младший.
Странно, мне казалось, что преобразование типов выполняется вполне однозначным образом. Другое дело, что адрес может по разному храниться в переменной-указателе. Но само преобразование одного целого числа в другое, меньшее по размеру, разве зависит от платформы?
Fulcrum_013
609 / 694 / 72
Регистрация: 14.12.2014
Сообщений: 5,414
Завершенные тесты: 3
08.01.2017, 12:25     Что означает *(uint8_t*)(&pbuf)? #7
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от likehood Посмотреть сообщение
Другое дело, что адрес может по разному храниться в переменной-указателе.
Вот правильно тут как раз и берут первый байт адреса. т.е. к uint8_t* приводят не сам buf а &buf - т.е. адрес указателя. а потом по этому адресу берут первый байт.

Добавлено через 10 минут
т.е.&buf приводят к типу uint8_t* а потом извлекают значение по этому указателю. поскольку указатель имеет тип uint8_t* то и извлекается один байт который уже ни к чему не приводится при присваивании.
likehood
470 / 351 / 117
Регистрация: 25.12.2016
Сообщений: 1,107
Завершенные тесты: 3
08.01.2017, 12:28     Что означает *(uint8_t*)(&pbuf)? #8
Да, теперь понял. Спасибо.
Evg
Эксперт CАвтор FAQ
17311 / 5559 / 347
Регистрация: 30.03.2009
Сообщений: 15,127
Записей в блоге: 26
08.01.2017, 12:38     Что означает *(uint8_t*)(&pbuf)? #9
Цитата Сообщение от likehood Посмотреть сообщение
Странно, мне казалось, что преобразование типов выполняется вполне однозначным образом
В том-то и дело, что тут нет преобразования типов. Преобразование типов работает над значениями, в то время, как ты хочешь получить сначала битовый образ значения, а потом выковырять из него нужный набор битов и уже их превратить в значение нужного типа

Смысл конкретно данного примера мне так же непонятен. Если это фрагмент какого-то менеджера памяти, то логика его работы будет различаться на big-endian и little-endian
zer0mail
Заблокирован
08.01.2017, 14:24     Что означает *(uint8_t*)(&pbuf)? #10
Не пойму, чем memtype = *(uint8_t*)(&pbuf); отличается от memtype = *pbuf;
Evg
Эксперт CАвтор FAQ
17311 / 5559 / 347
Регистрация: 30.03.2009
Сообщений: 15,127
Записей в блоге: 26
08.01.2017, 15:26     Что означает *(uint8_t*)(&pbuf)? #11
Цитата Сообщение от zer0mail Посмотреть сообщение
Не пойму, чем memtype = *(uint8_t*)(&pbuf); отличается от memtype = *pbuf;
Если бы было написано "memtype = *(uint8_t*) pbuf;", то ничем. Но тут стоит &pbuff
ArtemKolesnikov
23 / 23 / 10
Регистрация: 14.07.2016
Сообщений: 79
08.01.2017, 17:39  [ТС]     Что означает *(uint8_t*)(&pbuf)? #12
Всем огромное спасибо за участие!
Я могу привести весь код функции (это из готового официального примера от производителя), там потом полученное значение сравнивается с магическими (для меня) константами и pbuf приводится к data, xdata или pdata. и выполняется действие по макросу
Кликните здесь для просмотра всего текста

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
uint16_t hal_nrf_read_multibyte_reg(uint8_t reg, uint8_t *pbuf)
{
  uint8_t ctr, length;
  uint8_t memtype;
  uint8_t read_byte; /*lint -esym(530,read_byte) symbol not initialized*/
  bool first_round;
  first_round = true;
 
  memtype = *(uint8_t*)(&pbuf);
 
  switch(reg)
  {
    case HAL_NRF_PIPE0:
    case HAL_NRF_PIPE1:
    case HAL_NRF_TX:
      length = ctr = hal_nrf_get_address_width();
      CSN_LOW();
      hal_nrf_rw(RX_ADDR_P0 + reg);
      break;
 
    case HAL_NRF_RX_PLOAD:
      reg = hal_nrf_get_rx_data_source();
      if (reg < 7U)
      {
        length = ctr = hal_nrf_read_rx_payload_width();
        CSN_LOW();
        hal_nrf_rw(R_RX_PAYLOAD);
      }
      else
      {
        ctr = length = 0U;
      }
      break;
 
    default:
      ctr = length = 0U;
      break;
  }
 
  if (memtype == 0x00U)
  {
    uint8_t data *buf = (uint8_t data *)pbuf;
    NRF_READ_MULTIBYTE_REG_COMMON_BODY
  }
  else if (memtype == 0x01U)
  {
    uint8_t xdata *buf = (uint8_t xdata *)pbuf;
    NRF_READ_MULTIBYTE_REG_COMMON_BODY
  }
  else if (memtype == 0xFEU)
  {
    uint8_t pdata *buf = (uint8_t pdata *)pbuf;
    NRF_READ_MULTIBYTE_REG_COMMON_BODY
  }
  else
  {
    uint8_t *buf = (uint8_t *)pbuf;
    NRF_READ_MULTIBYTE_REG_COMMON_BODY
  }
 
  CSN_HIGH();
 
  return (((uint16_t) reg << 8) | length);
}
Evg
Эксперт CАвтор FAQ
17311 / 5559 / 347
Регистрация: 30.03.2009
Сообщений: 15,127
Записей в блоге: 26
08.01.2017, 17:52     Что означает *(uint8_t*)(&pbuf)? #13
Цитата Сообщение от ArtemKolesnikov Посмотреть сообщение
Я могу привести весь код функции
Без описания используемых в нём макросов он малополезен
Кому интересен оригинал, видимо, следует заглянуть сюда https://github.com/elechouse/Wireles.../src/hal_nrf.c
ArtemKolesnikov
23 / 23 / 10
Регистрация: 14.07.2016
Сообщений: 79
08.01.2017, 18:07  [ТС]     Что означает *(uint8_t*)(&pbuf)? #14
Цитата Сообщение от Evg Посмотреть сообщение
Без описания используемых в нём макросов он малополезен
Ну почему же, макросы к теме не относятся, а будут отвлекать внимание. К тому же, если вы обратили внимание, они одинаковы в каждом случае при сравнении значения memtype с магическими (для меня) значениями. Вопрос был про выражение.
Это код из программного обеспечения к комплекту разработчика от производителя чипа. Скачивается на официальном сайте (без гитхаба). чип nRF24LE1.
Evg
Эксперт CАвтор FAQ
17311 / 5559 / 347
Регистрация: 30.03.2009
Сообщений: 15,127
Записей в блоге: 26
08.01.2017, 18:51     Что означает *(uint8_t*)(&pbuf)? #15
Цитата Сообщение от ArtemKolesnikov Посмотреть сообщение
К тому же, если вы обратили внимание, они одинаковы в каждом случае
Это они для тебя, как для начинающего одинаковы. Я, например, более чем уверен, что макрос NRF_READ_MULTIBYTE_REG_COMMON_BODY раскрывается во что-то, что использует переменную "buf", которая имеет разный тип в каждом из блоков. Причём даже не понятно, что за тип, потому что по внешнему виду имеет место быть синтаксическая ошибка, так что либо uint8_t, либо data/xdata/pdata являются макросами. Либо какое-то нестандартное расширение Си в компиляторе под этот девайс

Цитата Сообщение от ArtemKolesnikov Посмотреть сообщение
Вопрос был про выражение
Для тебя вопрос по языку исчерпан, хотя лично я более чем уверен в том, что ты не понимаешь, что конкретно этот код делает. Так же как и прочие не понимают, ради чего в код включена такая извращённая конструкция. Наверняка найдётся и те, кому станет интересно, что же там такое, бесприменительно к тому, поймёшь ты это, или нет. Собственно, для них и поместил ссылку
ArtemKolesnikov
23 / 23 / 10
Регистрация: 14.07.2016
Сообщений: 79
08.01.2017, 19:22  [ТС]     Что означает *(uint8_t*)(&pbuf)? #16
Цитата Сообщение от Evg Посмотреть сообщение
кому станет интересно, что же там такое
Без железа на руках (на столе перед глазами)?
Цитата Сообщение от Evg Посмотреть сообщение
Для тебя вопрос по языку исчерпан

Не по теме:

Любой вопрос на любом форуме исчерпан только тогда, когда задавший вопрос (ТС) вопрос сам для себя решит, что он во всем разобрался не без помощи тех, кто помог ему в этом разобраться и дал правильный намек.
А товарищи, которые сидят (на попе) и умничают "Я вот такой супер-пупер умный и крутой, а ты не разобрался, и никто не разобрался, и вообще ничего не понимаешь в своем коде (в своей теме)..." и т.д. заслуживают ЧСВ lv. 9000 (если он им ранее не присвоен). Я сталкивался с такими давно на отдельном радио-кошачем форуме. Ну, бывает, что скажешь.
В моей профессии (я инженер-электрик, не программист) такие коллеги тоже есть. Я обычно молчу и даю им выговариваться сколько душе угодно. Кто-где учился и кто-что умеет, на какой подстанции работал/работает, с каким оборудованием и т.д. Тык...
Ну хочется человеку потешить свое эго, ну разве можно у него отнимать эту игрушку? Обидится же, если отнять.

LFC
617 / 421 / 261
Регистрация: 17.09.2015
Сообщений: 1,256
09.01.2017, 06:29     Что означает *(uint8_t*)(&pbuf)? #17
Цитата Сообщение от ArtemKolesnikov Посмотреть сообщение
заслуживают ЧСВ lv. 9000 (если он им ранее не присвоен).
ну вот,вместо того чтобы поблагодарить за науку,взял нахамил
ArtemKolesnikov
23 / 23 / 10
Регистрация: 14.07.2016
Сообщений: 79
09.01.2017, 11:37  [ТС]     Что означает *(uint8_t*)(&pbuf)? #18
Цитата Сообщение от LFC Посмотреть сообщение
поблагодарить за науку,взял нахамил
Покажите пожалуйста (может я слепой/тупой), за какую науку благодарить и кому "нахамил" то ?

Вас тоже нужно отблагодарить за ваше ценное замечание?
Ок, спасибо.
Вообще вопрос решен, я объяснение получил, а дальше сам буду вникать в глубокие конкретные подробности, параллельно разбераясь с volatile.
HighPredator
5429 / 1812 / 332
Регистрация: 10.12.2010
Сообщений: 5,369
Записей в блоге: 3
09.01.2017, 11:42     Что означает *(uint8_t*)(&pbuf)? #19
Судя по тому, что я вижу в этом коде, инструкция
C
1
memtype = *(uint8_t*)(&pbuf);
есть конверсия указателя на тип uint8_t** в целое типа uint8_t. Причем каст к uint8_t* и разыменование дает эффект реинтерпритации байтов pbuf как uint8_t. По аналогии с плюсовым reinterpret_cast-ом. Что касается "почему именно так", мне думается просто из-за того, что нужно было валидное и портабельное решение. И, навскидку точно не скажу, но на глаз похоже, что оно еще и endian-независимое.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.01.2017, 11:56     Что означает *(uint8_t*)(&pbuf)?
Еще ссылки по теме:

C (СИ) Что означает конструкция #if 0
Что означает символ $? C (СИ)
Что означает запись 1LL? C (СИ)
C (СИ) Что означает условие if(!in)
C (СИ) Что означает запись .5?

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Evg
Эксперт CАвтор FAQ
17311 / 5559 / 347
Регистрация: 30.03.2009
Сообщений: 15,127
Записей в блоге: 26
09.01.2017, 11:56     Что означает *(uint8_t*)(&pbuf)? #20
Цитата Сообщение от HighPredator Посмотреть сообщение
И, навскидку точно не скажу, но на глаз похоже, что оно еще и endian-независимое
Зависимое. Для little endian берутся младшие 8 бит адреса, а для big-endian - старшие. Поскольку речь идёт о софте для конкретного процессора, то этот момент с общей точки зрения непринципиален. А по сути надо лезть в исходники и смотреть.

Как вариант вполне может быть так, что железка big-endian и в ней пространство физических адресов раскидано по сегментам с разными свойствами. Типа того, что сегменты с адресами 0x0000-0x00ff, 0x0100-0x01ff, 0xfe00-0xfeff обладают какими-то особыми свойствами. Но это мои догадки из разряда "ткнуть пальцем в небо", что бы понять, что там в реальности, надо подробно изучать весь исходник и описание железки
Yandex
Объявления
09.01.2017, 11:56     Что означает *(uint8_t*)(&pbuf)?
Ответ Создать тему
Опции темы

Текущее время: 12:51. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru