Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Просто мнение
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Страницы: 1, 2, 3, 4, 5, 6, 7, 8
Petka
Цитата(zltigo @ Jun 16 2009, 20:16) *
Повторяю вопрос - лично Вы будете воспитывать, следить и так далее, дабы с этим "чудесным" bool работали только &&, ||, =0, =1? Не компилятор? Ну и зачем этот 'bool', который и не bool? Для удобного наступания на грабли?

~ это есть тоже вполне себе логическая smile.gif операция. Поразрядное логическое НЕ.

Не перегибайте палку. Компилятор не проследит и за тем, что я могу вызать (NULL) и грОмматические ошибки не отловит.
Суть такая: механизм сделать быстро и компактно по памяти есть. Удобен он или нет, это вопрос философский. Хотите что-бы компилятор относился ко всему слишком формально используйте Паскаль. Вы свободны в своём выборе =) Правда изначально топик был про свободу выбора контроллеров...
zltigo
Цитата(Petka @ Jun 16 2009, 20:23) *
Не перегибайте палку.

Не пытайтесь наводить тень на плетень.
Цитата
механизм сделать быстро и компактно по памяти есть. Удобен он или нет, это вопрос философский.

Нет. Совсем не в этом. Вопрос жестче жестче - "механизма" нет. СОВСЕМ нет. Предлагается чистой воды обманка:
Код
#define bool uchar

Просто вредная обманка по причине того, что ТОЛЬКО вводит в заблуждие ровным счетом ничего не делая, кроме ОБМАНА. Точка.
sonycman
Цитата(zltigo @ Jun 16 2009, 21:38) *
Просто вредная обманка по причине того, что ТОЛЬКО вводит в заблуждие ровным счетом ничего не делая, кроме ОБМАНА. Точка.

Ну а кто ввёл такой bool? Раз он таков - значит, все довольны? Язык же разрабатывают\дорабатывают супер пупер профессионалы типа Страуструпа и пр.? laughing.gif
Или тут компилерописатели напортачили?
defunct
Цитата(sonycman @ Jun 16 2009, 20:48) *
Ну а кто ввёл такой bool? Раз он таков - значит, все довольны? Язык же разрабатывают\дорабатывают супер пупер профессионалы типа Страуструпа и пр.? laughing.gif

В Cи нет типа bool.
aaarrr
Цитата(defunct @ Jun 16 2009, 22:21) *
В Cи нет типа bool.

Да вообще-то есть.

Цитата
6.2.5 Types
...
2 An object declared as type _Bool is large enough to store the values 0 and 1.


Цитата
7.16 Boolean type and values <stdbool.h>
...
2 The macro
bool
expands to _Bool.
defunct
Цитата(aaarrr @ Jun 16 2009, 21:31) *
Да вообще-то есть.

вообще-то нет.
bool(ean) - это удел паскаля, где шаг влево и вправо нельзя сделать.
aaarrr
Цитата(defunct @ Jun 16 2009, 22:34) *
вообще-то нет.
bool(ean) - это удел паскаля, где шаг влево и вправо нельзя сделать.

Если явление не соответствует вашим или паскалевским представлениям, то это отнюдь не значит, что его нет.
sonycman
Цитата(defunct @ Jun 16 2009, 22:21) *
В Cи нет типа bool.

В С++ точно есть. Встроенный тип bool.
Так стоит ли кого-то винить в кривой его реализации компилятором?
zltigo
Цитата(defunct @ Jun 16 2009, 21:34) *
bool(ean) - это удел паскаля, где шаг влево и вправо нельзя сделать.

C99 - десять лет, как уже даже официально закреплено существование _Bool и на усмотрение алиас bool. И, что характерно, работает "без обману"
rezident
Цитата(defunct @ Jun 17 2009, 00:21) *
В Cи нет типа bool.
В Pure C не было, в C99 появился.
Dir
Цитата(sonycman @ Jun 16 2009, 20:00) *
Вообще, серия Luminary (по крайней мере их младшая линейка) никоим образом не конкурент по потреблению тока.
Чипы здорово греются и жрут немеряно.
Их привели только в качестве малоногих армов. Может быть отладят техпроцесс или доработают камень когда нибудь...

Что значить когда-нибуть? Уже! Полюбуйтесь на один из новых чипов и найдите слабое место wink.gif
http://www.luminarymicro.com/products/lm3s9b95.html

Цитата(sonycman @ Jun 16 2009, 20:00) *
А вообще, такое ощущение, что их разрабатывали впопыхах, лишь бы успеть побыстрее выкинуть на рынок... sad.gif

Не впопыхах, а по технологии 0,25мкм. И успели, между прочим. Первые выпустили Cortex-M3 на рынок. А то, что продались TI - так Luminary, скорее всего, и создавалась для того, чтобы выгодно продаться. Типичная венчурная фирма типа Cygnal. Не повезло инвесторам. Вряд ли вообще свои бабки отбили. А вот если бы не кризис, то могли бы неплохо заработать.
defunct
Цитата(zltigo @ Jun 16 2009, 22:11) *
И, что характерно, работает "без обману"

Это хорошо. А на практике во что он пакуется? В int, в char, или в бит?
aaarrr
Цитата(defunct @ Jun 17 2009, 02:58) *
Это хорошо. А на практике во что он пакуется? В int, в char, или в бит?

На практике это оставлено на усмотрение компилятора, думаю, в подавляющем большинстве случаев это будет char.
AHTOXA
Цитата(zltigo @ Jun 17 2009, 01:11) *
C99 - десять лет, как уже даже официально закреплено существование _Bool и на усмотрение алиас bool. И, что характерно, работает "без обману"


Хм...
main.c:
Код
#include <stdio.h>

_Bool a = 2;

void printbool(void)
{
    printf("bool = %s\r\n", a ? "true" : "false");
}

void testbool(void)
{
    printbool();
    a = ~a;
    printbool();
    a = ~a;
    printbool();
    a = !a;
    printbool();
}

int main(void)
{
    printf("hello!\r\n");
    testbool();
}


Код
>gcc -Os -std=c99 -s -Wa,-adhlns=test.lst main.c -o test.exe
>test.exe

hello!
bool = true
bool = true
bool = true
bool = false


Без обману, говорите? :-)
zltigo
Цитата(aaarrr @ Jun 17 2009, 02:15) *
На практике это оставлено на усмотрение компилятора, думаю, в подавляющем большинстве случаев это будет char.

Маловероятно - для не восьмибитовиков типичным, скорее будет int. Проверить не нескольких компиляторах легко,но не особо интересно, ибо не для возвращаемых значений не использую вообще никогда. Да и вообще крайне редко - лишние команды по приведению к thru/false особо не окупаются.



Цитата(AHTOXA @ Jun 17 2009, 02:53) *
Без обману, говорите? :-)

Тем хуже sad.gif.
ArtemKAD
Цитата
Что значить когда-нибуть? Уже! Полюбуйтесь на один из новых чипов и найдите слабое место
http://www.luminarymicro.com/products/lm3s9b95.html


Ну и ? Полюбовался. Большой, дорогой (больше 8$), жутко крутой, ... Вот только токи потребления в доке не указаны. Наверное, что-бы потенциальных клиентов заранее не пугать smile3046.gif ...
dxp
Цитата(AHTOXA @ Jun 17 2009, 06:53) *
Хм...
main.c:
Код
#include <stdio.h>
[...]

hello!
bool = true
bool = true
bool = true
bool = false


Без обману, говорите? :-)

Интересный пример. smile.gif Поглядим. Согласно правилам языка (я по ++ным правилам разбираю, но думается, что в С99) оно так же.

Итак, инициалиация а = 2. Согласно правилам при присвоении булу результата арифметического выражения, если результат ноль, то присваивается false, иначе - true. Таким образом, после инициализации в а - true.

Далее. а = ~а Опять арифметическое выражение. При использовании була в арифметических выражениях он преобразоывается согласно правил к целому: если false, то в 0, если true - то в 1. У нас была true, значит при ~a имеем а преобразован (пусть int 16 бит) в 0x0001, а после инверсии - 0xfffe. Ну, и при присвоении обратно к булу - ненулевое значение преобразовывается в... правильно - в true. smile.gif

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

Никакого обмана. smile.gif
AHTOXA
Цитата(dxp @ Jun 17 2009, 10:32) *
Никакого обмана. smile.gif


Выкрутились smile.gif Я, помнится, всё это читал. Но забылsmile.gif А с позиции здравого смысла очень сложно принять, что ~(любой bool) - это true.
Но конечно этот bool лучше, чем ничего. Он даже индийское сравнение (if somevar == true) правильно обрабатывает:-)
MrYuran
Цитата(AHTOXA @ Jun 17 2009, 09:11) *
Но конечно этот bool лучше, чем ничего. Он даже индийское сравнение (if somevar == true) правильно обрабатывает:-)

Не понял...
(if somevar != false) я ещё понимаю... а это как правильно обработать?
dxp
Цитата(AHTOXA @ Jun 17 2009, 12:11) *
Выкрутились smile.gif Я, помнится, всё это читал. Но забылsmile.gif А с позиции здравого смысла очень сложно принять, что ~(любой bool) - это true.
Но конечно этот bool лучше, чем ничего. Он даже индийское сравнение (if somevar == true) правильно обрабатывает:-)

Ну, вы же помните разницу между & и && (| и ||, ~ и !). Вот тут и всплывает разница между bool и int. Достаточно помнить, что нативные операции над bool - это только лишь логические операции, а при использовании остальных начинаются преобразования типов со всеми вытекающими. Например, если вы целое присваиваете типу с плавающей точкой, то потенциально теряете точность. Это объяснимо и логично.

Имхо, вся сложность C/C++ как языков и содержиться в подобных нюансах, коих весьма немало. "Дьявол прячется в мелочах" (с) smile.gif
777777
Цитата(AHTOXA @ Jun 17 2009, 09:11) *
А с позиции здравого смысла очень сложно принять, что ~(любой bool) - это true.

С позиции здравого смысла сложно понять, зачем к логическим переменным применять побитовые операции. Но если программист просит - компилятор честно их выполняет.
Rst7
Цитата
С позиции здравого смысла сложно понять, зачем к логическим переменным применять побитовые операции.


С позиций здравого смысла вообще нет резона плодить лишние сущности типа bool.
sonycman
А может кто подскажет, уважаемые, где можно почитать про хитрый uint_fast8_t?
Этот тип что, обрабатывает байт как двойное слово, без накладывания масок?
Но как тогда будет обработан инкремент 0хff?
_Pasha
Цитата(sonycman @ Jun 17 2009, 10:20) *
А может кто подскажет, уважаемые, где можно почитать про хитрый uint_fast8_t?
Этот тип что, обрабатывает байт как двойное слово, без накладывания масок?
Но как тогда будет обработан инкремент 0хff?


<stdint.h> расскажет Вам обо всем. smile.gif Обратите внимание, что компилеру по барабану, как назовется этот хитрый тип, т.к. он не встроенный - все настройки на  платформенные особенности отданы на откуп прагмам и атрибутам. В общем, под таким углом зрения - ничего сложного и удивительного.
sonycman
Цитата(_Pasha @ Jun 17 2009, 11:25) *
<stdint.h> расскажет Вам обо всем. smile.gif Обратите внимание, что компилеру по барабану, как назовется этот хитрый тип, т.к. он не встроенный - все настройки на  платформенные особенности отданы на откуп прагмам и атрибутам. В общем, под таким углом зрения - ничего сложного и удивительного.

Хм, получается, что uint_fast8_t есть просто dword.
На кой он нужен тогда. Можно сразу напрямую задать тип dword... rolleyes.gif
_Pasha
Цитата(sonycman @ Jun 17 2009, 10:33) *
На кой он нужен тогда.   rolleyes.gif

На той, что:

1) Как портировать софтину с АВР-8бит на АРМ, если у исходной подавляющее большинство локальных переменных char, а если это перенести на 32-битовые регистры - получим оверхед по выделению байта ? Говорено-переговорено на эту тему.

2)Как только появляется необходимость в дополнительных атрибутах (т.е. оптимизация не может автоматом утоптать все конструкции, требуется явное указание на  способ обработки данных) - она отражается в stdint.h

Для программера ничего не меняется - он пользуется uint8_t когда надо явно указать размер (обмен с другими девайсами, например), и _fast и _least когда надо положить алгоритм оптимально на архитектуру. Лично я пока не сталкивался с острой необходимостью в uint_least8_t. Может кто прокомментирует, где оно применимо? Что до _fast - то тут все ясно - вычисления с использованием uint_fast8_t будут быстрее. 
dxp
Цитата(Rst7 @ Jun 17 2009, 13:51) *
С позиций здравого смысла вообще нет резона плодить лишние сущности типа bool.

Вообще? Или там, где нет нативного типа?
Rst7
Цитата
Вообще? Или там, где нет нативного типа?


Как по мне - так "вообще". Достаточно обычного С-шного соглашения о том, что ложь - ==0, истина - !=0.
sonycman
_Pasha
Спасибо, понятно.
zltigo
Цитата(_Pasha @ Jun 17 2009, 10:25) *
<stdint.h> расскажет Вам обо всем. smile.gif

Да ну?
Код
typedef __UINT_FAST8_T_TYPE__ uint_fast8_t;

Что поняли из рассказа?
Цитата
...этот хитрый тип, т.к. он не встроенный...

или встренный. Только вот поведение тоже не всегда устраивает sad.gif Лисно у меня это кончилось тем, что завел свои типы, естественно и более-менее разбираюсь вручную, или по быстрому назначаю на них поминаемые fast8 least8
sonycman
Цитата(zltigo @ Jun 17 2009, 12:15) *
Код
typedef __UINT_FAST8_T_TYPE__ uint_fast8_t;

А у меня в Кейле:
Код
typedef unsigned           int uint_fast8_t;
zltigo
Цитата(dxp @ Jun 17 2009, 10:53) *
Вообще? Или там, где нет нативного типа?

Вообще, ибо в приведенной трактовке он никаких проблем не решает и ведет себя, как и char/int/ только еще и имеет не предсакзуемый размер.
_Pasha
Цитата(zltigo @ Jun 17 2009, 11:15) *
или встроенный.

Интересно. Из какого компилера  __UINT_FAST8_T_TYPE__ ?

Согласитесь, лучше атрибутами бы "встроенность" обеспечивали.
zltigo
Цитата(sonycman @ Jun 17 2009, 11:23) *
А у меня в Кейле:

Понятно. В IAR встроенный и ведет себя (по крайней мере плотно экспериментировал во времена массового портирования с 8/16bit с least8 ) за счеет этого несколько интелектуальнее.
_Pasha
Цитата(zltigo @ Jun 17 2009, 11:26) *
В IAR встроенный и ведет себя .... несколько интелектуальнее.

Может, Вы приведете пример, где свойства _least и _fast расходятся? Ну нигде не найду возможности осязать разницы! smile3046.gif
zltigo
Цитата(_Pasha @ Jun 17 2009, 11:32) *
Может, Вы приведете пример, где свойства _least и _fast расходятся? Ну нигде не найду возможности осязать разницы! smile3046.gif

На ARM платформе fast всегда был( видел) только 32bit, а least в некоторых контекстах становился восьмибитовиком. Ну а для полатформ типа x86 c их кусочками регистров и гибкой адресации к памяти оставляют много больший простор, для компилятора.
Те-же 8bit в памяти выровняные на границу слова ничуть не медленнее 32bit. А если нет, то....
_Pasha
Цитата(zltigo @ Jun 17 2009, 11:39) *
для полатформ типа x86 c их кусочками регистров и гибкой адресации к памяти

Спасибо! Как-то подзабыл об этом...
Цитата
Те-же 8bit в памяти выровняные на границу слова ничуть не медленнее 32bit.

Т.е. в идеале на Load/Store архитектурах тот же uint_least8_t в памяти займет 1(2) байт, а в регистре - ширину регистра? И дальше ничем от _fast отличаться не будет?
dxp
Цитата(Rst7 @ Jun 17 2009, 15:07) *
Как по мне - так "вообще". Достаточно обычного С-шного соглашения о том, что ложь - ==0, истина - !=0.

Цитата(zltigo @ Jun 17 2009, 15:23) *
Вообще, ибо в приведенной трактовке он никаких проблем не решает и ведет себя, как и char/int/ только еще и имеет не предсакзуемый размер.

А вот неглупые дяди приводят такие аргументы (цитирую):

  • тип Boolean существует вне зависимости от того, есть он в стандарте С++ или нет;
  • наличие множества конфликтующих друг с другом определений делает неудобным и небезопасным любой тип Boolean;
  • многие пользователи хотят иметь возможность перегружать функции на базе типа Boolean.


И я полностью согласен со всем тремя аргументами. Сам давно и регулярно юзаю плюсовый bool, что нахожу наглядным, логичным и удобным, и никогда не испытывал с ним проблем (и не помню, чтобы кто-то жаловался).

Что касается размера, то размер его вполне предскзуемый и зависит от реализации. Ровно как и в случае с char, int, enum, double.
zltigo
Цитата(dxp @ Jun 17 2009, 12:00) *
И я полностью согласен со всем тремя аргументами.

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

Я в С99 в моих ситуациях тоже не жаловался, но честно говоря, представлял себе, это много более безопасным, нежели приведенная реализация bool в GCC.
Цитата
Что касается размера, то размер его вполне предскзуемый и зависит от реализации. Ровно как и в случае с char, int, enum, double.

Так "предсказуемый" или "завистит от реализации"? Со всеми вышеперечисленными, включая enuм действительно ясно (в рамках зависящих от платформы), а вот что такое боол и размер достаточный для его хранения? Огласите, сколько это в битах, как размещается в регистрах, как в памяти, как пакуется в структуры, union-ы..... Лично я могу только "предсказать" одну логичную с точки зрения универсальности реализации - int.

Цитата(_Pasha @ Jun 17 2009, 11:50) *
Т.е. в идеале на Load/Store архитектурах тот же uint_least8_t в памяти займет 1(2) байт, а в регистре - ширину регистра? И дальше ничем от _fast отличаться не будет?

Ну что-то где-то так. Только я в конце концов стал делать это через свои типы, поскольку мне это нужно было прежде всего для портирования, а замена какого-нибудь char на fast8 в трактовке Keil может легко выйти боком.
s.qwertyuiop
Цитата(_Pasha @ Jun 17 2009, 11:48) *
1) Как портировать софтину с АВР-8бит на АРМ, если у исходной подавляющее большинство локальных переменных char, а если это перенести на 32-битовые регистры - получим оверхед по выделению байта ? Говорено-переговорено на эту тему.

Я не большой знаток АРМа, но разве он не может оперировать байтами? И если нет, то как с ним вообще работать? И тогда чем он лучше сигнальных процессоров типа ADSP?
aaarrr
Может, но компилятор не сделает эффективный код, если локальные переменные сплошь восьмибитные - ему придется искуственно ограничивать разрядность при операциях с ними.

А уж чем ADSP не угодил - ума не приложу.
Xenia
Грустно, что обсуждение перешло обсуждение на размерности булевской переменной. По всей видимости, это произошло из-за того, что участники дискуссии путают "битность" процессора и шириной шины данных. Между тем, как это вещи в общем случае разные.
Разрядность регистров процессора может превосходить ширину шины данных (т.е. сетку физической адресации памяти), но наоборот быть не может. В своё время процессор i80386SX уже имел 32-разрядные регистры, когда как работал с 16-разрядной шиной памяти. Такая ситуация означает лишь необходимость в наличии инструкций по чтению/записи старшей и младшей части регистра и их комбинацию, обеспечивающую двухступенчатый обмен между целым регистром и двумя последовательными ячейками памяти.
Вопрос о размерности булевской переменной связан исключительно с шириной шины памяти. Не процессор виноват в том, что один бит из памяти он достать не может, а вынужден читать или писать целиком область памяти, равную разрядности шины данных - это атрибут памяти, которая не может считываться или записываться побитно.
При этом заметим, что и от адресации памяти (виртуальной) размер булевской переменной не зависит. Адресация памяти может быть побайтная, в то время как шина данных быть в 4 байта. Такая ситуация мешает процессору сразу записать байт в память, а вынуждает его сперва прочитать из нее 4 байта, потом заменить один из байтов на новый, и уж только затем записать назад эти 4 байта. Как видим, операция с булевскими переменными становятся неэффективными, если размерность такой переменной отличается от ширины шины данных. Причем это же касается и операций с текстовыми символами, которые в практическом отношении встречаются гораздо чаще, чем булевские переменные.
Возвращаясь к микропроцессорам замечаем, что разрядность шины данных у них обычно мала. Т.е. данные передаются во внешнюю память силами одного, максимум двух портов. Например, у AVR32 шина данных памяти 16 бит (шину адреса я не посчитала). Это означает, 3что 32-битность на память не распространяется, поскольку ФИЗИЧЕСКИ память обменивается с процессором сразу 2-мя байтами. Стало быть и булевская переменная, если уж она так сильно вам нужна, будет в данном случае иметь 16-битную размерность.
Гораздо более существенным вопросом, чем размерность булевской переменной, является вопрос о размерности АДРЕСА памяти, что в первую очередь определяется максимальным объемом рабочей памяти. У AVR32 этот адрес занимает 24 бита. Именно отсюда и возникает преимущества 32-битности, что адрес целиком помещается в регистр. Тут уже не надо маяться, работая с адресом, как регистровой парой (операция по ее инкрементированию более сложна).
Ну а главное все-таки арифметика! Все мы знаем, что размерность произведения вдвое больше размерности данных. Вот тут-то длинные регистры очень кстати. И, наконец, преимущества длинных регистров поймут все те, кто хотя бы краешком глаза заглядывал на то, как реализуется в библиотеках эмуляция работы с плавающей точкой.
AHTOXA
Цитата(MrYuran @ Jun 17 2009, 11:48) *
Не понял...
(if somevar != false) я ещё понимаю... а это как правильно обработать?


Ну как раз так и обрабатывается, сравнение (somevar == true) приводится к (somevar != false) smile.gif

Цитата(dxp @ Jun 17 2009, 11:51) *
Ну, вы же помните разницу между & и && (| и ||, ~ и !).


Помнюsmile.gif Однако я помню также, что инверсия бита на i51 получалась быстрее, если написать bit = ~bit. Но даже это не самое главное. Самое главное, что сам компилятор при обработке логических выражений не пользуется bool! Вот поэтому bool и продолжает оставаться слегка "сбоку" от языка.

Цитата(dxp @ Jun 17 2009, 11:51) *
Имхо, вся сложность C/C++ как языков и содержится в подобных нюансах, коих весьма немало. "Дьявол прячется в мелочах" (с) smile.gif


Согласен smile.gif
Dx!
У меня есть и такое
Код
    if(PINB&0b00000010) //обработка джампера

Цитата
(if somevar != false) я ещё понимаю... а это как правильно обработать?

волне можно использовать и if(somevar) - краткая запись. выполнится если этот самвар != 0 или if(!somevar) что одно и тоже с if(somevar == 0)
Как выше уже говорили - всё что == 0 - false а всё, что !=0 - true. Помнить это, да не путать логические и побитовые действия и в bool не будет надобности.
zltigo
Цитата(Dx! @ Jun 17 2009, 17:31) *
Помнить это, да не путать логические и побитовые действия и в bool не будет надобности.

Дык, весь прикол в том, что если путать, то bool просто НИЧЕМ не помогает. Сюрприз!
ARV
Цитата(zltigo @ Jun 17 2009, 18:37) *
Дык, весь прикол в том, что если путать, то bool просто НИЧЕМ не помогает. Сюрприз!
а если путать? biggrin.gif
zltigo
Цитата(ARV @ Jun 17 2009, 17:46) *
а если путать? biggrin.gif

Это написано в отцитированной Вами строке.
Dx!
Дык я к тому - не использовать bool ввиду убогости. Если в программировании путать божий дар с яичницой - ничего хорошего не будет при любых раскладах.
sonycman
Цитата(Dx! @ Jun 17 2009, 19:03) *
Дык я к тому - не использовать bool ввиду убогости. Если в программировании путать божий дар с яичницой - ничего хорошего не будет при любых раскладах.

Имхо, опять же, в ситуациях, когда функция возвращает только два значения - TRUE и FALSE, запись возвращаемого значения как bool выглядит гораздо логичнее и красивее, чем громоздкое и непонятное int laughing.gif
Dx!
Грабли тоже выглядят обычным садовым инвентарем 8)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.