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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> куча const..., элементарный вопрос по Си
cf7k
сообщение Aug 29 2009, 05:26
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 82
Регистрация: 14-03-06
Из: Санкт-Петербург
Пользователь №: 15 227



Дожился... smile.gif Помогите чайнику.

Итак... вводная: пользую PIC24H, пишу на Си (без плюсов), компилятор - С30, уже скурил весь гугль, учебники по сям...

имею определение интерфейса (структуру указателей на функции):
Код
typedef struct
{
    void (*FunctionPointer)  (char Param);
    int  (*OtherFuncPointer) (int SomeParam);
    ....
} PWInterface, *pPWInterface, **ppPWInterface;

Далее имеется несколько модулей, реализующих некое поведение и предоставляющих указанный интерфейс:
Код
заголовочный файл:
extern const PWInterface const PWMonitor0;

Код
сишный файл с реализацией:
static void    SomeFunc1 (char Param);
static void    SomeFunc2 (int SomeParam);

const PWInterface const PWMonitor0 =
    {
        &SomeFunc1,
        &SomeFunc2,
        ....
    };
ну и далее реализация этих функций.
таких модулей несколько, все предоставляют означенный в начале интерфейс. Т.е. я сознательно выделяю память в памяти программ и пишу дважды const.

Далее собираю интерфейсы в одну кучу:
Код
#include "PWMonitor0.h"
#include "PWMonitor1.h"        
#include "PWMonitor2.h"
....................

const PWInterface    *const PWMonMode1Arr[] = {&PWMonitor0, &PWMonitor0_c, &PWMonitor0_r};
const PWInterface    *const PWMonMode2Arr[] = {&PWMonitor1, &PWMonitor1_r};
const PWInterface    *const PWMonMode3Arr[] = {&PWMonitor2};
Т.е. массивы константных указателей на константные структуры заданного типа.
конструкцию представленную выше компилятор поглощает без проблем, а если же пользую
Код
const pPWInterface    const PWMonMode1Arr[] = ...
получаю warning: initialization discards qualifiers from pointer target type
Вопрос первый: Что именно я недопонимаю? Хотел как лучше (чтоб через typedef... красившее. Вроде корректно определенный тип указателя при определении структуры)...

Продолжу...
далее имея массивы(константные) (константных)указателей на (константные)интерфейсы, собираю их в свою очередь в массив(тоже константный):
Код
const ppPWInterface const Pathways[]    = {&PWMonMode1Arr, &PWMonMode2Arr, &PWMonMode3Arr};

чтоб можно было бы где-то в коде сказать нечто подобное:
result = Pathways[PowerMode][ID]->OtherFuncPointer(somecode);
Вот тут(при определении массива, а не на вызове метода интерфейса) уже имею трижды warning: initialization from incompatible pointer type
Пробовал разные вариации... но, видимо, не все...
Вопрос второй: как сделать правильно?

Компилятор, в общем-то, понимает что я от него хочу. Память распределяет правильно, инициализирует правильно, все компилируется... но этот варнинг... я ж из-за него невыспался. wink.gif

Уфффф... спасибо за терпение дочитавшим сий опус smile.gif
Go to the top of the page
 
+Quote Post
Student Pupkin
сообщение Aug 29 2009, 14:26
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 23-05-08
Пользователь №: 37 760



Я чайник smile.gif . И помочь ничем не смогу. Но хочу спросить (в целях самообразования) - а что значит вот это объявление?
Цитата(cf7k @ Aug 29 2009, 09:26) *
Код
заголовочный файл:
extern const PWInterface const PWMonitor0;

Я в смысле как это укладывается в общую схему объявления переменной?
[класс памяти] [const] тип имя [инициализатор] - в данном случае [класс памяти] -extern, тип - структура с именем PWInterface, определенным с помощью typedef, имя переменной - PWMonitor0.... А второй const (...PWInterface const PWMonitor0) - это что такое? А то получается что-то наподобие "extern const int const var1"....
Здесь мне тоже ничего не понятно:
Цитата(cf7k @ Aug 29 2009, 09:26) *
Код
const PWInterface const PWMonitor0 =
    {
        &SomeFunc1,
        &SomeFunc2,
        ....
    };

Надеюсь, мне по ходу дела объясните smile.gif .
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Aug 29 2009, 15:11
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(cf7k @ Aug 29 2009, 08:26) *
Дожился... smile.gif

Я делаю все попроще.

typedef void (*VECTORS)();
const VECTORS function[FUNCTION_QTY]={function1, function2, };

вызов:
function[function_index]();

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


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
cf7k
сообщение Aug 29 2009, 15:18
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 82
Регистрация: 14-03-06
Из: Санкт-Петербург
Пользователь №: 15 227



Цитата(Student Pupkin @ Aug 29 2009, 18:26) *
Я чайник smile.gif . И помочь ничем не смогу. Но хочу спросить (в целях самообразования) - а что значит вот это объявление?
Цитата
extern const PWInterface const PWMonitor0;

То же, что и полное объявление вместе с инициализацией, но в заголовочный файл вынесено только имя. Т.к. стоит extern - я сообщаю, что полное объявление с инициализацией существует где-то, а другим модулям достаточно знать имя, тип и "модифицируемость" объекта - всё, чтоб обратиться к нему, а компилятору сгенерировать код.

Цитата(Student Pupkin @ Aug 29 2009, 18:26) *
Я в смысле как это укладывается в общую схему объявления переменной?
[класс памяти] [const] тип имя [инициализатор] - в данном случае [класс памяти] -extern, тип - структура с именем PWInterface, определенным с помощью typedef, имя переменной - PWMonitor0.... А второй const (...PWInterface const PWMonitor0) - это что такое? А то получается что-то наподобие "extern const int const var1"....
Я исходил из следующих утверждений:
Код
int *int_ptr;  // Модифицируемый указатель на модифицируемый объект
const int *int_ptr;  // Модифицируемый указатель на константный объект
int * const int_ptr;  // Константный указатель на модифицируемый объект
const int * const int_ptr;  // Константный указатель на константный объект

Хотя это касается указателей.... а в моем примере... гм... как-то даже по-русски не получается... первый const - разместить в памяти программ, второй -... возможно лишний, но результат компиляции не меняется... возможно пока гонялся за указателями - намудрил лишнего...

Цитата(Student Pupkin @ Aug 29 2009, 18:26) *
Здесь мне тоже ничего не понятно:
Код
const PWInterface const PWMonitor0 =
    {
        &SomeFunc1,
        &SomeFunc2,
        ....
    };

Надеюсь, мне по ходу дела объясните smile.gif .
Идея такова: хочу инициализированную структуру, полям которой при инициализации присвоены указатели на функции. Далее считаю, что сами эти функции константы (собсно адреса никуда не перемещаются, и изменять их не надо) - ставлю второй const; далее хочу чтоб сия структура была компилятором создана в памяти программ, а не в секции данных, которая инициализируется все равно из памяти программ в startup коде - вот появляется первый const.

Вот примерно таковы мои рассуждения...

Цитата(Dog Pawlowa @ Aug 29 2009, 19:11) *
Я делаю все попроще.

typedef void (*VECTORS)();
const VECTORS function[FUNCTION_QTY]={function1, function2, };

вызов:
function[function_index]();

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

Возможно я некорректно выразился, но ведь в инициализированной структуре хранятся адреса функций. Поэтому первичная структура избыточность не содержит. Далее я объявлял массив содержащий указатели на структуры с адресами функций.
Цель всей этой затеи - в зависимости от двух параметров, которые выступают индексами по массивам, вызывать нужную функцию. Реализовать пытался без использования "марсианских писем"... так сказать - попонятней.
Go to the top of the page
 
+Quote Post
Student Pupkin
сообщение Aug 29 2009, 16:30
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 23-05-08
Пользователь №: 37 760



Цитата(cf7k @ Aug 29 2009, 19:18) *
Хотя это касается указателей.... а в моем примере... гм... как-то даже по-русски не получается... первый const - разместить в памяти программ, второй -... возможно лишний, но результат компиляции не меняется... возможно пока гонялся за указателями - намудрил лишнего...

Угумс smile.gif. Про указатели (константный указатель на константу) я знаю. А вот подобное объявление переменных - первый раз вижу (хотя я и так мало чего видел пока в жизни smile.gif).
Ну так может попробовать "возможно лишние" const убрать? А то как-то не по ANSI/ISO получается smile.gif ...
И второй вопрос -
Цитата(cf7k @ Aug 29 2009, 19:18) *
Далее считаю, что сами эти функции константы

А смысл? Если структура объявлена константой, то ее поля изменять нельзя... И потом - по логике константы должны размещаться в ROM. И еще сами функции размещаются в ROM, значит их адреса фиксированы... Идею использовать для указателя на функцию уточнение, что он указывает на константный объект не понимаю - это лишь необходимо для предотвращения изменений объекта, на который ссылаемся (в общем случае... для embedded-случаев это еще указывает на то, что объект будет размещен в секции констант, расположенной в ROM). В случае, если объект, на который указывает указатель, - функция, то его и поменять то невозможно... Он в ROM расположен (если специально никаких усилий на то, чтобы разместить функцию в RAM, не предпринималось).... Да и зачем менять то? На ходу править код функции?
P.S. Если я чего-то недопонимаю - надеюсь, мне тут объяснят smile.gif

Сообщение отредактировал Student Pupkin - Aug 29 2009, 16:34
Go to the top of the page
 
+Quote Post
cf7k
сообщение Aug 29 2009, 17:06
Сообщение #6


Частый гость
**

Группа: Свой
Сообщений: 82
Регистрация: 14-03-06
Из: Санкт-Петербург
Пользователь №: 15 227



Цитата(Student Pupkin @ Aug 29 2009, 20:30) *
Угумс smile.gif.
...
Ну так может попробовать "возможно лишние" const убрать? А то как-то не по ANSI/ISO получается smile.gif ...

Так уже пробовал, пока писал предыдущий пост - компилятор понимает и так и так... Но для порядку причесал.

Цитата(Student Pupkin @ Aug 29 2009, 20:30) *
А смысл? Если структура объявлена константой, то ее поля изменять нельзя... И потом - по логике константы должны размещаться в ROM. И еще сами функции размещаются в ROM, значит их адреса фиксированы...
......

Ну смысла не много - наверно для выразительности. Я в отрочестве не был сионистом smile.gif.
Сначала строил структуру, далее инициализировал её указателями (адресами функций) - вот и поставил средний const (сами указатели ж у меня констанстные - хотя для функций это скорее всего само собой разумеющееся). Далее все это разместил в ПЗУ приписав первый const. Вот так и родил монстра smile.gif Но компилятор уживается с этим монстром.

Меня ж более интересует последний монстр - "массив указателей на массивы указателей на структуры" (и это все в ПЗУ).
Go to the top of the page
 
+Quote Post
Student Pupkin
сообщение Aug 29 2009, 18:25
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 23-05-08
Пользователь №: 37 760



Цитата(cf7k @ Aug 29 2009, 21:06) *
Меня ж более интересует последний монстр - "массив указателей на массивы указателей на структуры" (и это все в ПЗУ).

Попробовал проделать аналогичное в Visual Studio 2008:
CODE
// Пустые функции (чтобы было)
void func1(int a)
{
};
void func2(int a)
{
};

typedef struct
{
void (*func1)(int);
void (*func2)(int);
} PWInterface;

/* Здесь с помощью макроподстановки я определяю имя pConstPWInterfaceConst
для константного указателя на структуру-константу PWInterface*/
#define pConstPWInterfaceConst const PWInterface *const


/*
Таким способом не получается:
typedef PWInterface *pPWInterface;
*/

const PWInterface PWMonitor1 = {func1, func2};
const PWInterface PWMonitor2 = {func2, func1};

pConstPWInterfaceConst PWMonitorPtr1 = &PWMonitor1;
/*
Таким способом не получается:
1)Ошибка компиляции (повторное использование const):
const pPWInterface const PWMonitorPtr1 = &PWMonitor1;
2) Ошибка компиляции (несовместимость квалификаторов типов,
т.е. указателю присваивается адрес константного объекта, чего нет в объявлении самого указателя):
const pPWInterface PWMonitorPtr1 = &PWMonitor1;
*/

Мысли по этому поводу такие
  1. Действительно, если писать что называется в лоб
    Код
    const PWInterface *const PWMonitor1 = &PWMonitor1;
    то никаких ошибок
  2. Если с помощью typedef определить имя pPWInterface для указателя на структуру PWInterface, то запись вида
    Код
    const pPWInterface const PWMonitorPtr1 = &PWMonitor1;
    получится неверной. Видимо, подобная запись соответствует общей схеме объявления переменной -
    Код
    [класс памяти] [const] ТИП ИМЯ [инициализатор]
    Как видите, в этой схеме места для еще одного const нет. Вы можете только таким способом объявить указатель-константу (массив указателей-констант), но не можете сообщить, что это указатель на объект-константу (а способом в п.1 можете smile.gif)
  3. Тоже самое происходит при попытке объявить массив указателей на указатели (есесно все там const - лень писать просто smile.gif)
  4. Предлагаю писать в лоб (не вводите с помощью typedef имена "*pPWInterface" и "**ppPWInterface")
  5. Если не хотите в лоб, то воспользуйтесь define, как в моем куске (не знаю, как там насчет портируемости, эстетики, красоты и т.д., но такой способ работает, все компилится без ошибок и предупреждений). Там есесно упрощенно, но таким макаром можно и массив... И для указателя на указатель можно тоже аналогичный дефайн написать...
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Aug 29 2009, 19:06
Сообщение #8


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(cf7k @ Aug 29 2009, 11:26) *
Код
const pPWInterface    const PWMonMode1Arr[] = ...
получаю warning: initialization discards qualifiers from pointer target type
Вопрос первый: Что именно я недопонимаю? Хотел как лучше (чтоб через typedef... красившее. Вроде корректно определенный тип указателя при определении структуры)...


Я сильно не вчитывался, но вот такое
Код
typedef struct
{
    void (*FunctionPointer)  (char Param);
    int  (*OtherFuncPointer) (int SomeParam);
}const PWInterface, *pPWInterface;

const PWInterface const PWMonitor0 = {0, 0};
const PWInterface const PWMonitor2 = {0, 0};

const pPWInterface const PWMonMode1Arr[] = {&PWMonitor0, &PWMonitor2};


компилится без ворнингов. Добавил слово const в typedef.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Student Pupkin
сообщение Aug 29 2009, 20:23
Сообщение #9


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 23-05-08
Пользователь №: 37 760



Цитата(AHTOXA @ Aug 29 2009, 23:06) *
Я сильно не вчитывался, но вот такое
Код
typedef struct
{
    void (*FunctionPointer)  (char Param);
    int  (*OtherFuncPointer) (int SomeParam);
}const PWInterface, *pPWInterface;

const PWInterface const PWMonitor0 = {0, 0};
const PWInterface const PWMonitor2 = {0, 0};

const pPWInterface const PWMonMode1Arr[] = {&PWMonitor0, &PWMonitor2};


компилится без ворнингов. Добавил слово const в typedef.

А у меня такой варнинг
Код
warning C4114: same type qualifier used more than once

Однако полагаю писать надо так:
Код
/* имя константной структуры PWInterface и указателя pPWInterface на константную структуру типа PWInterface */
typedef const struct
{
    void (*FunctionPointer)  (char Param);
    int  (*OtherFuncPointer) (int SomeParam);
} PWInterface, *pPWInterface;      

/* Объявление константных структур типа PWInterface с именами PWMonitor0 и PWMonitor2*/
PWInterface PWMonitor0 = {0, 0};   // объявление константной структуры типа PWInterface
PWInterface PWMonitor2 = {0, 0};   //

/* Объявление массива указателей-констант (на что указывает слово const) на структуру-константу типа PWInterface*/
const pPWInterface PWMonMode1Arr[] = {&PWMonitor0, &PWMonitor2};
Go to the top of the page
 
+Quote Post
cf7k
сообщение Aug 29 2009, 20:35
Сообщение #10


Частый гость
**

Группа: Свой
Сообщений: 82
Регистрация: 14-03-06
Из: Санкт-Петербург
Пользователь №: 15 227



Цитата(AHTOXA @ Aug 29 2009, 23:06) *
Я сильно не вчитывался, но вот такое
.......
компилится без ворнингов. Добавил слово const в typedef.

Гм... любопытный подход... возьму на заметку. Пасиба.
Код
вместо
const PWInterface    *const PWMonMode1Arr[] = {&PWMonitor0, &PWMonitor0_c, &PWMonitor0_r};
получилось то что хотелось:
const pPWInterface const PWMonMode1Arr[] = {&PWMonitor0, &PWMonitor2};

Но это "уровень 1" массива.



Цитата(Student Pupkin @ Aug 29 2009, 22:25) *
Попробовал проделать аналогичное в Visual Studio 2008:
....
Мысли по этому поводу такие
  1. Если не хотите в лоб, то воспользуйтесь define, как в моем куске (не знаю, как там насчет портируемости, эстетики, красоты и т.д., но такой способ работает, все компилится без ошибок и предупреждений). Там есесно упрощенно, но таким макаром можно и массив... И для указателя на указатель можно тоже аналогичный дефайн написать...

вот с дефайном не получилось - на самом деле я не define задаю, а пишу в лоб (ну что там вынести для красоты - это уже другое дело).

Пока самый человеко понятный код у меня такой:
Код
const ppPWInterface const Pathways[]    = {(ppPWInterface)(&PWMonMode1Arr), (ppPWInterface)(&PWMonMode2Arr), (ppPWInterface)(&PWMonMode2Arr)};
В общем-то и в объявлении есть двойной указатель и const'ы там где хочется... но... все же хочется знать, как это делается без коррекции типа, так сказать, по правилам языка.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Aug 29 2009, 21:06
Сообщение #11


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(cf7k @ Aug 30 2009, 02:35) *
Гм... любопытный подход... возьму на заметку. Пасиба.
Но это "уровень 1" массива.

Со вторым уровнем всё проще. Имя массива является указателем на первый его элемент, потому не надо писать & в
const ppPWInterface const Pathways[] = {&PWMonMode1Arr, &PWMonMode2Arr, &PWMonMode3Arr};

Короче, вот оба уровня, с учётом замечаний студента Пупкина:
Код
typedef struct
{
    void (*FunctionPointer)  (char Param);
    int  (*OtherFuncPointer) (int SomeParam);
}WInterface;

typedef WInterface const PWInterface;
typedef PWInterface* const pPWInterface;
typedef pPWInterface* const ppPWInterface;

const PWInterface PWMonitor0 = {0, 0};
const PWInterface PWMonitor2 = {0, 0};

const pPWInterface PWMonMode1Arr1[] = {&PWMonitor0, &PWMonitor2};
const pPWInterface PWMonMode1Arr2[] = {&PWMonitor0, &PWMonitor2, &PWMonitor0};
const pPWInterface PWMonMode1Arr3[] = {&PWMonitor2, &PWMonitor0};

const ppPWInterface final_array[] ={ PWMonMode1Arr1, PWMonMode1Arr2, PWMonMode1Arr3};


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Student Pupkin
сообщение Aug 29 2009, 21:13
Сообщение #12


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 23-05-08
Пользователь №: 37 760



Ну а если так:
Код
/* Вводим тип структура-константа с именем PWInterface */
typedef const struct
{
   void (*func1)(int);
   void (*func2)(int);
} PWInterface;

/* Вводим тип указатель-константа на структуру-константу типа PWInterface с именем pPWInterface. */
typedef PWInterface *const pPWInterface;

/* Вводим тип указатель-константа на указатель-константу (типа pPWInterface) на структуру-константу типа PWInterface. Имя вводимого типа - ppPWInterface */  
typedef pPWInterface *const ppPWInterface;

Как такой вариант себя ведет? При этом конечно все const-ы из обявлений переменных нужно выкинуть.
Т.е. не писать так:
Код
const PWInterface const PWMonitor0 =
    {
        &SomeFunc1,
        &SomeFunc2,
        ....
    };
ну и далее реализация этих функций.

и так
Код
const pPWInterface    const PWMonMode1Arr[] = ...

А писать так:
Код
PWInterface PWMonitor0 =
    {
        &SomeFunc1,
        &SomeFunc2,
        ....
    };
.
.
.
pPWInterface PWMonMode1Arr[] = ...

Ну и понятно последний "рубеж" должен выглядеть так:
Код
ppPWInterface Pathways[]    = {&PWMonMode1Arr, &PWMonMode2Arr, &PWMonMode3Arr};

То бишь без всяких const, т.к. момент с "константностью" уже определен в typedef.
Не знаю точно почему, но ваш компилятор на лишние const не ругается, а вот Visual Studio выкидывает варнинг. Да и вообще считаю, что "добавлять лишние const для выразительности" - это попахивает нечистью какой-то smile.gif .
Go to the top of the page
 
+Quote Post
cf7k
сообщение Aug 29 2009, 21:15
Сообщение #13


Частый гость
**

Группа: Свой
Сообщений: 82
Регистрация: 14-03-06
Из: Санкт-Петербург
Пользователь №: 15 227



Цитата(AHTOXA @ Aug 30 2009, 01:06) *
Со вторым уровнем всё проще. Имя массива является указателем на первый его элемент, потому не надо писать & в
const ppPWInterface const Pathways[] = {&PWMonMode1Arr, &PWMonMode2Arr, &PWMonMode3Arr};

const ppPWInterface final_array[] ={ PWMonMode1Arr1, PWMonMode1Arr2, PWMonMode1Arr3};[/code]

warning: initialization discards qualifiers from pointer target type
Go to the top of the page
 
+Quote Post
Student Pupkin
сообщение Aug 29 2009, 21:18
Сообщение #14


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 23-05-08
Пользователь №: 37 760



Цитата(cf7k @ Aug 30 2009, 01:15) *
warning: initialization discards qualifiers from pointer target type

Ну а с моим вариантом как? rolleyes.gif
Go to the top of the page
 
+Quote Post
cf7k
сообщение Aug 29 2009, 21:20
Сообщение #15


Частый гость
**

Группа: Свой
Сообщений: 82
Регистрация: 14-03-06
Из: Санкт-Петербург
Пользователь №: 15 227



Цитата(Student Pupkin @ Aug 30 2009, 01:13) *
То бишь без всяких const, т.к. момент с "константностью" уже определен в typedef.
Не знаю точно почему, но ваш компилятор на лишние const не ругается, а вот Visual Studio выкидывает варнинг. Да и вообще считаю, что "добавлять лишние const для выразительности" - это попахивает нечистью какой-то smile.gif .

Просто как-то не привык задавать "константный тип" (сегодня увидел такой подход впервые). Опять же привычно на месте определить - что в ПЗУ, что в ОЗУ, что не/изменяемо.
А "наш" smile.gif компилятор сделан на основе GCC третьей версии.

Цитата(Student Pupkin @ Aug 30 2009, 01:13) *
Ну а с моим вариантом как?

Ща... осваиваю...
add: скорее всего придется доосвоить утром wink.gif
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 17:41
Рейтинг@Mail.ru


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