GCC: в каком смысле внутренняя видимость "довольно бесполезна в реальном использовании"?
В настоящее время я разрабатываю библиотеку для QNX (x86) с использованием GCC, и я хочу сделать некоторые символы, которые используются исключительно в библиотеке и невидимы для других модулей, в частности для кода, который использует библиотеку.
Это уже работает, но, проводя исследование, как этого достичь, я нашел очень тревожный отрывок в документации GCC (см. http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Code-Gen-Options.html#Code-Gen-Options, объяснение флага - fvisibility):
Несмотря на номенклатуру, default всегда означает public; т. е. быть связанным с внешним общим объектом. охраняемый и внутренние довольно бесполезны в реальном использовании, так что единственный другой обычно используемый вариант скрыт. Значение по умолчанию if-fvisibility не является задано по умолчанию, то есть, сделать каждый символ открытым-это вызывает такое же поведение, как и в предыдущих версиях GCC.
Меня очень интересует, как видимость "внутренняя". довольно бесполезно в реальном использовании. Из того, что я понял из другого отрывка из документации GCC (http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Function-Attributes.html#Function-Attributes , объяснение атрибута видимости), видимость "внутренняя" еще сильнее (полезнее для меня), чем видимость "скрытая":
Внутренняя видимость похожа на скрытую видимость, но с дополнительными специфическая семантика процессора. Если иное не предусмотрено законом. псаби, GCC определяет внутреннюю видимость как означающую, что функция никогда не является звонили из другого модуля. Сравните это со скрытыми функциями, которые, хотя другие модули не могут ссылаться на них напрямую, они могут быть на него ссылаются косвенно через указатели функций. Указывая, что функция не может быть вызвана извне модуля, GCC может для экземпляр опускает загрузку регистра PIC, так как известно, что вызывающая функция загрузила правильное значение.
Может ли кто-нибудь объясните подробно?
2 ответа:
Если вы просто хотите скрыть свои внутренние символы, просто используйте
-fvisibility=hidden
. Он делает именно то, что вы хотите.Флаг
К сожалению, существует множество способов случайно открыть функцииinternal
идет гораздо дальше, чем флагhidden
. Это говорит компилятору, что совместимость ABI не важна, так как никто за пределами модуля никогда не будет использовать эту функцию. Если какому-то внешнему коду все же удастся вызвать эту функцию, она, вероятно, выйдет из строя.internal
внешнему миру, включая функцию указатели и виртуальные методы C++. Например, многие библиотеки используют обратные вызовы для передачи сигналов о событиях. Если ваша программа использует одну из этих библиотек, вы никогда не должны использовать функциюinternal
в качестве обратного вызова. Если вы это сделаете, компилятор и компоновщик не заметят ничего плохого, и ваша программа будет иметь тонкие, трудно отлаживаемые ошибки сбоя.Даже если ваша программа не использует указатели функций сейчас, она может начать использовать их через много лет, когда все (включая вас) забудут об этом. ограничение. Жертвовать безопасностью ради крошечного повышения производительности обычно плохая идея, поэтому
internal
видимость не рекомендуется по умолчанию для всего проекта.Видимость
internal
полезнее, если у вас есть сильно используемый код, который вы пытаетесь оптимизировать. Вы можете отметить эти несколько конкретных функций с помощью__attribute__ ((visibility ("internal")))
, что говорит компилятору, что скорость важнее совместимости. Вы также должны оставить комментарий для себя, поэтому вы помните, что никогда не указывайте на них функции.