Как защищена статическая функция / переменная - PullRequest
1 голос
/ 08 июля 2010

Я хочу знать, как защищена статическая переменная или функция для использования только для файла, в котором она определена. Я знаю, что такие переменные и функции объявлены в разделе данных (точнее, в области кучи), но так ли это помечены именем файла? Предположим, я одурачил компилятор, назначив такую ​​статическую функцию (определенную в foo.c) глобальному указателю функции, и вызову этот указатель функции в каком-то другом файле (bar.c). Очевидно, мой код не выдаст никакого предупреждения при компиляции, но, между прочим, он дает ошибку сегментации. Очевидно, это ошибка защиты, но мне интересно знать, как это реализовано внутри системы.

Спасибо. MS

Ответы [ 4 ]

5 голосов
/ 08 июля 2010

Компоновщик заботится об ограничении области отображения имени функции в функцию.

Нет защиты статических функций, вызываемых указателем на функцию - это не редкость идиома. Например, рекомендуемый способ реализации методов GObject - предоставить указатель на статическую функцию (см. Раздел виртуальных открытых методов в этом GObject how-to )

3 голосов
/ 08 июля 2010

Он «защищен» просто потому, что его символ / местоположение не стало известным компоновщику.Таким образом, вы не можете написать код в другом модуле, который явно ссылается на статический объект по имени символа, потому что компоновщик не имеет такого символа.Защита во время выполнения отсутствует.

Если вы передадите адрес статическому объекту другому модулю во время выполнения, вы сможете получить к нему доступ через такой указатель.Это не «дурак компилятора» (или компоновщик на самом деле), такие действия могут быть полностью законными.

Тот факт, что вы получили ошибку сегмента, возможно, по совершенно другой причине (например, неверный указатель).Компилятор может выбрать встроенный код, и в этом случае указатель на него будет невозможен, но если вы явно берете адрес объекта, компилятор должен его создать, поэтому это маловероятно.

2 голосов
/ 08 июля 2010

Цель static - не «защитить» переменную / функцию, а защитить пространство имен и защитить остальную часть вашей программы от неправильного поведения в символах с конфликтующими именами. Это также позволяет значительно повысить оптимизацию, поскольку компилятор знает, что ему не нужно облегчать доступ к имени символа внешними модулями.

0 голосов
/ 08 июля 2010

у вас может возникнуть проблема, если foo.c и bar.c скомпилированы в разные динамически загружаемые библиотеки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...