Сейчас кое кто за мат в бан полетит. Да, для профилактики. На пару дней. Rel А вам предупреждение. Ведите себя прилично
Rel #define HASH_SOLT 123 #define HASH_BASE 321 #define HASH(name, name_len) name_len > sizeof(long long) ? \ (*(long long*)name + *(long long*)(name + name_len - sizeof(long long)) + HASH_SOLT) % HASH_BASE : \ (*(long*)name + *(long*)(name + name_len - sizeof(long)) + HASH_SOLT) % HASH_BASE меняете хэш_соль и хэш_базу каждый раз при перекомпиляции (можно задавать через ключи компилятора, а можно точно также автоматически генерировать из даты и времени компиляции) и имеете разные хэши. все просто я уже говорил - назойливость и навязчивость миссионеров от них. которые, к томуже, понимают в чем говорят как морж в древнекитайской грамоте. решетка + нет - и язык и виртуалка средние по качеству. собрание недостатков как компилируемых, так и интерпретируемых подходов. возвращение закрытой по суду в конце 90х мс-жабы, но под другим именем. уже есть гораздо лучше. чего лезьть во все темы с этой решеткой, да еще и не умея аргументировать повторяемые за кемто мифы о ее преимуществах? какие? и какие из них нельзя реализовать существующими средствами без всех этих криков и стандартов? просто спрашиваю. интересно.
ну это далеко не хеш-цункция... тем более "хешируется" ограниченная часть строки, и тем более видимо в таком случае строка попадет в открытом виде в секцию данных и весь смысл ее хеширования пропадает... шаблоны с переменным числом параметров - очень удобны... как например без них невозможна адекватная реализация того кода, что я преводил раньше... точнее тот код выливается никому не нужным копипастом... constexpr - без него не получается сделать нормальную обработку строк во времени компиляции (во времени компиляции - ключевое слово)... да фактически весь механизм алгоритмов времени компиляции, что я использую построен на этих двух фичах нового стандарта... ну и по мелочам... лямбда выражения на практике мне очень понравились... еще бывает использую типизированные и классифицированные enum'ы... авто-типизированные переменные удобны, UTF-8, UTF-16, UTF-32 и raw строки... да много чего...
Rel для того чтобы судить о "хэш функциях" неплохо бы знать что такое "хэш", для чего он и откуда они взялись. это неплохо описано у кнута, втором томе "сортировка и поиск". сперва читаете, потом разговор о "далеко не" или "совсем да" продолжим. учитывается до 16 символов по 8 от начала и от конца строки. если вам мало, то добавьте по тому принципу еще и выборок от середины при достаточной длине. вы тот иф можете наращивать сколько хотите. даже до 1234567890 учитываемых символов (правда иф длинный будет) о включении строки: оптимизатор мсвс в состоянии посчитать это константное выражение во время компиляции. и со включенной оптимизацией дает просто число. ваш компилятор на такое не способен? этого всего я не знаю зачем. в принципе, не чувствую нехватки. возможно, в типизируемых енумах может быть смысл. лямбда и автотипизированные переменные могут создать сложности при отладке и переделывании кода. особенно в специфике С++. про строки вообще ничего не понял. короткие примеры приведите. как оно так, и как бы оно решалось без так
Я правильно понял - что перебираеться таблица экспорта, пока не будет совпадения по хешу от имени функции?
хорошо, давайте рассмотрим вопрос с другой стороны... какая, вы считаете, наиболее качественная виртуальная машина? и в чем ее существенные преимущества над виртуальной машиной от майкрософт? над виртуальной машиной Mono? над виртуальной машиной DotGNU? или может, вы считаете, что формат байт-кода MSIL и его оупенсорсных наследников чем то уступает какому-нить другому формату байт-кода? или может компиляторы в IL плохи в студии или в Mono или в DotGNU? или может JIT-компиляция в этих проектах уступает вашей любимой виртуальной машине? мне хотелось бы узнать побольше конкретики))) ну или киньте ссылку на статью/книгу, где обсуждается преимущества вашей любимой виртуальной машины над семейством дотнет машин... не, я не об этом... это - не хеш-функция, это - быдло-код на коленке))) тем более, как вы видете аналогичную функцию времени выполнения (взять хеш для того, чтобы просто взять хеш - бессмысленно)? вы попробуйте взять любую простую хеш-функцию от строки, например: и попробуйте реализовать ее с помощью препроцессора или шаблонов (без использования C++0x)... я почти уверен, что у вас не получится, тк до C++0x не было средств для нормальной обработки строк во времени компиляции... я же могу записать эту функцию с помощью рекурсивного constexpr и "константифицировать" значение с помощью шаблона... это копипаст, то есть то, от чего я всегда хотел уйти до появления C++0x... тем более говорить, что длина входного параметра ограничена N-символами - это и есть быдлокод))) в случае с вычислениями с помощью constexpr и рекурсивных шаблонов при превышения лимита рекурсии будет выдано сообщение об ошибке компилятора, в этом случае программист может решить увеличивать ли ему предел рекурсии или менять входной параметр... в вашем же случае будет просто баг, при котором хеш-значение времени компиляции никак не хочет совпадать со значением вычисленным во времени выполнения... я вообще говоря не хочу полагаться на оптимизатор... тут возможны варианты, например порог вложенности до которого оптимизатор будет раскрывать выражение... я кстати помню тут тема была про то, что какой-то компилятор зависал на определенном коде времени компиляции... или падал вообще, не помню уже... автотипизированные переменные я использую в тех случаях, например когда надо записать длинный тип итератора какого-нить шаблонного контейнера... вообще блин, это все долго писать... я предлагаю вам посмотреть стандарт, хотя бы по той ссылке, что я дал выше (поддержка gcc 4.6.1), там напротив каждой фичи есть ссылка на спецификацию, в которой как раз написано "как оно так, и как бы оно решалось без так"... да, вы правильно поняли... qqwe, вот кстати хотел вас спросить, раз уж вы такой сторонник старых стандартов... есть ли возможность с помощью макросов решить одну задачу, решения которой мне будет нехватать до выхода gcc 4.7.0))) я хотел бы иметь возможность записать вот такую штуку: Код (Text): // например char Str[] = { STRTOCOMMA("String") }; // или например SomeThing<STRTOCOMMA("String")> something; при этом макрос STRTOCOMMA разбивает строку на послудовательность ее символов через запятую... буду вам очень благодарен, если предложете решение... можно даже с "копипастом")))
ну вот же пример Код (Text): typedef mpl::string<'hell','o wo','rld'> hello; typedef mpl::push_back<hello, mpl::char_<'!'> >::type hello2; BOOST_ASSERT(0 == std::strcmp(mpl::c_str<hello2>::value, "hello world!")); а решение исходной задачи вероятнее всего вам не требуется
я смотрю, вы владеете телепатией и видиньем будущего))) к сожалению, мне требуется то о чем, я написал, а никак не mpl-строки...
сейчас я осуществляю шифрование строк во времени компиляции с помощью структуры с constexpr конструктором, в принципе все нормально, но он генерирует много лишнего кода такого вида: Код (Text): mov [ebp + <смещение_шфир_символа>], <значение_шифр_символа> // так для каждого символа в строке это не очень красиво... я хотел бы, что зашифрованная строка попадала в секцию данных, так же, как происходит с незашифрованной строкой... это можно сделать с помощью шаблона структуры со статическим полем массива шифр-символов))) но строки сами по себе никак не константифицируются, то есть их нельзя передать, как параметр шаблона, и из constexpr, где строка используется как входной параметр, нельзя использовать отдельные ее символы в качестве параметров шаблона... таким образом решить эту задачу (без user defined literals, которые должны появиться в gcc 4.7.0) можно только с помощью записи строки в виде последовательности символов в параметрах шаблона с переменным числом параметров, шифрующего ее в компайл-тайме... но это крайне неудобно для длинных строк, поэтому пытаюсь найти какой-нить вариант преобразования строки к виду последовательности символов через запятую на препроцессоре...
так какая мне разница? я и так и так должен разбивать строку на отдельные символы или на 32-битные инты (по 4 символа)...
Напиши конкретно, что ты хочешь. Ты хочешь в компайл тайме иметь последовательность типов, хранящих строку побуквенно? Это есть. Что дальше ты собираешься с ними делать?
Rel для какой цели, для каких применений? что именно для вас является преимуществами (переносимость, скорость и прожорливость, я так понял, для вас не аргументы) хм. вы поставили сложный для ответа вопрос. сложный для ответа вам. .нет использует стеково-словарную "школьную" виртуалку. как и жаба и еще ряд известных интерпретаторов. она самая простая в написании. но и одна из самых прожорливых и тормозных. дальнейшее объяснение в эту сторону не знаю как проводить, тк там будут часто встречаться те же хэши и код на С в котрых вы, имхо, ближе к чтению луркморя (тоже надо. оболтусы охотнее читать-печатать учатся). это решение поставленной задачи. причем, простое, допускающее автоматическую генерацию несовпадающих хэшей при каждой перекомпиляции, создающее прогнозируемый код, не переусложняющее задачу, не требующее повышения класса инструмента, не требующее использования специнструментов из экспериментальной ветки, компилируемое большинством компиляторов, что дает возможность использовать наилучший. впрочем, вы не практик, потому для вас эти соображения пустой звук. в целом и общем, оптимизатор нормально оптимизирующих компиляторов (мсвс, ов. интел не пробовал), любое константное выражение будет стараться рассчитать еще на этапе компиляции. если, конечно, вы не внесете в него переменной части. это нормально и для этого совсем не надо вводить доп команды. попробуйте отвлечься от своих стандартов и попробовать другие компилеры. иногда качество выходного кода существеннее каких то там стандартов. а свободное владение даже 1м инструментом предпочтительнее минутных мод на навороты. и все хватает. например, как преимущество смайлика выводилось наличие в нем гц, но вы уже можете использовать гц. причем, в любом С или С++ проекте начиная с анси. а как скомпилированную либу - со всем что умеет использовать С-либы. зачем тогода эта суета со стандартами? очередная молодежная революция за "более крутые чем раньше" слова? задачи не понял. если разговор о разбиении по символу, то почему бы не char Str[] = "String"; если чтоб строка получилась с запятыми, то запишите просто char Str[] = "S,t,r,i,n,g,"; в чем проблема? вобщем, не понял чего вы хотите, кроме как поспорить ни о чем. кстати, если вам требуются действительно сложные препроцессорные операции, то почему бы вам не воспользоваться внешним интерпретатором как все делают? наверно, любой современный скриптоланг даст 100 баллов вперед всем новым стандартам бедного С++ на 10 лет вперед.
вот пример... простейшее шифрование "однобайтным ксором": Код (Text): // шифрующий шаблон template <char... Ch> struct EncryptString { static const char Value[sizeof...(Ch)]; }; template <char... Ch> const char EncryptString<Ch...>::Value[sizeof...(Ch)] = { (Ch ^ 0x55)... }; // дешифрование и вывод const char* Value = EncryptString<'T', 'e', 's', 't', '!'>::Value; for(uint32_t t = 0; t < 5; t++) { printf("%c", Value[t] ^ 0x55); } printf("\n"); благодаря таким манипуляциям строка "Test!" появится в секции данны в "зашифрованном" виде... я хотел бы вместо: 'T', 'e', 's', 't', '!' писать "Test!"... теперь... что тут может быть непонятного?))) и на кой мне сдались эти mpl строки?))) цель - исполнение байт-кода на десктопной машине во всех своих эпостасиях (от приложений командной строки до 3д-движков, от научных проектов до программ для домохозяек)... какая по вашему мнению наилучшая виртуальная машина? да, но с другой стороны стековая виртуальная машина особо то и не мешает ни дотнет, ни джава проектам... вы считаете, что виртуальная машина должна быть регистровой? или использовать стек и набор регистров? опять же повторюсь... это решение на коленке... то, которое подходит для одной определенной задачи... я предпочитаю делать код с минимумом надуманных ограничений и с максимумом возможностей его повторного использования... но я же не практик... мне не понять... ну вот с этим нельзя не согласиться... однако в моем случае, это уже видимо спортивный интерес))) в том, чтобы решить все задачи одним инструментом...
Вот код, который криптует строку в compile time Код (Text): #include "stdafx.h" #include <stdio.h> #include <boost/mpl/string.hpp> #include <boost/mpl/char.hpp> #include <boost/mpl/transform.hpp> #include <boost/mpl/placeholders.hpp> #include <iostream> typedef boost::mpl::string<'Test'> src_string; template <typename TChar> struct encrypt { BOOST_STATIC_CONSTANT(char, eChar = typename TChar::value ^ 0x55); typedef boost::mpl::char_<eChar> type; }; typedef boost::mpl::transform< src_string, encrypt<boost::mpl::_1> >::type dst_string; typedef boost::mpl::transform< dst_string, encrypt<boost::mpl::_1> >::type dst_dst_string; int _tmain(int argc, _TCHAR* argv[]) { std::cout << boost::mpl::c_str<src_string>::value << std::endl; std::cout << boost::mpl::c_str<dst_string>::value << std::endl; std::cout << boost::mpl::c_str<dst_dst_string>::value << std::endl; return 0; }
я решительно не понимаю, что ты сказал. если ты имел ввиду, что тебе всё равно требуется разбивать строку на отдельные символы, то это не так. ты вводишь строку одним куском. ты получаешь криптованную строку одним куском. 'Test' -> 'shit' -> 'Test'. если ты хочешь иметь где-то 'T', 'e', 's', 't' явно написанным, то я НЕ понимаю, на хуя это надо