Нет. Не соглашусь, досрочный выход бывает полезен, например функция для проверки правильности многих параметров. Code (Text): result:=false; if NOT <проверка параметра 1> then Exit; if NOT <проверка параметра 2> then Exit; ... result:=<проверка последнего параметра> А насчет Break в case +1, всегда удивлялся кому это нужно, чтобы кейс не брейкался.
CyberManiac Почему ж, существуют, и не так уж и мало. Нужна приличная базовая подготовка. Ну а Фортран или Си++ -- не такая уж большая разница, если голова на плечах есть, и она не пуста Согласен. Однако применительно к оператору выхода из функции с возвратом значения и исключения как такового не потребуется: он должен быть способен возвращать в том числе и динмассивы. Естественно, ему такой массив должен быть задан в виде переменной (ну или функции, результатом которой будет динмассив). Не такой уж и редкий. Во всяком случае, мне не нравится нагромождение условных операторов, и отбивание их пробелами тут роли не играет (отбиваю я пробелы, отбиваю). И я предпочитаю использовать Exit, если работа функции реально закончилась. Кстати, ИМХО, это повышает читабельность, а отнюдь не снижает: видишь Exit -- и сразу понимаешь, что процедура всё, закончила работу, и нет нужды пытаться вникнуть, а не продолжается ли её выполнение где-то дальше. Ursus На чём написано ядро Линуха? На чём написан, кажется, ГНОМ (или КДЕ?)? Так что действительно погорячились
А я неоднократно сталкивался с обратным эффектом, и в Паскале (ох и давно это было) и в С++ и конечно в моём любимом асме периодически бывает что компилятор начинает заявлять о несуществующей синтаксической ошибке, начинаешь разбираться внимательнее - обнаруживаешь там ошибку в логике кода, исправляешь и мистическая синтаксическая ошибка бесследно исчезает ) причём искуственно воспроизвести ситуацию чтобы она опять возникла в правильном коде и позволила обвинить компилятор в ложных ошибках не удаётся ) потому как он прав )
Ursus, GoldFinch признаюсь, есть ошибки в коде вот исправленный код, позволяющий осуществить приведение указателя метода класса к char* и осуществляющий сплайсинг. Code (Text): class AAA { public: int x; AAA(int i); ~AAA(); int get(void); }; AAA::AAA(int i) {x=i;}; AAA::~AAA() {}; int AAA::get(void) {return x;}; int myFunc(void) { return 5; }; { //в функции мейн такой код: AAA obj(1); // создаем объект и полю x присваиваем 1 int y = obj.get(); // возращает 1, так как обычный вызов метода класса. char *s = new char[5]; char buff[1024]; wsprintf(buff, "%p", &AAA::get); // получаем адрес переходника DWORD addr = strtol(buff, NULL, 16); // в хекс-виде s = (char*)addr; // вот собственно само приведение типа указателя к char* DWORD addrFunc = (DWORD)myFunc; DWORD oldFlags; VirtualProtect((LPVOID)s, 5, PAGE_EXECUTE_READWRITE, &oldFlags); // даем добро на перезапись в сегменте кода s[1] = 0x4A + 0x19; // ну тут надо смещение высчитывать самому, у всех будет разное y = obj.get(); // снова вызываем метод класса, но в результате будет 5 :) чудеса да и только :) // единственное что нужно учесть, что перед вызовом метода класса в стек кладется указатель на обьект. // и в релизной компиляции могут быть так же другие смещения. } вот она гибкость языка. с помощью функций и приведения типов сделал простейший сплайсинг
Флуд развели. Ну скажите что можно сделать на С# чего нельзя сделать в Делфи и встроенного в него асма? Для меня Делфи понятен и я сомневаюсь что число программистов, которым не хватает возможностей любого высокоуровневого языка превышает 5% от их общего кол-ва. А разговоры о меньшем кол-ве строк или места при ресурсах современных компов - бессмыслица, если только вы не занимаетесь написанием вирусов
Ну как тебе сказать... Твой код делает (ну, или, по крайней мере, ты рассчитываешь на то, что он это делает) абсолютно то же самое, что строка Code (Text): char *s = (char*)&AAA::get; но делает это через ж%у, уж извини за выражение Но проблема даже не в этом. Проблема в том, что именно в том случае, о котором говорит GoldFinch, этот код (и твой, и тот, что я привел) работает не так, как требуется (там случай с множественным виртуальным наследованием, если мне не изменяет склероз). Вотъ...
Ursus строка char *s = (char*)&AAA::get; не работает, так же как и DWORD dw = (DWORD)AAA::get; GoldFinch знал об этом, когда просил написать код. Иначе бы он не просил бы Замена одной строчки кода тремя - ну не знаю, трудно назвать это решение через одно место. Там где цикл for с непростыми параметрами заменили на цикл while в паскале - я тоже могу назвать решением через одно место. Про множественное виртуальное наследование не было речи в посте №250 http://wasm.ru/forum/viewtopic.php?pid=279453#p279453 Не хотите ли привести пример решения данной задачи на паскале?
Хорошо, давай разбираться. Что, по-твоему, происходит в этом куске Code (Text): wsprintf(buff, "%p", &AAA::get); // получаем адрес переходника и чем это отличается от Code (Text): char *s = (char*)&AAA::get; А "через ж%у" - это получение строкового представления адреса только для того, чтобы в тут же восстановить числовое значение из этой строки посредством strtol()
Не хочу. Паскаль для таких вещей не предназначен. Ограничения синтаксиса тут выросли отнюдь не на пустом месте.
Ursus при char *s = (char*)&AAA::get; студия выдает ошибку: "Error 1 error C2440: 'type cast' : cannot convert from 'int (__thiscall AAA::* )(void)' to 'char *' f:\work\wasm_ntp_\wasm_ntp_\bred.cpp 43 wasm_ntp_" Я так понял, это связано с тем, что функция является членом класса, потому как обычные функции работают на ура. немножко покурил статью: http://www.developing.ru/com/compilation_theory.html и поработав с отладчиком, выяснил, все таки адрес метода получить возможно. Ведь обычный метод класса - это обычная функция по определенному адресу, а значит получить ее адрес вполне возможно. Вот решил обойти это ограничение. Там дальше в статье обсуждают уже таблицу виртуальных функций, тока мне это уже было не интересно. // ушел спать, завтра посвободе выйду.
Хорошо, я тоже туплю Изменяем пример Code (Text): char *s = (char*)(void*)&AAA::get; Теперь компилируется? (если нет - на этот раз полезу уже сам пробовать Но ответь на главный вопрос: Что происходит в строке Code (Text): wsprintf(buff, "%p", &AAA::get);
Ладно, я таки полез в стандарт Не работает, потому как не должно. Работает вот это, но это - грязный хак Code (Text): union{ int (__thiscall AAA::*pp)(void); void* v; }e; e.pp = &AAA::get; char* p = (char*)e.v; но, повторюсь, синтаксические ограниченя языка не на пустом месте растут.
если указатель на метод 32разрядный, ничто не должно мне мешать привести его к любому другому 32разрядному указателю или 32разрядному числу вообще %)
reinterpret_cast ? понятно, что в случае необходимости каста к войду он уже не поможет, как выше грамотно заметил Ursus. GoldFinch вы много таких языков знаете, которые позволяют это?