Избегать слишком много кастинга - PullRequest
1 голос
/ 25 ноября 2010

В настоящее время я работаю над проектом, который включает поиск и перемещение элементов в графиках.Я подумал, что пакет igraph довольно хорош для моих простых потребностей, однако, поскольку я привык работать с Java, некоторые вещи не ясны.

Почему, например, делаютлюди, которые создали пакет igraph, переопределяют базовые элементы, такие как целые числа, как 'igraph_integer_t'?Есть ли способ избежать приведения всех обратно к целым числам каждый раз, когда я вызываю функцию из их библиотеки, так как это делает код довольно грязным?

Ответы [ 3 ]

2 голосов
/ 25 ноября 2010

Как один из авторов igraph, я понимаю, что это сомнительное дизайнерское решение, которое было принято в самом начале проекта. Первоначально предполагалось «добавить слой абстракции»: раньше мы работали с научным исходным кодом, где приложение везде использовало int, и из-за проблем переполнения пришлось заменить все int на long все через исходный код, чтобы заставить программу работать с проблемой, с которой мы были представлены. Вот почему у нас есть igraph_integer_t вместо простого int или long - если вы обнаружите, что тип данных igraph_integer_t слишком мал для ваших проблем, вам придется изменить только одно место в исходном коде.

В ретроспективе приведенный выше сценарий довольно редок, поэтому, вероятно, это довольно слабый аргумент. Чтобы усложнить ситуацию, igraph_integer_t является typedef'd к double из-за боязни случаев, когда тип данных long недостаточно на всех платформах. (Один из сценариев, о котором я могу подумать сейчас, - это подсчет мотивов на большом графике - число мотивов, хотя и является целочисленным, может легко превысить пределы типа данных long на старых платформах). Поскольку в то время, когда было принято решение о igraph_integer_t, его не было вокруг проекта, возможно, это не является точной причиной, я думаю, это было именно так. Не стесняйтесь спрашивать в списке рассылки igraph-help , если вы заинтересованы в кровавых деталях. В любом случае, я часто использую ядро ​​C в igraph (так как я отвечаю за оболочки Python), поэтому я могу с уверенностью сказать, что нет необходимости в приведении между igraph_integer_t и другими типами данных, кроме двух случаев:

  1. При использовании значения igraph_integer_t в printf. Вы должны либо привести igraph_integer_t к long и использовать %ld в строке формата, либо не выполнять преобразование и использовать %g в строке формата (что неявно полагается на igraph_integer_t, являющуюся double).

  2. При индексировании массива с igraph_integer_t. Вы, очевидно, должны привести его к long.

1 голос
/ 25 ноября 2010

Это довольно неприятная практика, которую делают многие библиотеки без веской причины.Посмотрите на тип igraph_integer_t.Если это int, что я и ожидал, просто используйте int везде и притворяйтесь, что igraph_integer_t не существует.Там нет абсолютно никакой необходимости в кастах.Все целочисленные типы (и числа с плавающей запятой) неявно преобразуются в C, и типы C typedef в любом случае не считаются отличными от их определений.

0 голосов
/ 25 ноября 2010

Я не знаю, возможно ли это (я не знаю этот пакет), но вы должны использовать igraph_integer_t в своем собственном приложении или создать структуру вокруг igraph для общения с ним.

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

В двух словах: добавьте слой абстракции.

...