реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Использование offsetof, что то не получается.
Stanislav_S
сообщение Jan 24 2016, 02:59
Сообщение #1


извечный пессимист
*****

Группа: Свой
Сообщений: 1 113
Регистрация: 9-10-06
Из: Днепропетровск
Пользователь №: 21 125



Итак имеем структуру для теста:
CODE
struct
{
uint16_t data0;
uint16_t data1;
uint16_t data2;
uint16_t data3;
uint16_t data4;
uint16_t data5;
}Data_test;

static uint8_t number;


Далее в программе пытаюсь посмотреть:

CODE
number = offsetof(Data_test, data0);


Получаю в ответ:

CODE
Error[Pe029]: expected an expression C:\Project for ARM\LBR004_V1\Sources\main.c 69
Error[Pe028]: expression must have a constant value C:\Project for ARM\LBR004_V1\Sources\main.c 69
Error[Pe018]: expected a ")" C:\Project for ARM\LBR004_V1\Sources\main.c 69


Компилятор IAR ARM, статьи читал, что делаю не так, или я чего то не понял?

smile3046.gif help.gif



--------------------
Slaves are those of this world
Given freedom to lay chains upon The Master
The wolf is no longer free
Release the chains and come for me
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jan 24 2016, 03:33
Сообщение #2


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Текст дефайна offsetof можно найти в хидерах и понять как он работает. В offsetof первым аргументом задаётся ТИП структуры. А не сама структура. Обычно перед объявлением структуры (как переменной) объявляется её тип внутри typedef. При объявлении структур (как типа или переменной) можно задаеть ещё один идентификатор, относящийся к типу, сразу после слова struct. Получится struct name1 {...} name2. В дальнейшем name1 с предворяющим словом struct будет означать тип структуры, в которой имя объявлено. Тогда можно написать number = offsetof(struct name1, data0); Естественно, имя name1 заменить на более подходящее.

Уточню, что в компиляторе не проверял. Может быть какой-то заругается, если не реализовали приведение к типу структур вида (struct name).

Сообщение отредактировал GetSmart - Jan 24 2016, 13:13


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Stanislav_S
сообщение Jan 24 2016, 12:21
Сообщение #3


извечный пессимист
*****

Группа: Свой
Сообщений: 1 113
Регистрация: 9-10-06
Из: Днепропетровск
Пользователь №: 21 125



Цитата(GetSmart @ Jan 24 2016, 08:33) *
Можно попробовать написать number = offsetof(struct name1, data0);

Естественно, имя name1 лучше заменить на более подходящее.

Уточню, что в компиляторе не проверял. Может быть заругается, т.к. не реализовали.


В хидере stddef.h макрос описан так:
CODE
#define offsetof(T, member) (__INTADDR__((&((T *)0)->member)))


Пробовал и такой способ - number = offsetof(struct name1, data0); , то же ругается - Error[Pe393]: pointer to incomplete class type is not allowed.
В статьях люди его используют, точно в так же как и я пытаюсь, но вот результат почему - то разный smile3046.gif


--------------------
Slaves are those of this world
Given freedom to lay chains upon The Master
The wolf is no longer free
Release the chains and come for me
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jan 24 2016, 12:27
Сообщение #4


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(Stanislav_S @ Jan 24 2016, 16:21) *
В статьях люди его используют, точно в так же как и я пытаюсь, но вот результат почему - то разный smile3046.gif

К примеру в вики непонятно написано о offsetof. Если этот оператор не встроенный в компилятор (не обязан быть встроенным по стандарту) и всегда работает через дефайн, то в него ну никак первым аргументом нельзя передать переменную-структуру или юнион. А если бы оператор был встроенным, то в зависимости от реализации.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Stanislav_S
сообщение Jan 24 2016, 12:44
Сообщение #5


извечный пессимист
*****

Группа: Свой
Сообщений: 1 113
Регистрация: 9-10-06
Из: Днепропетровск
Пользователь №: 21 125



Ну вот например - offsetof - embedded, по этой статье пробовал применить на практике. Но вот результат у нас разный sm.gif


--------------------
Slaves are those of this world
Given freedom to lay chains upon The Master
The wolf is no longer free
Release the chains and come for me
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jan 24 2016, 13:16
Сообщение #6


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Вариант из первого поста этой ветки будет работать, но далеко не во всех компиляторах.
например
https://ru.wikipedia.org/wiki/Stddef.h
Цитата
Современные компиляторы реализуют макрос с помощью встроенных функций. Например, реализация gcc выглядит следующим образом[3]:

#define offsetof( st, m ) __builtin_offsetof( st, m )


Точнее может работать. Если в стандарте соответствующей ревизии или расширении, которое поддерживает компилятор внятно написано, что offsetof первым аргументом принимает не только типы, но и переменные.

Сообщение отредактировал GetSmart - Jan 24 2016, 13:26


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 24 2016, 13:28
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Полное объявление типа структуры выглядит так:
Код
typedef struct { здесь список членов } имя_типа;
В плюсах есть более короткая запись
Код
struct имя_типа { здесь список членов };

После такого объявления компилятор знает имена, размеры и взаимное расположение членов и вы можете использовать offsetof:
Код
n = offsetof(имя_типа, имя_члена);

Просто объявление struct имя_типа; - неполное (incomplete) объявление типа. После такого объявления компилятор знает, что где-то будет объявлен такой тип и что этот тип будет структурой. Что будет в этой структуре он не знает, максимум, что он может вам позволить после такого объявления - объявить указатель на эту структуру и присваивания с этим указателем. Ни содержания этой структуры, ни размера ее он не знает, поэтому даже инкремента или декремента такого указателя он сделать не может, не говоря уже о доступе к членам этой структуры.

объявление struct { список членов } имя; объявляет структуру безымянного типа и переменную "имя" этого типа. Поэтому вы не можете использовать "имя" в offsetof, ибо это имя переменной, а не типа.

В обычных Сях возможно объявление struct имя_типа { здесь список членов } имя_переменой; Здесь имя_типа - тоже неполное объявление типа, оно позволяет вставить в структуру указатель на нее же (используется для организации связанных списков), но не более того.

В первом сообщении темы нужно было объявить тип структуры и переменную этого типа:
Код
typedef struct
{
  uint16_t data0;
  uint16_t data1;
  uint16_t data2;
  uint16_t data3;
  uint16_t data4;
  uint16_t data5;
}data_test;

data_test Data_test;
struct data_test Data_test1; //можно и так, но тут ключевое слово struct избыточно
И вот после этого можно было использовать offsetof():
Код
number = offsetof(data_test, data0); // тут используется имя типа "data_test", а не имя переменной!


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Stanislav_S
сообщение Jan 24 2016, 13:34
Сообщение #8


извечный пессимист
*****

Группа: Свой
Сообщений: 1 113
Регистрация: 9-10-06
Из: Днепропетровск
Пользователь №: 21 125



Цитата(GetSmart @ Jan 24 2016, 18:16) *
Вариант из первого поста этой ветки будет работать, но далеко не во всех компиляторах.
например
https://ru.wikipedia.org/wiki/Stddef.h
Точнее может работать. Если в стандарте соответствующей ревизии или расширении, которое поддерживает компилятор внятно написано, что offsetof первым аргументом принимает не только типы, но и переменные.

Спасибо что пнули в нужном направлении, никак не мог понять, что действительно нужен тип объекта, а не его реалзация, вот нормально получилось:
CODE
typedef struct
{
uint16_t data0;
uint16_t data1;
uint16_t data2;
uint16_t data3;
uint16_t data4;
uint16_t data5;
}Data_test_t;

Data_test_t Data_test;

Далее -

CODE
number = offsetof(Data_test_t, data5);


number = 10, как и должно быть, проверил еще на целевом union (для которого все затевалось), то же работает. Спасибо! Но опять же получается это именно фишка IARа?


--------------------
Slaves are those of this world
Given freedom to lay chains upon The Master
The wolf is no longer free
Release the chains and come for me
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jan 24 2016, 13:40
Сообщение #9


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(Сергей Борщ @ Jan 24 2016, 17:28) *
Полное объявление типа структуры выглядит так:
Код
typedef struct { здесь список членов } имя_типа;
В плюсах есть более короткая запись
Код
struct имя_типа { здесь список членов };

Полное объявление как раз состоит из двух имён. И после такого полного объявления хоть типа, хоть сразу переменной можно ниже по тексту создавать такие же переменные. То есть после такого полного объявления выше по коду можно объявлять так
Код
struct name1 var1,var2;

Смысл первого имени в объявлении структур, юнионов и энумов, а так же здесь указанных переменных, интересно, как иначе можно толковать.

упд
Цитата
В обычных Сях возможно объявление struct имя_типа { здесь список членов } имя_переменой; Здесь имя_типа - тоже неполное объявление типа, оно позволяет вставить в структуру указатель на нее же (используется для организации связанных списков), но не более того.

Возможно более. Т.к. и вне структуры можно создавать через первое имя переменные с типом этой структуры. А это значит, что пара struct name1 должна означать (преобразовываться в) тип структуры и по логике должна съедаться во всех местах, принимающих тип. В т.ч. в type-cast. Иначе это какая-то необоснованная кастрация.

Сообщение отредактировал GetSmart - Jan 24 2016, 13:50


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Stanislav_S
сообщение Jan 24 2016, 13:40
Сообщение #10


извечный пессимист
*****

Группа: Свой
Сообщений: 1 113
Регистрация: 9-10-06
Из: Днепропетровск
Пользователь №: 21 125



Цитата(Сергей Борщ @ Jan 24 2016, 18:28) *
Полное объявление типа структуры выглядит так:

Сергей, спасибо за развернутый ответ - не знал об этой осбенности - думал если объявил структуру, то компилятор знает о ней все. Еще раз спасибо - одним пробелом меньше.


--------------------
Slaves are those of this world
Given freedom to lay chains upon The Master
The wolf is no longer free
Release the chains and come for me
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 24 2016, 13:50
Сообщение #11


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(GetSmart @ Jan 24 2016, 15:40) *
Полное объявление как раз состоит из двух имён. И после такого полного объявления хоть типа, хоть сразу переменной можно ниже по тексту создавать такие же переменные.
Не совсем понял, а может и я неточно выразился. Да, после такого объявления можно писать struct name1 var1,var2;, а вот писать name1 var1,var2; нельзя, то есть name1 как бы еще не совсем тип. Полным типом он станет в сочетании с ключевым словом struct и мне кажется проще написать один раз typedef, чем засорять потом весь остальной исходник дополнительным struct в каждом месте, где нужно упомянуть тип.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jan 24 2016, 13:55
Сообщение #12


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(Сергей Борщ @ Jan 24 2016, 17:50) *
Полным типом он станет в сочетании с ключевым словом struct...

Станет. Должен становиться. Но у ИАРа видимо своё мнение на этот счёт.

упд
То есть логичнее всего считать первое имя типом структуры из области видимости слова struct. И пара struct name1 должна преобразовываться в полноценный тип, съедаемый везде.

Сообщение отредактировал GetSmart - Jan 24 2016, 14:11


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 24 2016, 14:02
Сообщение #13


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(GetSmart @ Jan 24 2016, 15:55) *
Станет. Должен становиться. Но у ИАРа видимо своё мнение на этот счёт.

ГЦЦ согласен с ИАРом. Точнее они оба согласны со стандатром, но вам виднее:
Код
// test.c:
struct a
{
    int A;
} A;

a B;

Код
Compiling: test.c
test.c:7:1: error: unknown type name 'a'
a B;
^


P.S. поправил, для полного совпадения


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jan 24 2016, 14:12
Сообщение #14


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(Сергей Борщ @ Jan 24 2016, 18:02) *
P.S. поправил, для полного совпадения

О таком применении речи не было. Только в паре со struct. Чуть выше дополнил.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 24 2016, 14:23
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Сергей Борщ @ Jan 24 2016, 15:50) *
Полным типом он станет в сочетании с ключевым словом struct и мне кажется проще написать один раз typedef, чем засорять потом весь остальной исходник дополнительным struct в каждом месте, где нужно упомянуть тип.

Поддержу.
Без typedef только объявления анонимных вложенных структур, это все для чего нужны кастрированные варианты.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd June 2025 - 14:32
Рейтинг@Mail.ru


Страница сгенерированна за 0.015 секунд с 7
ELECTRONIX ©2004-2016