2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3, 4, 5, 6  След.
 
 Re: Сравнение двух стилей программирования
Сообщение14.12.2012, 02:51 
Аватара пользователя


31/10/08
1244
Качественный код дело не простое.
С одной стороны. Хочется предусмотреть все несчастные случае и добавляешь проверки.
С другой стороны хочется писать чистый код не загромождая его проверками. И это возможно писать качественный код без проверок или с минимальным числом проверок.

И это только одна сторона качественного кода.

Арифметические операции подвержены переполнения переменных. И для устранения этого в одних языках/библиотеках применяют соглашения о автоматической конвертирование типов. В других напротив применяют длинную арифметику.

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

Если ничего не делать то и качественный код не получиться. Поэтому и следует стараться как можно сильнее. Есть куча советов о том как сделать ваш код более качественным.

Но сейчас лично меня интересует как писать код с минимальным числом проверок входных параметров. Какие языки способствуют этому?

 Профиль  
                  
 
 Re: Сравнение двух стилей программирования
Сообщение14.12.2012, 13:40 
Заслуженный участник


09/09/10
3729
ewert в сообщении #658180 писал(а):
Должен скомпилироваться по логике языка (Дельфи -- это всё-таки Паскаль). Он же заранее не знает, байт там выйдет в момент обращения, или два, или ещё сколько.

Я или схожу с ума, или реально уже все позабыл? Компилятор видит вызов процедуры с аргументом типа Integer, он знает, что формальный параметр имеет тип Byte, он знает, что автоматического преобразования из Integer в Byte нету — и прекращает трансляцию с ошибкой.

Ладно, щас поставим, посмотрим.

-- Пт дек 14, 2012 14:45:15 --

Pavia в сообщении #658193 писал(а):
С другой стороны хочется писать чистый код не загромождая его проверками. И это возможно писать качественный код без проверок или с минимальным числом проверок.

Например:
Код:
export int func(Type params);

int func(Type params) {
  return _checkFuncParams(params) ? _funcImpl(params) : -1;
}


В функции _funcImpl никаких проверок уже нет, но она не экспортируется и видна только вам, как создателю модуля.

Pavia в сообщении #658193 писал(а):
Но сейчас лично меня интересует как писать код с минимальным числом проверок входных параметров. Какие языки способствуют этому?

Любые с поддержкой исключений. Нагрузка на проверку корректности ложится не на процедуру, а на того, кто ее вызывает.

 Профиль  
                  
 
 Re: Сравнение двух стилей программирования
Сообщение14.12.2012, 14:10 
Заслуженный участник


11/05/08
32166
Joker_vD в сообщении #658276 писал(а):
он знает, что автоматического преобразования из Integer в Byte нету

Ну как он может это знать, когда фактическим параметром может вообще быть даже не переменная, а выражение.

 Профиль  
                  
 
 Re: Сравнение двух стилей программирования
Сообщение14.12.2012, 14:29 
Заслуженный участник


09/09/10
3729
ewert в сообщении #658284 писал(а):
Ну как он может это знать,

А как сишарповский компилятор это знает? У любого выражения есть вполне определенный тип. Просто в Си/Си++/Дельфи все целые типы автоматически преобразуются друг в друга (что довольно печально).

 Профиль  
                  
 
 Re: Сравнение двух стилей программирования
Сообщение14.12.2012, 17:41 
Заслуженный участник


09/09/10
3729
И да, я действительно ошибался, когда говорил, что
Joker_vD в сообщении #658276 писал(а):
автоматического преобразования из Integer в Byte нету

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

 Профиль  
                  
 
 Re: Сравнение двух стилей программирования
Сообщение14.12.2012, 17:46 


05/09/12
2587
Все эти разговоры про дебаггабал, модифайабал и реюзабал, писать функции как библиотечные и т.п. конечно очень правильны и хороши. Однако, буквально сейчас, написал 3 своих функции - аналогов printf. Которые ничего не проверяют, мизерно форматируют и шлют данные в выходной поток. А за корректностью передаваемых данных я слежу при их вызове. Казалось бы - зачем, когда эта функция написана, есть в стандартной библиотеке и вызывается с кучей вариантов входных переменных и форматирования вывода? А затем, что я вывожу данные в отладочную печать в терминалы, у меня распределенная система реального времени из нескольких МК, связанных по радиоканалу, и я потратил достаточно времени чтобы понять, что ошибки возникают не из-за неправильной логики моего кода, а просто потому что стандартный библиотечный prinf безобразно медленный (за счет своей долбаной универсальности), и не влезает в мои тайм-слоты, которые я отвожу на различные ситуации.

 Профиль  
                  
 
 Re: Сравнение двух стилей программирования
Сообщение14.12.2012, 19:36 
Заслуженный участник


11/05/08
32166
Joker_vD в сообщении #658296 писал(а):
Просто в Си/Си++/Дельфи все целые типы автоматически преобразуются друг в друга (что довольно печально).

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

-- Пт дек 14, 2012 20:49:36 --

Joker_vD в сообщении #658378 писал(а):
передать в подпрограмму байт не выйдет, передается минимум машинное слово,

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

 Профиль  
                  
 
 Re: Сравнение двух стилей программирования
Сообщение14.12.2012, 20:32 
Заслуженный участник


09/09/10
3729
ewert в сообщении #658424 писал(а):
Что довольно правильно. Ведь, в конце-то концов, все разумные типы просто обязаны автоматически приводиться друг к другу. Кроме неестественных ситуаций -- но это уже обязанность программиста предусмотреть эти особые случаи; ведь никто, кроме него, не сможет предугадать, когда те случаи возникнут в его конкретных задачках.

Вещественные автоматом к целым не приводятся; односимвольные строки не приводятся автоматом к символам; строки вообще автоматом к числовым типам не приводятся; в Java int автоматом к byte не приводится... да вообще неявное приведение численных типов — источник труднообнаружимых ошибок, потому что в общем-то типы друг к другу автоматом приводиться в любом направлении не должны. Велика радость: нечаянно обронить три байта из четырех.

ewert в сообщении #658424 писал(а):
Да нет, теоретически можно передать даже хоть и байт

На x86 невозможно положить на стек ровно байт.

 Профиль  
                  
 
 Re: Сравнение двух стилей программирования
Сообщение14.12.2012, 21:08 
Заслуженный участник


04/05/09
4587
Joker_vD в сообщении #658446 писал(а):
Велика радость: нечаянно обронить три байта из четырех.
Мало чем отличается от переполнения при сложении.

Joker_vD в сообщении #658446 писал(а):
На x86 невозможно положить на стек ровно байт.
Можно, для этого не обязательно пользоваться командой push. Есть ещё зачастую более эффективная команда mov, и хороший компилятор ею пользуется, если это выгодно.

 Профиль  
                  
 
 Re: Сравнение двух стилей программирования
Сообщение14.12.2012, 21:20 
Заслуженный участник


11/05/08
32166
Joker_vD в сообщении #658446 писал(а):
да вообще неявное приведение численных типов — источник труднообнаружимых ошибок

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

В том же Паскале есть механизм приведения типов (или уж не помню, как он называется). Запросто можно написать то-нибудь типа byte(c):=i или там char(b):='&', или наоборот, и это весьма эффективно. Если, конечно, хоть изредка приходить в сознание.

 Профиль  
                  
 
 Re: Сравнение двух стилей программирования
Сообщение14.12.2012, 22:05 
Заслуженный участник


09/09/10
3729
venco в сообщении #658469 писал(а):
Мало чем отличается от переполнения при сложении.

Отличается, и сильно: переполнение приводит к установке OF, это легко отследить. А вот как узнать, что старшие три байта никто не читал?

venco в сообщении #658469 писал(а):
Можно, для этого не обязательно пользоваться командой push. Есть ещё зачастую более эффективная команда mov, и хороший компилятор ею пользуется, если это выгодно.

Как все-таки здорово, что x86 позволяет misalignment, правда? На ARM это не прокатило бы, ну так там и параметры традиционно идут в регистрах — которые отнюдь не байтовые.

ewert в сообщении #658475 писал(а):
В том же Паскале есть механизм приведения типов (или уж не помню, как он называется). Запросто можно написать то-нибудь типа byte(c):=i или там char(b):='&', или наоборот, и это весьма эффективно. Если, конечно, хоть изредка приходить в сознание.

Вот именно — есть механизм явного приведения типов (в любом языке). И используется он для двух вещей:
1) Сказать компилятору "Ты этого не знаешь, но на самом деле это значение — вот такого типа, а не того, которого ты думаешь". При этом никакого кода не генерируется, просто компилятор начинает считать, что тип у переменной другой. Пример: char *t = (char*)malloc(32 * sizeof(char));
2) Сказать компилятору "Я хочу преобразовать значение одного типа в значение другого типа". При этом компилятор вставляет код, который преобразует значение одного типа в значение другого типа. Пример: float x = 2.0; int y = (int)x;

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

 Профиль  
                  
 
 Re: Сравнение двух стилей программирования
Сообщение14.12.2012, 22:11 
Заслуженный участник


04/05/09
4587
Joker_vD в сообщении #658495 писал(а):
venco в сообщении #658469 писал(а):
Мало чем отличается от переполнения при сложении.

Отличается, и сильно: переполнение приводит к установке OF, это легко отследить.
Это в каком языке есть такая возможность?

Joker_vD в сообщении #658495 писал(а):
venco в сообщении #658469 писал(а):
Можно, для этого не обязательно пользоваться командой push. Есть ещё зачастую более эффективная команда mov, и хороший компилятор ею пользуется, если это выгодно.

Как все-таки здорово, что x86 позволяет misalignment, правда? На ARM это не прокатило бы, ну так там и параметры традиционно идут в регистрах — которые отнюдь не байтовые.
1. Причём тут выравнивание? У байтов его нет.
2. Причём тут ARM? Вы ведь явно про x86 говорите.

 Профиль  
                  
 
 Re: Сравнение двух стилей программирования
Сообщение14.12.2012, 22:18 
Заслуженный участник


09/09/10
3729
venco в сообщении #658498 писал(а):
Это в каком языке есть такая возможность?

Ассемблер. А Java VM и .NET CLR так вообще швыряют OverflowException.

venco в сообщении #658498 писал(а):
1. Причём тут выравнивание? У байтов его нет.

Если вы положите в стек байт, то положенное вслед за ним 4-байтное слово будет либо а) невыровненным, либо б) выровненным за счет 3-байтного дополнения — т.е. вы положили все-таки не байт, а 4 байта.

venco в сообщении #658498 писал(а):
2. Причём тут ARM? Вы ведь явно про x86 говорите.

Хорошо, давайте поговорим про Itanium. Реальный пример: В Win32 API есть структура FILETIME:
Код:
typedef struct _FILETIME {
  DWORD dwLowDateTime;
  DWORD dwHighDateTime;
} FILETIME, *PFILETIME;

Она имеет размер в 8 байт, она держит младшую и старшую половины 64-разрядного целого, и некоторые товарищи обращались с ней как с __int64:
Код:
pi = (__int64*)&ft;
(*pi) += (__int64)num*datepart;


Но вот беда — такой код часто приводил к STATUS_DATATYPE_MISALIGNMENT, угадайте почему.

 Профиль  
                  
 
 Re: Сравнение двух стилей программирования
Сообщение14.12.2012, 22:26 
Заслуженный участник


04/05/09
4587
Joker_vD в сообщении #658502 писал(а):
venco в сообщении #658498 писал(а):
Это в каком языке есть такая возможность?

Ассемблер. А Java VM и .NET CLR так вообще швыряют OverflowException.
Ну так они и при преобразовании int в byte то же самое швыряют.

Joker_vD в сообщении #658502 писал(а):
venco в сообщении #658498 писал(а):
1. Причём тут выравнивание? У байтов его нет.

Если вы положите в стек байт, то положенное вслед за ним 4-байтное слово будет либо а) невыровненным, либо б) выровненным за счет 3-байтного дополнения — т.е. вы положили все-таки не байт, а 4 байта.
У вас какое-то превратное представление. Естественно, так никто не делает, ибо невыровненные данные уменьшают эффективность. А делают совсем не так - пишут ровно один байт в 4-байтовый блок в стеке. Каждый параметр выравнен как ему надо.

Joker_vD в сообщении #658502 писал(а):
venco в сообщении #658498 писал(а):
2. Причём тут ARM? Вы ведь явно про x86 говорите.

Хорошо, давайте поговорим про Itanium...
Зачем вы уводите разговор в сторону? Мы ведь про переполнение говорили, а вы всё про выравнивание.

 Профиль  
                  
 
 Re: Сравнение двух стилей программирования
Сообщение14.12.2012, 23:24 
Аватара пользователя


27/01/09
814
Уфа
Если уж про эту задачу говорить, то Read можно внутрь AddElement затолкать и ничего передавать не надо будет и он будет единственным, заполняющим список присоединением к списку по мере надобности, а для вставки элемента в произвольное место над специальную процедуру сделать и функцию поиска элемента соответственно. Но для дата-поля динамической структуры интеджера всё равно как-то маловато будет, поэтому можно передавать ссылку на дата-структуру (или нетипизированную) и ссылку на функцию заполнения полей дата-структуры, но т.к. заголовком темы были стили программирования то уже лучше с ООП сравнивать. А на уровне оформления повторяющегося кода в виде подпрограмм в пределах одной программы надо обсуждать как в подпрограмму передаются параметры и как возвращаются.
Оптимизировать код для x86 не имеет смысла, т.к. он всё равно эмулируется и читать по 32 или 64 бита одинаково по времени что читать 8 или 16 бит, если же конечно вы не решили упаковывать 8 бит по по 4 в 32 бита.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 82 ]  На страницу Пред.  1, 2, 3, 4, 5, 6  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group