Ada_Ru форум

Обсуждение языка Ада

Long_Integer vs. Integer_32

Оставить новое сообщение

Сообщения

Olleg Samoylov
Long_Integer vs. Integer_32
2006-01-17 21:59:11

Приветствую всех.

Я новичек, и вопрос мой ньюбский. В GNAT присутствуют схожие целочисленные типы. Одни определены в Standart (Long_Integer, etc), другие в Interfaces (Integer_32, etc). Преимущество типов, что определены в Standart понятны, они совпадают с аналогичными типами gcc в C и C++ и можно будет пользоваться внешними библиотеками не заморачиваясь сильно. Но наверное есть сильные стороны и в типах из Interfaces.

Кто может растолковать, когда и в каких ситуациях каким целочисленным типам отдавать предпочтение?

-- Olleg Samoylov

Не считаю себя экспертом во внутренних представлениях, поэтому готов что меня поправят, но скорее дело обстоит наоборот - если используете Standard

- Ада вам гарантирует что при переходе от реализации к реализации будете иметь совместимый тип, а если используете Interfaces.C, совместимость между реализациями языка не гарантируется но зато гарантируется совместимость по типам с некоей конкретной реализацией Си. Разумеется если вы остаетесь в рамках семейства GCC то совместимость типов вам гарантируется бесплатно просто в силу того что бэкенд один и тот же, поэтому можно смело

использовать типы из Standard и подразумевать совместимость с GCC C.

ВФ.

Всем привет!

 

Друзья, тоже вопрос новичка. Буду вам благодарен за прояснение вопроса с Posix threads в среде Linux. Как я понял, раньше, multitasking осуществлялась только через Linux threads, а для Posix threads нужен был Florist.

Мир Linux активно переходит на использование Posix threads, а как с этим обстоят дела в отношении Ada 2005? К сожалению, на сайте AdaCore ничего по этому вопросу не нашли. Неужели всё так и осталось по-прежнему? Поправьте меня, пожалуйста, если я где-то ошибаюсь.

 

 

Алексей

rainbow-2000 wrote:

Всем привет!

 

Друзья, тоже вопрос новичка. Буду вам благодарен за прояснение вопроса с Posix threads в среде Linux. Как я понял, раньше, multitasking

осуществлялась только через Linux threads, а для Posix threads нужен был Florist.

Исторически сначала для Linux нитей не было. Потом появились FSU

Threads. Уже после этого - Xleroy Threads. И, наконец, совсем недавно - Native Threads.

 

Все перечисленные библиотеки поддерживают POSIX Threads API в той или иной степени.

 

Любая из этих библиотек может использоваться GNAT-ом для реализации multitasking. Любая из этих библиотек может использовать с Florist.

(PS. Вася, если я не прав, поправь. FSU ещё поддерживается?)

 

В чём разница? Только во внутренней организации, используемых механизмах ядра и, как следствие, получаемых результатах.

 

FSU реализуют все собственными силами. Плюсы: возможность работы в реальном времени и хорошах совместимость с POSIX. Минусы - очень редкая штука, остальные библиотеки Linux с ней слабо совместимы, не может использовать возможности многопроцессорных систем.

 

Xleroy Threads используют vfork (аналог fork, но без создания отдельного адресного пространства процесса). Плюсы - классно распараллеливается на многопроцессорных машинах, ввод-вывод не блокирующий. Минусы -

совместимость с POSIX страдает, особенно в части обработки сигналов.

Native Linux Threads - последний писк моды - наиболее совершенная библиотека. Огромная её часть является частью ядра Linux. Требует самых последних версий ядер с включенной поддержкой NTPL. Минусов на

сегодняшний день не известно. Даже обеспечивается совместимость бинарных программ, использовавших Xleroy Threads.

 

Мир Linux активно переходит на использование Posix threads, а как с этим обстоят дела в отношении Ada 2005? К сожалению, на сайте AdaCore ничего по этому вопросу не нашли. Неужели всё так и осталось по-прежнему? Поправьте меня, пожалуйста, если я где-то ошибаюсь.

 

Переход с Xleroy на Native Threads выглядит совершенно прозрачно: "просто замени DLL библиотеку".

Olleg wrote:

Приветствую всех.

Я новичек, и вопрос мой ньюбский. В GNAT присутствуют схожие

целочисленные типы. Одни определены в Standart (Long_Integer, etc), другие в Interfaces (Integer_32, etc). Преимущество типов, что

определены в Standart понятны, они совпадают с аналогичными типами gcc в C и C++ и можно будет пользоваться внешними библиотеками не

заморачиваясь сильно. Но наверное есть сильные стороны и в типах из Interfaces.

Типы данных из Interfaces.* предназначены для взаимодействия с

одноимёнными языками. Для них и только для них гарантируется одинаковое предстваление Ada и представлением языка.

 

Что же касается типов из Standard, то для них гарантируется только минимальный диапазон значений.

 

PS. В общем случае значительно грамотнее объявлять собственные типы - Ada для этого и создавалась.

Vadim Godunko wrote:

Типы данных из Interfaces.* предназначены для взаимодействия с

одноимёнными языками. Для них и только для них гарантируется одинаковое

предстваление Ada и представлением языка.

 

Эти типы обвъявлены в корневом Interfaces, так что о взаимодействии с одноименными языками говорит сложно, т.к. непонятно для взаимодействия с каким языком они создавались. И бонус, что я пока нашел, для модульных целых чисел из Interfaces присутствует побитовый сдвиг и вращение, что делает их уникальными. Кроме того, только у них есть явное указание, сколько байт данное число занимает в памяти, что может быть полезно, например, для разбора заголовков сетевых пакетов.

 

Что же касается типов из Standard, то для них гарантируется только

минимальный диапазон значений.

 

В том то и дело, что практический не гарантируется стандартом. Это просто, стандартом разрешено, если реализация компилятора захочет добавить собственные типы целых числа, то она может использовать пакет Standard и предопределенные имена. Оговаривается стандартом только:

1. Integer должен иметь как минимум диапазон 16битовых целых чисел. (Описание совпадает с C). Это действительно стандартный тип.

2. Long_Integer может быть или не быть. Если есть, то должен быть как минимум 32битным диапазоном.

3. Диапазон Short_Short_Integer<=Short_Integer<=Integer<=Long_Integer<=Long_Long_Integer (Описание совпадает с С).

4. Как видно минимальный диапазон для всех нестандартных целочисленных типов из Standard, за исключением Long_Integer и Integer не определен. Более того, стандарт не рекомендует в реализации задавать эти дополнительные целочисленные типы, за исключением Long_Integer. При необходимости рекомендуется использовать типы из Interfaces.

 

Другое дело GNAT гарантирует, что эти типы из Standard совпадают с типами C в gcc, кол-во байт и минимальный диапазон которых, кстати, тоже жестко не определены, поэтому нельзя использовать типы из Interfaces для этой цели. В результате можно будет использовать C библиотеки не прибегая к спецефическому преобразованию типов.

 

Вот такие вот чудеса. Обобщая вышесказанное: из Interfaces стандартны, но не подходят для интеграции с внешними системными библиотеками. Типы из Standard не стандартны, но в GNAT хорошо со внешними системными библиотеками интегрируются.

 

PS. В общем случае значительно грамотнее объявлять собственные типы -

Ada для этого и создавалась.

 

Сомневаюсь, что грамотнее. Замучаешься потом в арифметических выражениях их преобразовывать. Гораздо грамотнее, IMHO, создавать subtype на базе какого-то одного целочисленного типа. subtype для этого и создавался. :)

-- Olleg Samoylov

On Wed, Jan 18, 2006 at 11:17:29AM +0300, Olleg wrote:

Vadim Godunko wrote:

Типы данных из Interfaces.* предназначены для взаимодействия с

одноимёнными языками. Для них и только для них гарантируется одинаковое предстваление Ada и представлением языка.

 

Эти типы обвъявлены в корневом Interfaces, так что о взаимодействии с одноименными языками говорит сложно, т.к. непонятно для взаимодействия с каким языком они создавались.

 

Смотри, например, Interfaces.C.int, Interfaces.C.unsigned_long,

Interfaces.C.size_t и т.д.

Типы Interfaces.Integer_* и Unsigned_* имеют определенную

длинну, но их набор может меняться в компиляторах и платформах.

 

И бонус, что я пока нашел, для модульных

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

 

Если завязаться на использование типов из Interfaces, то реализация будет зависить от компилятора. Этой завасимости лучше избежать, описав свои типы нужного размера. Например

type Byte is mod 2 ** 8;

for Byte'Size use 8;

 

Они будут работать не хуже чем типы Interfaces.* но будут переносимы. Ну разве что не будет сдвигов/ротаций.

 

Вот такие вот чудеса. Обобщая вышесказанное: из Interfaces стандартны, но не подходят для интеграции с внешними системными библиотеками. Типы из Standard не стандартны, но в GNAT хорошо со внешними системными библиотеками интегрируются.

 

 

Ада может работать на широком диапазоне платформ. Поэтому ограничения на предопределенные типы минимальны.

 

Если нужна переносимость - используй собственные типы нужного диапазона.

Если нужна интеграция с внешней библиотекой на языке Си используй типы из Interfaces.C и получишь переносимость не зависимо от размера int и long на целевой платформе.

 

Если нужна интеграция с железом или протоколами описанными в терминах битов и байт - используй собственные типы указывая необходимый размер и др параметры представления.

 

Про типы из Standard известно, кроме минимального диапазона, что они эффективно реализуются на целевой платформе.

 

PS. В общем случае значительно грамотнее объявлять собственные типы - Ada для этого и создавалась.

 

Сомневаюсь, что грамотнее. Замучаешься потом в арифметических выражениях их преобразовывать. Гораздо грамотнее, IMHO, создавать subtype на базе какого-то одного целочисленного типа. subtype для этого и создавался. :)

 

Это заблуждение. Строгая типизация не только не усложняет жизнь, но и помогает, отлавливая многие ошибки на этапе компиляции.

 

--

Olleg Samoylov

 

 

 

--

Maxim Reznik

Olleg wrote:

 

Эти типы обвъявлены в корневом Interfaces, так что о взаимодействии с одноименными языками говорит сложно, т.к. непонятно для взаимодействия с каким языком они создавались. И бонус, что я пока нашел, для модульных целых чисел из Interfaces присутствует побитовый сдвиг и вращение, что делает их уникальными. Кроме того, только у них есть явное указание, сколько байт данное число занимает в памяти, что может быть полезно, например, для разбора заголовков сетевых пакетов.

 

Последнее не верно. Для сетевых паетов важен ещё и порядок следования байт.

Нашел некоторые ответы на свои вопросы. :)

 

Maxim Reznik wrote:

On Wed, Jan 18, 2006 at 11:17:29AM +0300, Olleg wrote:

Эти типы обвъявлены в корневом Interfaces, так что о взаимодействии с одноименными языками говорит сложно, т.к. непонятно для взаимодействия с каким языком они создавались.

То что лежит в корневом Interfaces это интеграция с ассемблером. ;) Вот

из AARM "in particular for interfacing to assembly language".

 

Типы Interfaces.Integer_* и Unsigned_* имеют определенную

длинну, но их набор может меняться в компиляторах и платформах.

 

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

 

И бонус, что я пока нашел, для модульных целых чисел из Interfaces присутствует побитовый сдвиг и вращение, что делает их уникальными. Кроме того, только у них есть явное указание, сколько байт данное число занимает в памяти, что может быть полезно, например, для разбора заголовков сетевых пакетов.

 

Теперь очевидно, почему сдвиг и ротация находятся только здесь. В

ассемблере это выполняется одной машинной командой. :)

 

PS. В общем случае значительно грамотнее объявлять собственные типы -

Ada для этого и создавалась.

 

Сомневаюсь, что грамотнее. Замучаешься потом в арифметических выражениях их преобразовывать. Гораздо грамотнее, IMHO, создавать subtype на базе какого-то одного целочисленного типа. subtype для этого и создавался. :)

 

Это заблуждение. Строгая типизация не только не усложняет жизнь, но

и помогает, отлавливая многие ошибки на этапе компиляции.

 

Я вас понимаю, а вы меня нет. :) Вот смотрите, стандартный Integer -

гарантированно до 32тыс. Для очень многих задач этого мало. Вы

предлагаете создать свой тип. В результате каждая библиотека будет

вынуждена создать свой тип 32битного целого числа и дальше при

необходимости его наследовать. Для работы с библиотеками, надо будет

постоянно "перекодировать" 32битное целое из одной библиотеки в другую,

хотя на самом деле они одинаковы, и имеют одинаковый смысл, кол-во штук.

По обилию скобок и трудности чтения ада начнет напоминать Lisp. %)

Наличие чего-то похожего на стандартный тип Long_Integer ситуацию может

разрядить.

 

Мне кажется, если речь идет, например, о натуральных числах, не стоит

плодить разные их типы, надо ограничиваться подтипами. Правда опыта

программирования на аде у меня нет, все больше java или C. :)

-- Olleg Samoylov

Olleg wrote:

 

>Я вас понимаю, а вы меня нет. :)

 

Для того что бы Вас понимали, надо ясно излагать свои потребности. Уверяю Вас, здесь понятливые люди собрались.

 

Вот смотрите, стандартный Integer -

>гарантированно до 32тыс. Для очень многих задач этого мало. Вы

>предлагаете создать свой тип. В результате каждая библиотека будет >вынуждена создать свой тип 32битного целого числа и дальше при

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

 

В одной архитектуре, в разных библиотеках с большой вероятностью у целых типов будет одинаковое физическое представление.

если биндиться к С функциям содержащим int параметры, то грамотнее использовать тип Interfaces.c.int, но Ада тип Integer тоже прокатит, по крайней мере на 32 разрядной архитектуре x86.

п'ятниця, 20. січень 2006 08:56, Olleg Ви написали:

Это заблуждение. Строгая типизация не только не усложняет жизнь, но и помогает, отлавливая многие ошибки на этапе компиляции.

>

Я вас понимаю, а вы меня нет. :) Вот смотрите, стандартный Integer - гарантированно до 32тыс. Для очень многих задач этого мало. Вы

Именно поэтому нужно использовать не Integer32 или просто Integer, а: type MyInt is range -100_000_000 .. 100_000_000; -- например

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

предлагаете создать свой тип. В результате каждая библиотека будет вынуждена создать свой тип 32битного целого числа и дальше при

необходимости его наследовать. Для работы с библиотеками, надо будет постоянно "перекодировать" 32битное целое из одной библиотеки в другую,

Ни в коем случае так делать не следует!

В библиотеках работающих с числами подобным образом (где нужна гибкость) стоит

использовать generics. Именно для этого (не только, но как одно из основных применений) они и были введены в стандарт. Что не только решает проблемму "скобок", но и позволяет компилятору лучше оптимизировать код (за счет избавления от ненужных range checks и т.п.).

хотя на самом деле они одинаковы, и имеют одинаковый смысл, кол-во штук. По обилию скобок и трудности чтения ада начнет напоминать Lisp. %)

Это про casting здесь? Значит вы неправильно применяете типизацию ;), обычно правильно определенные типы как раз уменьшают потребность в castingе, или по крайней мере не увеличивают..

George

Новое сообщение:
Страницы: 1

Чтобы оставить новое сообщение необходимо Зарегистрироваться и Войти