LINUX.ORG.RU

K&R C Вопрос

 , , ,


0

2
/* atoi: преобразует строку s в целое число */

int atoi (char s [] )

{ int i, n;
  n = 0;
  for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
    n = 10 * n + (s [i] - '0' ) ;
 return n;
}

Возник вопрос на интуитивном уровне:

А зависит ли реализация данной функции (пусть даже в таком примитивном варианте) от порядка байтов машины на которой она выполняется?

cast beastie

Перемещено JB из talks

★★★★★

Ответ на: комментарий от Twissel

Ты не спеши. Сейчас тут такой срач разведётся, что все мы 3 раза поменяем свою точку зрения и сойдёмся на том, что Ельцин это сплав жёлтого и бобра.

Stahl ★★☆ ()
Ответ на: комментарий от Twissel

Порядок байт в char* от "конечности" не зависит! Вот если ты будешь разбирать побайтно какую-нибудь uint64_t, то здесь тебе нужно на конечность системы ориентироваться.

И да, даже если бы какая-то извращенная система имела конечнозависимый порядок символов в char*, тебе все равно было бы на это насрать, т.к. write выводит их в таком же порядке, как пишет read. Ну и как ты заполняешь.

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Stahl

Не знаю, я думал, что здешние погромисты классику зачитали до дыр.

В отличии от меня

Twissel ★★★★★ ()
Ответ на: комментарий от Eddy_Em

Откуда взялся s? Вот в чём вопрос. Если он заполнялся аналогичным образом побайтово, то и разницы никакой нет. Мы знаем какой байт-литера на какой позиции. И железо тут ничего менять без нашего ведома не будет.

Stahl ★★☆ ()
Последнее исправление: Stahl (всего исправлений: 1)

Кстати, прикинь: я больше года думал, что мои STM32 тупоконечные, пока не наткнулся в RM о том, что они — тоже остроконечные! (правда, в некоторых более крутых моделях можно системными регистрами конечность менять).

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

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Stahl

Тебе должно быть безразлично, откуда он взялся. Поверь мне, и на остроконечных, и на тупоконечных машинах этот код будет работать одинаково. И он одинаково паршив везде. Если ты не для микроконтроллера пишешь, то забудь про atoi, пользуйся strtoll.

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Twissel

«Порядок байт» относится к многобайтным типам данных. char[] это массив однобайтных. Нумерация символов в нём происходит естественным образом также как при чтении.

kim-roader ★★ ()
Ответ на: комментарий от Eddy_Em

В char* не зависит, безусловно.

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

Или я не понимаю специфики работы кода?

Twissel ★★★★★ ()
Ответ на: комментарий от Twissel

Она запихнет их в правильном порядке, т.к. самым первым символом в char* будет старший разряд.

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em

ЭТОТ код да, тут ломаться нечему. Если s придёт в правильной последовательности, то всё ок. Но вопрос, как мне кажется, был в другом: вот есть реализация atoi и можно ли её такую использовать в любом случае.
Никто же не гарантирует, что заполнение массива будет по байтам? Может там словами считывается, а потом уже приводится всё к char*. И в таком случае мы получим беду-беду-огорчение.

Stahl ★★☆ ()
Ответ на: комментарий от Stahl

Эм. Ты хочешь сказать, что если пользователь даст функции какую-то фигню, вместо строки с числом, то функция не запустит предсказатель из libastral.so?

kim-roader ★★ ()
Ответ на: комментарий от Eddy_Em

EBCDIC например. Хотя цифры там тоже компактно и по порядку.

PolarFox ★★★★★ ()
Ответ на: комментарий от Stahl

Вот и я говорю, что его там нет. Так зачем ты придумываешь случай, когда переданный char* ссылается на что-то отличное от строки с числом?

kim-roader ★★ ()
Ответ на: комментарий от Stahl

Никто же не гарантирует, что заполнение массива будет по байтам?

Архитектура гарантирует. Если заполнение массива будет не по байтам (а, скажем, с выравниванием на 64 бита), то и твой код будет с таким же выравниванием брать индексы!

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от kim-roader

Потому что s, вероятней всего, просто сраный буфер, куда считывается строка. Если запить туда идёт не по 1 байту, то возможны варианты.
Это вполне логичный и распространённый вариант. Нахрена читать по байту если есть возможность читать словами?
Но если отталкиваться только от кода, который приведён и принять за данность, что содержимое s в очевидном порядке, то у меня возражений нет — код будет работать на любой машине одинаковым образом.

Stahl ★★☆ ()
Ответ на: комментарий от Eddy_Em

Удивительно. Но Эдик в этом топике выглядит самым адекватным.

Все верно он говорит. Одинаково этот код будет везде работать.

anonymous ()
Ответ на: комментарий от Stahl

Нахрена читать по байту если есть возможность читать словами?

А что, есть вариант, когда read(fd, uint64_t, 8) считает тебе в буфер не в том порядке, как оно на диске было, а задом-наперед? Это как?

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em

Выделили память.
Прочитали int.
Записали его в эту память.
Дальше приводим это к char* и работаем как со строкой.
Что тут архитектура будет гарантировать? Никто тут не вмешается.

Stahl ★★☆ ()
Ответ на: комментарий от Stahl

Что тут архитектура будет гарантировать?

Она будет гарантировать, что порядок байт будет тем же самым. Иначе ты на этом говне вообще работать не сможешь, т.к. вместо 0xaabb прочитаешь 0xbbaa.

Другое дело — что в самом int уже порядок байт может иметь разное значение. Но тебя в данном случае это никак не касается!

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em

Хм. Ну ты прав в том, что, как ни крути, но именно строка не возьмётся откуда-то покорёженной. Даже если она будет генерироваться на лету в коде, сложно предположить, что она будет создаваться не побайтно.
Ок. Молчу.

Stahl ★★☆ ()

Пока дело отдельных байтов (или пересылки по сети мультибайтных значений) не касается, то зависить нечему.

beastie ★★★★★ ()

Хорошо, т.е. вся суть в том, что char* обрабатывается напрямую — побайтно.

И меняться тут просто нечему, так?

Twissel ★★★★★ ()
Ответ на: комментарий от beastie

А я-то думал, что network byte order везде один :3 Два слова htons() и htonl()
P.S. Обожаю треды про Си, сколько радости они приносят! Какие страсти, какие драмы! Добра всем ИТТ.

fero ★★★★ ()
Последнее исправление: fero (всего исправлений: 1)
Ответ на: комментарий от Stahl

Ещё раз, ты понимаешь что такое строка? Строка - это кусок адресспейса, где min начало, а max конец. Это определено, что строка читается вверх по адресам, как и любая память. Вся память выделяется вверх - это тоже определено.

Никто же не гарантирует, что заполнение массива будет по байтам?

Ты понимаешь что такое вообще этот порядок байт? Это представление данных в регистре(битиков), а не в памяти.

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

Может там словами считывается, а потом уже приводится всё к char*

И? Какая разница как это считается - считывается память в регистр так же, как и кладётся обратно.

Вот иди возми 12кубиков и беря по 4 и кладя по 4 в том порядку, в котором взял и кладя туда, откуда взял попробуй сделать «биду-пичаль».

TrueTsar1C ()
Ответ на: комментарий от beastie

Пока дело отдельных байтов

Эти эксперты, эти эксперты.

Пока дело отдельных байтов МУЛЬТИБАЙТНЫХ ЗНАЧЕНИЙ

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

TrueTsar1C ()
Ответ на: комментарий от Twissel

Видно кто-то из палаты выпустил и сюда внес.

anonymous ()

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

</thread>

вброс хитер, но уныл

anonymous ()
Ответ на: комментарий от TrueTsar1C

уйди, болезный, не похож ты на царя, не похож

anonymous ()
Ответ на: комментарий от i-rinat

Пиши-пиши, я всегда ищу.

Я тут уже подписался на коечто, но тут нас ждут ещё месяцы общения с пациентом во имя понимания и захвата мира.

TrueTsar1C ()
Ответ на: комментарий от anonymous

вброс хитер, но уныл

Да не вброс это, я просто не подумал.

И, действительно, Царь правильно сказал нехорошо путать память с регистрами ЦП.

Twissel ★★★★★ ()
Ответ на: комментарий от TrueTsar1C

Нужно доработать (но там по сути — написать заново) sub filter модуль для nginx так, чтобы новая версия умела заменять сразу несколько шаблонов за один проход. С деградацией по скорости в зависимости от числа шаблонов примерно как у Ахо-Корасик или лучше.

i-rinat ★★★★★ ()
Ответ на: комментарий от Twissel

Ну да, пока не перемешаем сами кубики, а не куски по четыре кубика, беды-печали нам не видать :-)

Её никогда не видать.

Вот ты берёшь 4кубика - это твой новый кубик, который теряет свои границы и расширяется до 4-х. Если ты будешь от него брать части - всё будет тоже самое.

А вот порядок байт - это не порядок байт, а интерпритация начала этого кубика твоим процессором. Т.е. с какой стороны у него первый байт, а с какой 2-й.

Это влияет только на то, когда ты манипулируешь с регистром - т.е. битопы, и самое основное - это формат чисел.

Если ты сделаешь int i = 0xaabbccdd; char * ip = &i; *ip = это будет всегда первый, т.е. младший по адресам байт. Т.е. один и тот же везде.

А вот значение разное и уже что там будет aa|dd или ещё что-то уже зависит какраз от того как как проецирует байты числа процессор на регистр. 0123 3210, либо ещё как - это уже порядок.

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

А представление байта везде одинаковое, а строка это байты, поэтому на строку повлиять никак нельзя.

TrueTsar1C ()
Ответ на: комментарий от TrueTsar1C

В общем и целом понял, спасибо.

Порядок байт это вопрос интерпретации этих байт на ЦП определенной архитектуры.

И к коду в топике он никаким боком относиться не может.

Twissel ★★★★★ ()
Ответ на: комментарий от i-rinat

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

Что значит заменять? Типа a->b, c->d, e->f или a,c,e->b?

С деградацией по скорости в зависимости от числа шаблонов примерно как у Ахо-Корасик или лучше.

И как это должно юзаться - приведи пример.

location / {
    sub_filter      </head>
        '</head><script language="javascript" src="$script"></script>';//как?
    sub_filter_once on;
}
TrueTsar1C ()
Ответ на: комментарий от TrueTsar1C

Что значит заменять? Типа a->b, c->d, e->f или a,c,e->b?

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

И как это должно юзаться - приведи пример.

Например, несколькими директивами sub_filter:

location / {
    sub_filter 'Lorem' 'ipsum';
    sub_filter 'dolor' 'sit';
    sub_filter 'amet' 'consectetur';
    sub_filter 'adipiscing' 'elit';
    sub_filter 'Duis' 'condimentum';
    sub_filter 'est' 'quis';
    sub_filter 'velit' 'tincidunt';
    sub_filter 'vehicula' 'Fusce';
    sub_filter 'velit' 'erat';
    sub_filter 'efficitur' 'a';
    sub_filter 'neque' 'at';
    sub_filter 'egestas' 'tempor';
    sub_filter 'odio' 'Duis';
    sub_filter 'facilisis' 'orci';
    sub_filter 'nec' 'fermentum';
    sub_filter 'sollicitudin' 'nibh';
    sub_filter 'neque' 'lobortis';
    sub_filter 'leo' 'ut';
    sub_filter 'gravida' 'quam';
    sub_filter 'risus' 'eget';

    sub_filter_once off;
}

Считай, что их там порядка трёх сотен, может тысяч.

i-rinat ★★★★★ ()
Ответ на: комментарий от i-rinat

Хорошо.

Считай, что их там порядка трёх сотен, может тысяч.

А выкати это куда-то и примеры того, в чем это ищется для бенчмарков.

TrueTsar1C ()

Да.

Что-то меня сегодня накрыло, странно.

Twissel ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.