Маленький сюрприз при переходе на 64x

флоппик

promotor fidei
Команда форума
Партнер клуба
Причем такое поведение задокументировано. И то, что поведение функции отличается на различных платформах, должно быть в первую очередь предусмотрено пользователем этой функции
Проблема в том, что язык высокого уровня по определению предназначен для того, что бы скрывать разницу между платформами, на которых он работает. Поэтому - это баг.
 

Santiago

Новичок
флоппик
Это был бы баг, если бы такое поведение не было бы задокументировано.
 

Wicked

Новичок
Santiago
тесты из поставки сорцов кагбе не очень имеют отношение к документации.
или оно где-то еще задокументировано? :)
 

Santiago

Новичок
Wicked
Спорить не буду. Вопрос в том, что видимо не все представляют, как хранятся отрицательные числа в компьютере. Поэтому и возникают такие топики.
 

флоппик

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

Santiago

Новичок
Wicked
Чем отличаются числа 4294967040 на 64-х битах и -256 на 32х битах?
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Автор оригинала: Santiago
Именно так и есть. Причем такое поведение задокументировано. И то, что поведение функции отличается на различных платформах, должно быть в первую очередь предусмотрено пользователем этой функции (опять же, в случае документирования сего факта).
Оно нормально не задокументировано, в том-то и дело. Я в параллельном топике про crc32() уже писал, нормальным было прямое указание в документации на то, что функция по-разному себя ведёт на разных платформах. Видимо разработчики (справедливо) полагают, что после написания подобного замечания на них будут показывать пальцем и смеяться.

-~{}~ 16.06.09 17:49:

Автор оригинала: Santiago
Вопрос в том, что видимо не все представляют, как хранятся отрицательные числа в компьютере.
Ты чё, от tony2001 понтами заразился? Тока мы все знаем, что полезного tony2001 сделал, и поэтому относимся к нему с (относительным) уважением.
 

Santiago

Новичок
Автор оригинала: Sad Spirit
Оно нормально не задокументировано, в том-то и дело. Я в параллельном топике про crc32() уже писал, нормальным было прямое указание в документации на то, что функция по-разному себя ведёт на разных платформах. Видимо разработчики (справедливо) полагают, что после написания подобного замечания на них будут показывать пальцем и смеяться.
Sad Spirit
Так все же это баг или вопрос неполной документации? Если тебе кажется, что документацию надо дополнить, можно это предложить на тот же php.doc. Видимо, для кого-то очевидно, что представление signed int на разных платформах будет различным, для кого-то нет.

Ты чё, от tony2001 понтами заразился? Тока мы все знаем, что полезного tony2001 сделал, и поэтому относимся к нему с (относительным) уважением.
Не стоит видеть везде негатив. Просто когда "это вызвало вообще ступор сервака и никто 2-е суток не мог понять в чём трабел" это говорит о том, о чем я сказал выше.
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Автор оригинала: Santiago
Так все же это баг или вопрос неполной документации? Если тебе кажется, что документацию надо дополнить, можно это предложить на тот же php.doc. Видимо, для кого-то очевидно, что представление unsigned int на разных платформах будет различным, для кого-то нет.
Медленно и печально: в похапэ нету никакого unsigned int. Поэтому на обеих платформах мы получаем signed int, но на 32-битной он почему-то отрицательный, а на 64-битной --- положительный. Вот этот факт и надо отразить в документации: "внимание! результат этой функции зависит от разрядности платформы, фазы луны и вида кишок жертвенного животного".
 

Santiago

Новичок
Sad Spirit
Да, извини, описАлся. В тот и дело, что signed.

Теперь смотрим функцию ip2long

unsigned long int ip;
----- skip----
if (Z_STRLEN_PP(str) == 0 || (ip = inet_addr(Z_STRVAL_PP(str))) == INADDR_NONE) {
----- skip----
RETURN_LONG(ntohl(ip));


Учитывая , что uint32_t ntohl(uint32_t netlong); и RETURN_LONG возвращает signed long, становится понятным, почему он отрицательное на 32х битах
Так что никаких фаз луны тут нет. Для конечного пользователя сказано в документации, что если нужно unsigned представление числа, нужно использовать %u. Кому надо узнать почему так, лезет в сурс. Поэтому лично я и не вижу, в чем здесь баг.
 

Kelkos

Сам себе программер
Кстати, ради прикола попробовал пример от Wicked
PHP:
function ip2long32($ip_address) {
  return ip2long($ip_address) & 0xffffffff;
}
Вобще то, не рабочий (а никто и не заметил.) ;)

рабочий типа этого:
PHP:
function ip2long32($ip_address) {
	$int_32=unpack('l',pack('l',ip2long($ip_address)));
	return $int_32[1];
}
Ну это так... Что бы никто не наделал ошибок после прочтения топика.

Продолжайте дальше теорию гнуть. Я читаю.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
мне кажется, рабочим может быть вариант
$addr = sprintf('%u',ip2long('255.255.255.0'));
а в комментах в документации стоит написать об этом

-~{}~ 16.06.09 20:22:

вообще, у PHP документация намного приятней, чем, например, у Python
 

Wicked

Новичок
Вобще то, не рабочий (а никто и не заметил.)
потрясающее сообщение об ошибке .-))))

-~{}~ 17.06.09 00:44:

мне кажется, рабочим может быть вариант
$addr = sprintf('%u',ip2long('255.255.255.0'));
ну это если преобразовывать к unsigned int всегда, что не очень хорошо на 32-битных машинах, т.к. кроме как в виде строки там такие числа не записать. В топике же речь шла о преобразовании 64 bit unsigned int в 32 bit signed

-~{}~ 17.06.09 01:00:

но ладно, с тем, что код не работает, соглашусь :)
 

Lightning

Трудоголик
Автор оригинала: флоппик
Проблема в том, что язык высокого уровня по определению предназначен для того, что бы скрывать разницу между платформами, на которых он работает. Поэтому - это баг.
C++ тоже язык высокого уровня, но разницу между платформами не скрывает.
Но а вообще я согласен с тем, что в данном случае это баг.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
C++ тоже язык высокого уровня, но разницу между платформами не скрывает.
http://ru.wikipedia.org/wiki/Си_плюс_плюс
Философия Си++
....
Избегать особенностей, которые зависят от платформы или не являются универсальными.
....
 

phprus

Moderator
Команда форума
флоппик
Скажи пожалуйста, чему равен размер типа int(или любого другого) в байтах? Если думаешь, что 4 или какое-либо определенное число, то нет. В стандарте написано, что это зависит от реализации и дано только указание на то, как должны соотноситься размеры разных типов. Так что различия аппаратных платформ С++ скрывает далеко не везде.

Что касается темы, то я думаю что поведение php является верным, но почему-то не достаточно документированным. В имени функции ip2long прописано в какой тип преобразуется ip-адрес, но никто, ни разработчики PHP, ни стандарт С не может гарантировать размер типа long на различных платформах. По этому и всплывают такие платформенно-зависимые вещи.

Что касается программирования сети на С в никсах, то в стандартной библиотеке для представления адресов используются специальный типы и функции, а в какой тип эти typedef'ы развернуться на конечной платформе это уже заботы тех, кто писал стандартную библиотеку, а не тех, кто писал прикладные программы.
 

Lightning

Трудоголик
флоппик
буахахаха.
Что ты кидаешься ссылкой на википедию? :)
Ты на C++ программировал?
Как ты думаешь, для чего там есть оператор sizeof?

http://msdn.microsoft.com/en-us/library/4s7x1k91(VS.71).aspx
This operator allows you to avoid specifying machine-dependent data sizes in your programs.
В C++ программер должен сам заботиться о совместимости, проверяя когда нужно размерность типов ручками при помощи sizeof().

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

Где написано, что PHP - переносимый ЯП?

-~{}~ 17.06.09 00:38:

Что касается темы, то я думаю что поведение php является верным, но почему-то не достаточно документированным. В имени функции ip2long прописано в какой тип преобразуется ip-адрес, но никто, ни разработчики PHP, ни стандарт С не может гарантировать размер типа long на различных платформах
Где в PHP тип long?

-~{}~ 17.06.09 00:52:

Посмотрел документацию внимательно. Это не баг :)

http://www.php.net/manual/en/language.types.integer.php
The size of an integer is platform-dependent
http://www.php.net/manual/en/function.ip2long.php
int ip2long ( string $ip_address )
Note: Because PHP's integer type is signed, and many IP addresses will result in negative integers, you need to use the "%u" formatter of sprintf() or printf() to get the string representation of the unsigned IP address.
Все так и есть, как написано :)

-~{}~ 17.06.09 00:58:

Разработчикам надо бы добавить в PHP unsigned int.
 

zerkms

TDD infected
Команда форума
вообще, у PHP документация намного приятней, чем, например, у Python
потому что рассчитана на специалистов немного другого уровня подготовки :)
 

phprus

Moderator
Команда форума
Lightning
Где в PHP тип long?
В php нету, но в названии функции прописано такое слово и у меня, как у пишущего на С сразу-же возникает соответствующая ассоциация про то, что на выходе может дать эта функция. При том они соответствует тому, что происходит в реальности по этому я и считаю поведение PHP верным.

В C++ программер должен сам заботиться о совместимости, проверяя когда нужно размерность типов ручками при помощи sizeof().
На сколько я помню, все еще хуже. sizeof дает размер типа не в байтах, а в char'ах, тоесть sizeof(char) по определению равен 1, но никто не гарантирует, что в байтах тип char занимает ровно один байт.
 
Сверху