Комментарии 39
А по поводу «страшилок» как нельзя лучше подходит старая фраза «В уставе караульной службы каждая строчка написана кровью военнослужащих, которые пытались делать по своему»
часто имеют размер больше 8 байт.
Вывод: 16
Размер указателя на метод больше 8 байт.
Прежде чем что-то утверждать стоит указать для какой архитектуры компилируется пример, 32 и 64 бит.
У меня нет технической возможности проверить что происходит в компиляторах Microsoft, поэтому не особо про них рассказал. Однако протестировав онлайн компиляторы, я заметил что MSVC умеет анализировать структуру классов и удалять поле значения корректирования, если оно не требуется.
Нет, MSVC поступает иначе. Я прошу прощения за самоцитирование, но я делал доклад, где было упомянуто сравнение в том числе генерации кода указателя на метод: www.youtube.com/watch?v=Ak0u8PX5tRU (примерно с 15 минут)
(про вышеупомянутые ARM и AVR там тоже есть).
Или смотреть ассемблер — это не предположение (или не под капотом?), а простой примерчик — это предположение о том что под капотом?
Я точно делаю что-то не то?
Может быть устаревшая, но всё равно полезно Указатели на функции-члены и реализация самых быстрых делегатов на С++. Отдельный раздел, дополняющий эту статью на Хабре: "Реализация указателей на функции-члены".
Только если вам очень повезет, и указатель на функцию-член действительно будет размером sizeof(void*)
.
Основные случаи когда это может быть не так — особенности реализации компилятора, множественное наследование, указатель на виртуальную функцию, отладочная информация.
Адрес чего? Выше вы привели код, из которого можно понять, что там происходит получение значения машинного адреса указателя на указатель на функцию-член класса.
В таком случае указатель на указатель будет действительно sizeof(void*)
, но это уже следующий уровень косвенности.
Ну и си сам по себе хорошо с памятью все достает и кладет. Можно при желании неявно вызвать тот же memcpy без его прямого вызова
github.com/wasiher/member_pointers_linux/blob/master/member_pointers_linux.cpp#L11
Сколько знаю, компилятору может быть болезненно работать с ассемблером.
Самое безопасное, наверное, именно чтоб кастами разными приводить.
Теперь каждый раз когда что-то делаю в С++, узнаю что есть еще УБ где-то почему-то.
УБ похожи на покемонов.
Доказательств привести не могу, но теоретически оптимизатор может знать реальный адрес функции после девиртуализации какого-то экземпляра класса или link-time optimization.
Если сможешь что-то нашаманить и скинуть, то буду рад.
Если брать указатель на неизвестную структуру, то в gcc и clang будет 16.
gcc: rextester.com/CUCL60020
clang: rextester.com/ZCB93726
Если брать msvc, мало понимаю что там и почему происходит. Там размер 24, и что-то может и есть.
msvc: rextester.com/SNU4983
Может, если будет не лень, могу попробовать разобраться что происходит в MSVC, если кому надо…
Вот тут я нашёл кусок статьи, которая рассматривает вопрос подробнее, чем твоя stackoverflow.com/a/13875868/8452129
Насколько я понимаю, gcc и clang всегда используют минимум 2 слова, msvc пытается варьировать 1-3 слова, в зависимости от класса. Реймонд Чен писало про это: Pointers to member functions are very strange animals
Указатели на методы классов в C++