IPB

Добро пожаловать, гость ( Вход | Регистрация )

9 Страниц V « < 6 7 8 9 >  
Reply to this topicStart new topic
> Delphi, Asm, C, WinAPI, PHP, ..., FAQ
-=CHE@TER=-
Oct 27 2016, 15:59
Сообщение #141


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



Отличный пример наглядно иллюстрирующий почему если ты не чистишь память сразу после выделения (или не выделяешь с флагом автоматической очистки типа HEAP_ZERO_MEMORY / LMEM_ZEROINIT / GMEM_ZEROINIT и т.п.), то ты - баобаб.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Nov 23 2016, 15:03
Сообщение #142


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



QUOTE(-=CHE@TER=- @ Feb 13 2014, 14:49) *
Натолкнулся на то, что в нескольких играх используется LZSS, описанный в моём сообщении выше.
Но, есть одно отличие MS-LZSS (Microsoft LZSS) от классического LZSS (который, похоже, используется во многих играх), без которого на выходе получится не файл, а что попало.
Нашёл ещё одну вариацию - применялась в старых играх от Blizzard:
- Warcraft: Orcs and Humans
- Blackthorne
- Lost Vikings
В ближайшее время распаковщик на сайт добавлю (там нет имён и через флаги у размера / смещения файла определяется сжат он или нет). Кому интересно, описываю изменения в том алгоритме что я приводил ранее.

Вот эти строки:
CODE
FillChar(buff[0], $FFF + 1, 32);
I:=($FFF + 1) - 16;
...
J:=J + ((Len And $F0) ShL 4);
Len:=(Len And $0F) + 3;

Заменяются этими:
CODE
FillChar(buff[0], $FFF + 1, 0);
I:=0;
...
J:=J + ((Len And $0F) ShL 8);
Len:=((Len And $F0) ShR 4) + 3;

И всё.


Спасибо сказали:
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jan 29 2017, 19:55
Сообщение #143


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



AsmBB
Форум написанный на FASM. Нет, вы не ослышались. Да, это Assembler.
Дизайн дикий, функционал скромный, но идея интересная - наверняка потом в какой-нибудь KolibriOS интегрируют. (*улыбается*)
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Siberian GRemlin
Feb 27 2017, 09:33
Сообщение #144


Advanced Member
***

Группа: CTPAX-X
Сообщений: 537
Регистрация: 4-February 08
Пользователь №: 2
Спасибо сказали: 221 раз(а)



Установил игру на 64-разрядную систему. Программа устанавливается через 32-разрядную InstallShield 11.0, но каким-то образом пишет данные в область реестра доступную только 64-разрядным приложениям. Например, создаёт ветку, которая в 64-разрядном редакторе реестра доступна, а в 32-разрядном отсутствует.
CODE
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-21-3391727471-1739702130-609907194-1000\Components\66EEC61806F24F94D949A665B121C141


Таким образом, я из своего 32-разрядного приложения не могу получить путь к установленной игре, так как это единственное место в системе, где он указывается. Игра, кстати, 2006 года и 32-разрядная.

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

Добавлено.
Нашёл кривое решение через экспорт ветки в файл, который нужно затем читать.
CODE
REG.EXE export HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-21-3391727471-1739702130-609907194-1000\Components\66EEC61806F24F94D949A665B121C141 test.reg


Добавлено позже.
Похоже, из 32-разрядного приложения вызывается только 32-разрядная версия REG.EXE со всеми вытекающими. Идиотство.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Feb 28 2017, 08:16
Сообщение #145


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



Переместил твоё сообщение в более подходящую тему.
Как я понял, тебе поможет KEY_WOW64_64KEY при вызове RegOpenKeyEx().
Обрати внимание, что эта штука не будет работать под Windows 2000.
Ещё снизу см. Note - есть другой способ без флагов, но "it's stable but it should be considered an implementation detail subject to change".
Такие дела.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jul 2 2017, 14:16
Сообщение #146


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



Может кому пригодится: libunpak.zip (~16 Kb)
Библиотека для Delphi 7, где я собрал бинарники для последних:
- puff() из zlib (распаковывает deflate)
- blast() из zlib (распаковывает PKWARE)
Теперь это библиотека, с небольшой обёрткой, которая позволяет работать обоим алгоритмам с памятью, а не жёстким диском. Плюс к blast() добавил интерфейс, так что он теперь тоже может возвращать необходимый размер буфера для распаковки. Давно хотел такую штуку для Delphi, без всяких зависимостей от "msvcrt.dll" и прочего мусора.
Также в архиве программа-пример и два файла "deflate.dat" и "pkware.dat" на которых можно потренироваться.
Через дефайны: NO_DEFLATE или NO_PKWARE можно убрать ненужные алгоритмы, для уменьшения размера.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Dec 11 2017, 12:54
Сообщение #147


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



Прошло 10 лет с момента. Посмотрел я снова Lazarus, последнюю версию - 1.8.0 (5-го декабря, кстати, вышла). Для теста взял один не очень большой и сложный проект на Delphi 7. Сконвертировался он нормально, но поглядев как работает я всё равно продолжаю офигевать от этого ужаса:
- .EXE файлы по прежнему толстые: проект в Delphi 7 был 500 Кб, здесь - 2 Мб, и это с включённой в опциях проекта оптимизацией по размеру и отключённой отладочной информацией (без них будут десятки мегабайт);
- не смотря на то что проект сконвертировался без проблем, в FPC / Lazarus у TJPEGImage нет метода DIBNeeded, на что мне сразу вышибло ошибку - прозреваю, что это не единственная несовместимость;
- контрол TImage так за 10 лет и не починили (долбанный стыд!) - достаточно провести по нему мышкой, чтобы он начал ужасно, чудовищно и вырвиглазно моргать и перерисовываться (хотя в изображение никаких изменений не вносилось);
- все строки в UTF-8 (почему-то ключ в настройках проекта об использовании ANSIString игнорируется), поэтому загружая файлы с русскими строчками в 1251 вы будете видеть "????" вместо них;
- если у вас на компьютере стоял FPC старой версии, то сносите его перед установкой Lazarus, ибо эта скотина вместо установленного с ней 3.0.4, будет подтягивать старый, который уже стоит в системе, в результате вы ничего не сможете скомпилировать (половины юнитов не будет);
- установщик никакой - ставит всё, в том числе компоненты, которые вы никогда не использовали, не используете и использовать не будете, причём вместе с исходными кодами, так что готовьте гигабайт свободного места под всё это барахло (а ещё это всё будет долго устанавливаться), ибо выбрать только то что вам нужно во время установки вы не сможете.
Там ещё всякого по мелочи и хотя есть и положительные моменты, но, в целом, всё по прежнему очень грустно.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Dec 25 2017, 17:16
Сообщение #148


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



QUOTE(-=CHE@TER=- @ Feb 13 2014, 14:49) *
Натолкнулся на то, что в нескольких играх используется LZSS, описанный в моём сообщении выше.
Но, есть одно отличие MS-LZSS (Microsoft LZSS) от классического LZSS (который, похоже, используется во многих играх), без которого на выходе получится не файл, а что попало.
Не поверите - очень популярный алгоритм. Во многих играх используется.
Выложил сейчас на сайт распаковщик .GPF для Snake Battle / Змеиный бой (Gamos, 1992).

Вот эти строки:
CODE
I:=($FFF + 1) - 16;
...
J:=J + ((Len And $F0) ShL 4);
Len:=(Len And $0F) + 3;

Заменить такими:
CODE
I:=($FFF + 1) - 16 - 2;
...
J:=J + ((Len And $0F) ShL 8);
Len:=((Len And $F0) ShR 4) + 3;

И всё.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Feb 9 2018, 09:14
Сообщение #149


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



QUOTE(Siberian GRemlin @ Feb 8 2018, 10:27) *
Только одна проблема — не хочется тратить время на вникание в код, если ты его перепишешь на Си или на Паскале с помощью допотопных AssignFile и пр. Я года с 2004 использую потоки после того как увидел, как это делается в одном из исходников основателя extractor.ru
Чтобы не раздувать холивар постараюсь его сократить. У меня к тебе такие вопросы:
1) Обоснуй чем потоки лучше, скажем, CreateFile() + CreateFileMapping()? Ты точно также можешь весь файл в память засунуть и делать с ним что угодно.
2) В чем проблема заменить (автозаменой даже можно), скажем, "BlockRead(fl, buffer, size);" на "stream.Read(buffer, size);"?
А почему ООП вообще и потоки в частности это плохо я сейчас объяснять не буду, дабы не разводить холивар - там на отдельную большую статью хватит. Вот например - обрати внимание, ООП не последние люди критикуют, хотя некоторые, конечно, личности спорные.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Mar 4 2018, 16:12
Сообщение #150


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



Интересная статья: Calling C From ASM In X64. Тот случай, когда технологии уже дошли до того, что нельзя вот так просто взять и что-то вызвать из ассемблера, не огребя при этом кучу проблем в ответ. Оптимизация она такая, да.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Mar 29 2018, 12:36
Сообщение #151


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



Товарищи! Возник интересный вопрос по поводу ключей командной строки.
Смотрите, для ключа, как правило, используется какой-то символ-префикс:
-param
или вот так:
/param
Проблемы тут ровно две:
1) Если использовать '-', тогда встаёт проблема с именем файлы начинающегося с этого символа. Я писал в этой теме уже, что это можно решить коротким именем файла (dir /B /X *.*), но это сработает только в том случае, если файл имеет длинное имя.
2) Если использовать '/' и ты пишешь кроссплатформенную утилиту на сях, то этот символ является вполне себе разрешённым, ибо в иксах вместо '\' для разделения путей используется именно что '/' и путь '/usr/vasia/myfile' - это обычное дело.
А идея использовать запрещённые символы в имена файла в качестве префикса - никуда не годится.
Потому что в Windows они такие: \ / : * ? " < > |
\ и / - используются для указания путей ('/' в Windows fopen и прочие иксовые функции перед использованием разворачивают в '\');
: - используется для указания потока у файла в NTFS дисках (кстати говоря, ещё и не является запрещённым символам в имени файла в иксах);
* и ? - используются для задания маски у имени файлов, а * в иксах и того хуже - если globe не отключён, то вызов "tool *" приведёт к тому, что все файлы в текущем каталоге буду сконвертированнны в аргументы argv (аналог ParamStr в Delphi);
" - используется для экранирования параметров содержащих пробел или символ табуляции;
< и > используются для перенаправления ввода и вывода;
| - используется для конвеера.

Вариантов решения, как я понимаю, немного:
1) Если у программы один обязательный входной параметр имя файла, то жёстко делать его первым, а все остальные необязательные ключи 2, 3 и т.д. так что там можно и '-' использовать и совсем без префикса.
2) Использовать ужасное с двумя минусами '--param' как в некотрых иксовых утилитах.
3) Ещё один линуксовый подход - все параметры должны предворяться ключами, т.е. нельзя написать:
tool input.dat -deflate output.dat
а нужно обязательно писать громоздкое:
tool -input=input.dat -method=deflate -output=output.dat

У кого-нибудь ещё идеи и предложения есть? Может я что-то забыл?
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Grom PE
Mar 29 2018, 16:38
Сообщение #152


Advanced Member
***

Группа: CTPAX-X
Сообщений: 84
Регистрация: 7-February 08
Из: i@grompe.org.ru
Пользователь №: 3,120
Спасибо сказали: 95 раз(а)



Проблемы с файлами, начинающимися с "-" в винде как таковой нет, потому что маски файлов подставляются программой, а не исполняющей средой, и нет опасности, что при вызове команды "myprog *" встанет файл, превратившийся в ключ "уничтожить всё".

Лично я предпочитаю, чтоб ключи начинались с "-". Если очень надо файл "-something.txt", можно его указать программе как "?something.txt*. Проблема тут может быть в том, что в программах, обрабатывающих только один файл, авторы часто забывают сделать раскрытие масок.

А в линуксах для одиночного файла принято использовать stdin/stdout, что тоже обходит проблему с минусовым файлом.

(добавлено:)
А, можно же ещё относительно текущей директории указывать: ".\-something.txt"


Спасибо сказали:
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Mar 30 2018, 16:06
Сообщение #153


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



QUOTE(Grom PE @ Mar 29 2018, 16:38) *
Проблемы с файлами, начинающимися с "-" в винде как таковой нет, потому что маски файлов подставляются программой, а не исполняющей средой, и нет опасности, что при вызове команды "myprog *" встанет файл, превратившийся в ключ "уничтожить всё".
Я не помню писал тут уже или нет, опять искать лень, но если ты компилируешь в GCC и не добавил библиотеку CRT_noglob.o в команду сборки, то, например, для каталога C:\Test\ с такими файлами:
something.dat
myprog.exe
readme.txt
вызов программы: "myprog.exe *" автоматически вернёт тебе не
argc = 2
argv[0] = "C:\Test\myprog.exe"
argv[1] = "*"
а вот такую штуку вместо этого:
argc = 4
argv[0] = "C:\Test\myprog.exe"
argv[1] = "something.dat"
argv[2] = "myprog.exe"
argv[3] = "readme.txt"

QUOTE(Grom PE @ Mar 29 2018, 16:38) *
Лично я предпочитаю, чтоб ключи начинались с "-". Если очень надо файл "-something.txt", можно его указать программе как "?something.txt*. Проблема тут может быть в том, что в программах, обрабатывающих только один файл, авторы часто забывают сделать раскрытие масок.
Я не хочу делать обработку маски, потому что, во-первых, тупо лень, во-вторых, если это для какой-нибудь программы типа stuns, то там это бессмысленно, потому что у тебя каждый следующий файл будет затирать выходные файлы от предыдущего. Т.е. нужно будет страдать фигнёй в отдельные каталоги записывать (например образованные от имени входного файла), либо ещё что-то придумывать. Маска больше подходит к программам, где она действительно необходима - JPGStrip например.

QUOTE(Grom PE @ Mar 29 2018, 16:38) *
А в линуксах для одиночного файла принято использовать stdin/stdout, что тоже обходит проблему с минусовым файлом.
На обработку stdin/stdout надо отдельный код писать, в отличие от разворота "*", который принудительно отключать нужно.

QUOTE(Grom PE @ Mar 29 2018, 16:38) *
(добавлено:)
А, можно же ещё относительно текущей директории указывать: ".\-something.txt"
Вот же блин, а я тоже самое сделал, просто искать лень было своё прошлое сообщение, а оно оказалось последним на предыдущей странице. Почему я про длинное имя подумал, вместо этого сам не знаю (к тому же это и не работает - короткое имя тоже будет с "-" начинаться). За 1,5 года нахрен всё забыл. Но всё равно спасибо!
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Grom PE
Apr 4 2018, 14:00
Сообщение #154


Advanced Member
***

Группа: CTPAX-X
Сообщений: 84
Регистрация: 7-February 08
Из: i@grompe.org.ru
Пользователь №: 3,120
Спасибо сказали: 95 раз(а)



QUOTE(-=CHE@TER=- @ Mar 31 2018, 00:06) *
но если ты компилируешь в GCC и не добавил библиотеку CRT_noglob.o в команду сборки, то [...]
вызов программы: "myprog.exe *" автоматически вернёт тебе не argc = 2
Ну охренеть теперь, по умолчанию идти в чужой монастырь со своим уставом — это уж слишком. Впрочем, никогда не любил GCC.

QUOTE(-=CHE@TER=- @ Mar 31 2018, 00:06) *
Я не хочу делать обработку маски, потому что [...] у тебя каждый следующий файл будет затирать выходные файлы от предыдущего.
Поддержка маски ≠ поддержка нескольких входных файлов. Но если лень, то хозяин — барин.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Apr 6 2018, 11:34
Сообщение #155


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



QUOTE(Grom PE @ Apr 4 2018, 14:00) *
Ну охренеть теперь, по умолчанию идти в чужой монастырь со своим уставом — это уж слишком. Впрочем, никогда не любил GCC.
Ты чего такой злой? (*улыбается*) GCC - нативный компилятор для иксов. Я понимаю что, возможно, ты кроссплатформенностью не особо заморачиваешься, но мне в принципе было интересно обсудить возможное универсальное решение.

QUOTE(Grom PE @ Apr 4 2018, 14:00) *
Поддержка маски ≠ поддержка нескольких входных файлов. Но если лень, то хозяин — барин.
На мой взгляд поддержка нескольких входных файлов ещё более уродская, чем маска (особенно, если их много). И это всё равно не снимает вопроса о выходных файлах.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Grom PE
Apr 6 2018, 14:21
Сообщение #156


Advanced Member
***

Группа: CTPAX-X
Сообщений: 84
Регистрация: 7-February 08
Из: i@grompe.org.ru
Пользователь №: 3,120
Спасибо сказали: 95 раз(а)



QUOTE(-=CHE@TER=- @ Apr 6 2018, 19:34) *
Я понимаю что, возможно, ты кроссплатформенностью не особо заморачиваешься, но мне в принципе было интересно обсудить возможное универсальное решение.
Кроссплатформенность — это хорошо и правильно. Но в случае с GCC, как и с другими особенно юниксово-идеологическими вещами, под кроссплатформенностью почему-то понимается не подстроиться под новую исполняемую среду, а притащить пол-юникса за собой, частью чего вот такая внезапная подстановка "*" и является. И такой подход вызывает отвращение.


Спасибо сказали:
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jun 9 2018, 15:49
Сообщение #157


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



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

Суть:
1) Открываем файл на чтение-запись: fopen("filename.ext", "rb+")
2) Читаем что-то, меняем и тут же пишем назад:
fread(buf, sz, 1, fl); // прочитали
fseek(buf, -sz, SEEK_CUR); // вернулись назад
fwrite(buf, sz, 1, fl); // записали
3) Повторяем в цикле пару раз.
4) Получаем на выходе хрень вместо файла.

Чтобы это пофиксить, нужно либо:
а) В п.1 сразу после открытия файла делать setbuf(fl, NULL) чтоб отключить буферизацию.
б) Либо в п.2 после записи добавить, например:
fseek(fl, 0, SEEK_CUR); // сбрасываем внутренние флаги состояния

Потому что:
QUOTE
When the "r+", "w+", or "a+" access type is specified, both reading and writing are enabled (the file is said to be open for "update"). However, when you switch from reading to writing, the input operation must encounter an EOF marker. If there is no EOF, you must use an intervening call to a file positioning function. The file positioning functions are fsetpos, fseek, and rewind. When you switch from writing to reading, you must use an intervening call to either fflush or to a file positioning function.
(с) MSDN - fopen, _wfopen

В Borland Turbo C под DOS та же фигня, кстати. А я уже было думал, что баг в винде нашёл, но это, оказывается, дофига не интуитивные сишные функции. А что, в структуре FILE нельзя было поле предусмотреть для сохранения состояния последней операции и сбрасывать внутренние флаги, если операции различаются? Риторический вопрос.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Nov 27 2018, 12:28
Сообщение #158


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



Я тут просто охреневаю с происходящего. Короче, понадобилось мне скомпилять на сях одну либу, которая использовала функции из Windows DDK. Мой обычный способ для этого не канал, ибо ключ -ansi вызывал в одном из заголовочных файлов DDK кучу ошибок, так что я быстро накатал .BAT файл:
gcc -Wall -pedantic test.c
где упомянутые два ключа должны были спасти меня от всевозможных глупых ошибок, которые я мог в процессе написания сделать. Да?.. Хрен там! Как бы не так! Когда нашёл ошибку, то вытащил функцию в отдельный файл и скопилировал уже с ключами:
gcc -Wall -pedantic -ansi test.c
но предупреждение всё равно не появилось!
Скомпилировал тестовый файл обычным способом - и вот оно, пожалуйста.
Начал убирать ключи по одному, пока не выяснилось что минимальный набор ключей, для того чтобы предупреждение наконец-то появилось, должен быть таким:
gcc -Wall -Os test.c
Кто не знает или забыл:
-Wall - показывать предупреждение о любых некорректно написанных вещаях, даже самых незначительных
-pedantic - ваще-ваще показывать сообщения обо всём и придираться ко всему
-ansi - использовать стандарт C89 для компиляции (более жёсткий, чем остальные)
-Os - оптимизировать генерируемый код по размеру
Как оптимизация по размеру выкидывает предупреждение, которое должен был кидать компилятор?! Почему оно, вообще, там? Причём это предупреждение выводится на любом уровне оптимизации, кроме нулевого -O0 (без оптимизации). Заглядываем в документацию:
QUOTE
-O0
Reduce compilation time and make debugging produce the expected results. This is the default.
Понятно что по умолчанию и уменьшает время компиляции, но, блин, я же не хочу время компиляции уменьшить, я явно указал все ключи какие были, чтобы мне ошибки выводились! Я специально это указал - при чём тут оптимизация?
Можете со мной поспорить, но не инициализируемое значение возвращаемое из функции - это ошибка которую должен компилятор ловить, а не оптимизатор. И уж тем более эта ошибка обязана ловиться, если включены режимы -Wall или -pedantic - т.е. когда ты явно сказал, что тебе пофиг на скорость компиляции, ты хочешь чтобы проверялось всё.

Кому интересно, код тестовой программы с комментариями ниже.
CODE
/*

MinGW GCC 3.2

no warnings, no errors:
> gcc -Wall -ansi -pedantic test.c

only this one shows the warning:
> gcc -Wall -ansi -pedantic -Os test.c

> test.c: In function `func':
> test.c:15: warning: `b' might be used uninitialized in this function

*/

#include <stdio.h>
#include <time.h>

int func(int a) {
time_t b;
/*  b = 0;*/ /* accidentally forgotten line of code */
  if ((a >= 0) && (a <= 59)) {
    b = time(NULL);
  }
  return(b);
}

int main(void) {
  printf("%d", func(-1));
  return(0);
}
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jan 29 2020, 14:30
Сообщение #159


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



Кто знает, что будет выведено на экран в этих двух программах?

CODE
#include <stdio.h>
#include <string.h>

int main(void) {
char s[10];
int i;
  strcpy(s, "123456789");
  for (i = 0; i < strlen(s); i++) {
    printf("%c", s[i]);
    s[5] = 0;
  }
  return(0);
}

CODE
program test;
{$APPTYPE CONSOLE}
var
  s: string;
  i: integer;
begin
  s:='123456789';
  for i:=1 to Length(s) do
  begin
    Write(s[i]);
    SetLength(s, 5);
  end;
end.


Код можно переписать короче:
CODE
#include <stdio.h>

int main(void) {
int i, j;
  j = 9;
  for (i = 1; i <= j; i++) {
    printf("%c", '0' + i);
    j = 5;
  }
  return(j); /* do not optimize j = 5 */
}

CODE
program test;
{$APPTYPE CONSOLE}
var i, j: integer;
begin
  j:=9;
  for i:=1 to j do
  begin
    Write(Chr(Ord('0') + i));
    j:=5;
  end;
  Halt(j); (* remove warning about unused j:=5 *)
end.


Узнать ответ
В первом случае будет:
GCC: 12345
Delphi: 12345.789 (вместо точки там будет символ $00)
Во втором:
GCC: 12345
Delphi: 123456789
Потому что Си каждый раз вычисляет условие, а Delphi делает это только один раз в начале, поэтому любые изменения условия внутри цикла for не завершат его. Из чего следует, что если в сях условие выполнения не меняется в цикле, то нужно его посчитать заранее, чтобы оно не рассчитывалось на каждом шаге (лишние операции тормозят выполнение). По сути код прохода по строке:
for (i = 0; i < strlen(s); i++) ...
Не оптимальный, поэтому его и переделывают в такой:
for (i = 0; s[i]; i++) ...
Или такой, если порядковый номер символа не нужен:
for (d = s; *d; d++) ...
Или даже такой, если ни номер, ни сам указатель на начало не нужен:
for (; *s; s++) ...
Си достаточно гибкий язык по сравнению с Delphi, но и следить за подобными вещами там нужно внимательно.
Всё описанное выше, конечно же, справделиво только для циклов for, т.к. в while и repeat (Delphi) условие выполнение вычисляется всегда независимо от языка и компилятора.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jun 23 2020, 13:36
Сообщение #160


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



Пацаны! Глядите, чего я в одной книжке 1999 года по Pascal нашёл (в Delphi, во всяком случае 7-ом, тоже работает):
CODE
program test;
{$APPTYPE CONSOLE}
var s: string(.4.);
begin
  s:='TEST';
  s(.1.):='W';
  writeln(s);
  readln;
end.
Кто знает, что будет выведено без компиляции?
Ну и, собственно, подсказка:
(. = [
.) = ]
Я знал, что в Pascal / Delphi, есть два способа многострочных комментариев:
{ ... } - обычный
(* ... *) - дополнительный
Второй способ пригодится когда нужно закомментарить большой кусок кода, где уже есть обычный. Хотя, это можно было бы сделать и так:
{$IFDEF NEVER} ... {$ENDIF}
Но я не знаю с какой версии в Pascal появились директивы IFDEF и ENDIF, так что, возможно, на каком-то этапе это было оправдано, особенно с учётом того, что в Pascal изначально не было строчных комментариев // как в Delphi, поэтому закомментаривать куски кода с уже какими-то комментариями внутри было проблематично.
Но вот хоть ты тресни я никак не могу понять зачем мог понадобиться второй способ указания индекса у массивов.
Наверняка причины тоже какие-нибудь исторические, но чем они обоснованы были придумать не смог. Если кто знает - напишите, ибо я понятия не имею как этот способ указания индекса гуглить.
Предположу, что, возможно, в первых версиях языка или на старых клавиатурах не было квадратных скобок, а как-то отличать аргументы функций, типа work(1), от аргументов массива, типа list(.1.), надо было.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post

9 Страниц V « < 6 7 8 9 >
Reply to this topicStart new topic
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0 -

 



Упрощённая версия Сейчас: 14th November 2024 - 03:37