В примере, где передаются данные из глухой ВМ в браузер на хосте: каким образом между отправителем и получателем согласовывается используемый банк памяти? Если нативному процессу внутри ВМ еще может быть реально получить карту трансляции виртуальных адресов (а также получить доступ к каким-то определенным страницам), то как это сделать со стороны JavaScript?
Не соглашусь. Допустим, есть несколько worker-тредов, которые в случайный момент обращаются к такому коду, и в нем в однократном блоке производится некая инициализация. Другое дело, что лично я не вижу смысла использовать для этого макросы, тем более когда есть стандартное средство.
В отличие от std::function здесь не используется динамическое выделение памяти. Вместо этого функторы хранятся как статические объекты, что, очевидно, имеет свои минусы, но лучше в плане производительности.
Думаю, действительно стоит.
Я подготовил универсальный (для всех трех компиляторов) пример, иллюстрирующий баг: pastebin.
Предлагаю вам добавить его в баг репорты.
Получаем обманным путем (с помощью примера с Extract из баг-репорта автора к gcc) указатель на "void()const".
Присваиваем данному указателю адрес non-member функции. (Причем, в clang нужен cast, в gcc — не нужен).
Вызываем функцию с помощью этого указателя.
В программе, скомпилированной clang просто произошел вызов функции, а вот с gcc интереснее: генерируется вообще некорректный код.
Если вызов был произведен через указатель на "void()const", то код вызова отсутствует совсем, если же const заменить на volatile или const volatile, то функция вызывается, но после программа падает (код вызывающей функции обрывается после вызова).
Кстати, в VC++ проверка, видимо, есть, но она не работает из-за другого бага: код автора компилируется только когда параметр функции, который должен стать указателем, является безымянным. Если же имя у парамтра есть, то мы всё же получаем желаемую ошибку:
error C2270: 'value': modifiers not allowed on nonmember functions
note: see reference to class template instantiation 'S<void (void) volatile>' being compiled
При этом, если проверку всё же обойти, то std::is_same для типов указателей на "void()const" и "void()volatile" возвращает false, но любое другое использование данных типов указывает на то, что компилятор их не различает.
В целом, действительно интересная статья, автору спасибо. Мне понравился итоговый способ, хотя, конечно, всем уже давно пора перейти на новый стандарт языка.
Допустим, если я допишу A=8 в ваш пример с ideone, то получаем ошибку компиляции:
prog.cpp: In static member function 'static std::string X::to_string(X::Y)':
prog.cpp:60:13: error: lvalue required as left operand of assignment
ENUM(Y,A=8,B,C)
^
Я подготовил универсальный (для всех трех компиляторов) пример, иллюстрирующий баг: pastebin.
Предлагаю вам добавить его в баг репорты.
В программе, скомпилированной clang просто произошел вызов функции, а вот с gcc интереснее: генерируется вообще некорректный код.
Если вызов был произведен через указатель на "void()const", то код вызова отсутствует совсем, если же const заменить на volatile или const volatile, то функция вызывается, но после программа падает (код вызывающей функции обрывается после вызова).
Кстати, в VC++ проверка, видимо, есть, но она не работает из-за другого бага: код автора компилируется только когда параметр функции, который должен стать указателем, является безымянным. Если же имя у парамтра есть, то мы всё же получаем желаемую ошибку:
При этом, если проверку всё же обойти, то std::is_same для типов указателей на "void()const" и "void()volatile" возвращает false, но любое другое использование данных типов указывает на то, что компилятор их не различает.
В целом, действительно интересная статья, автору спасибо. Мне понравился итоговый способ, хотя, конечно, всем уже давно пора перейти на новый стандарт языка.