Перейти к содержанию
    

WinAVR и адрес статической функции

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Гость Maddy

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

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И как быть бедному gcc ?
Так же, как и в случае с указателем на функцию. Почему у gcc для других платформ с этим проблем не возникает?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Гость Maddy

Хм ...

long handleTimersISR(void);

static U8 data[]={0,0,((U32)handleTimersISR >>24)& 0xff,((U32)handleTimersISR >>16)& 0xff,((U32)handleTimersISR >>8)& 0xff,((U32)handleTimersISR )& 0xff };

 

..\072-cxxV2\fwcommon\boards\072-Cxx\bsp_hw_timersInit.c:17: error: initializer element is not constant

..\072-cxxV2\fwcommon\boards\072-Cxx\bsp_hw_timersInit.c:17: error: (near initialization for 'data[2]')

..\072-cxxV2\fwcommon\boards\072-Cxx\bsp_hw_timersInit.c:17: error: initializer element is not constant

..\072-cxxV2\fwcommon\boards\072-Cxx\bsp_hw_timersInit.c:17: error: (near initialization for 'data[3]')

..\072-cxxV2\fwcommon\boards\072-Cxx\bsp_hw_timersInit.c:17: error: initializer element is not constant

..\072-cxxV2\fwcommon\boards\072-Cxx\bsp_hw_timersInit.c:17: error: (near initialization for 'data[4]')

..\072-cxxV2\fwcommon\boards\072-Cxx\bsp_hw_timersInit.c:17: error: initializer element is not constant

..\072-cxxV2\fwcommon\boards\072-Cxx\bsp_hw_timersInit.c:17: error: (near initialization for 'data[5]')

 

И я ему верю ;) Ибо все-таки адрес функции хоть и константа , но на этом этапе не определена ;)

avr32-gcc.EXE (AVR_Toolchain_3.0_124) 4.3.3

 

или опять приколы Атмеловцев ?

 

НЕ winAVR но gcc ж)

Изменено пользователем Maddy

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Почему у gcc для других платформ с этим проблем не возникает?

У gcc с указателями иногда очень странные отношения.

Вот пример:

struct rec1 {
    int field1;
    int field2;
};

#define prec1 ((rec1 *) 0x10000)

static const int field2addr = (uint32_t)&prec1->field2;    // строка 1

class testcase2
{
    static const int field2addr = (uint32_t)&prec1->field2;   // строка 2
};

 

Строку 1 - проглатывает, а строку 2 - нет:

tests.cpp:64:43: error: a cast to a type other than an integral or enumeration type cannot appear in a constant-expression

tests.cpp:64:50: error: '->' cannot appear in a constant-expression

tests.cpp:64:50: error: '&' cannot appear in a constant-expression

Почему так - не понимаю...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Через него и выкрутился:

    static const int field2addr = 0x10000 + offsetof(rec1, field2);

Но это несколько коряво, ибо пришлось вытаскивать константу 0x10000 (в реале это адрес регистровой структуры).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У gcc с указателями иногда очень странные отношения.

 

Строку 1 - проглатывает, а строку 2 - нет:

Почему так - не понимаю...

Потому что (статические) члены классов не инициализируют таким образом, как у Вас в строке 2. Вот такой вариант:

class testcase2
{
   static const int field2addr;
};
const int testcase2::field2addr = (uint32_t)&prec1->field2;

gcc компилирует без замечаний.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Статические int-ы легко инициализируются таким образом:

class testcase2
{
    static const int test_static_const_int = 0x12345;
};

Кроме того, в enum-ах инициализация указателем тоже не проходит, на

class testcase2
{
    enum { field2addr = (uint32_t)&prec1->field2 };
};

-- ругается точно так же. Так что дело не в статике. Но за способ обхода - спасибо:)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Статические int-ы легко инициализируются таким образом:

class testcase2
{
    static const int test_static_const_int = 0x12345;
};

Нашел соответствующее место в спецификации языка, вроде бы все правильно. Такая форма требует constant expression в правой части, а constant expression, в свою очередь, может содержать только литералы, перечисления, const переменные интегральных типов и sizeof(). Указатели под перечисленное не подпадают.

 

И еще в constant expression допускаются приведения только к интегральным типам или перечислениям, поэтому компилятор совершенно справедливо ругается на (rec1 *)0x10000.

Изменено пользователем alx2

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нашел соответствующее место в спецификации языка
Языка - C++? А когда мы объявляем вне класса, то срабатывает совместимость с Си, а там это можно? Если так, то немного проясняется, спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Языка - C++?
Да, конечно.

А когда мы объявляем вне класса, то срабатывает совместимость с Си, а там это можно?
Ничего не "срабатывает". Просто то, что у Вас в строке 1 и в строке 2 - это две разные семантические конструкции, и они подчиняются разным правилам языка C++. В строке 1 инициализатор не обязан быть integral constant expression, в строке 2 - обязан.
Изменено пользователем alx2

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

в строке 1 и в строке 2 - это две разные семантические конструкции

А в чём разница? Можно какую-нибудь цитату из стандарта?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно какую-нибудь цитату из стандарта?

Конечно. Подпункт 4 пункта 9.4.2 по версии ISO:

If a static data member is of const integral or const enumeration type, its declaration in the class

definition can specify a constant-initializer which shall be an integral constant expression (5.19).

А это из подпункта 1 пункта 5.19:

An integral constant-expression can involve only literals (2.13), enumerators, const variables or static

data members of integral or enumeration types initialized with constant expressions (8.5), non-type

template parameters of integral or enumeration types, and sizeof expressions. ... Only type conversions

to integral or enumeration types can be used. In particular, except in sizeof expressions, functions, class objects,

pointers, or references shall not be used,...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Конечно. Подпункт 4 пункта 9.4.2 по версии ISO:

На мой взгляд, эта цитата не о том, что это две разные семантические конструкции. А только лишь о том, что на инициализацию статической константной переменной-члена внутри объявления класса накладываются некоторые дополнительные ограничения.

В любом случае, спасибо за цитату, теперь понятно в чём дело.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...