Не можете инициализировать статическую структуру с помощью указателя на функцию из другого модуля перевода? - PullRequest
5 голосов
/ 09 августа 2011

В документации Python утверждается, что на некоторых платформах или компиляторах не работает следующее:

int foo(int);  // Defined in another translation unit.
struct X { int (*fptr)(int); } x = {&foo};

В частности, документы Python говорят:

Мы хотели бы просто назначить это в слот tp_new, но мы не можем, для ради переносимости, на некоторых платформах или компиляторах мы не можем статически инициализировать элемент структуры с функцией, определенной в другом C модуль, поэтому вместо этого мы назначим слот tp_new в модуле Функция инициализации непосредственно перед вызовом PyType_Ready (). - http://docs.python.org/extending/newtypes.html

Вышеупомянутый стандарт C89 и / или C99? Какие компиляторы конкретно не могут справиться с вышесказанным?

Ответы [ 3 ]

3 голосов
/ 09 августа 2011

Такого рода инициализация разрешена как минимум с C90.

Из C90 6.5.7 «Инициализация»

Все выражения в инициализаторе для объекта со статической продолжительностью хранения или в списке инициализатора для объекта, который имеет агрегат или объединениеТип должен быть константными выражениями.

И 6.4 «Выражения констант»:

Константой адреса является указатель на lvalue, обозначающий объект статической длительности хранения, илиобозначение функции;он должен быть создан явно с использованием унарного оператора & ...

Но, безусловно, возможно, что некоторые реализации могут иметь проблемы с конструкцией - я думаю, что это не будет так для современных реализаций.

2 голосов
/ 09 августа 2011

Согласно пункту 9 n.670 пункта 6.6 адрес функции является адресной константой , в соответствии с 6.7.9, это означает, что он может использоваться для инициализации глобальных переменных. Я почти уверен, что это также верно C89.

Однако

На нормальных платформах значение указателя функции (или любого другого указателя, кроме NULL) известно только во время выполнения. Это означает, что инициализация вашей структуры не может иметь место до времени выполнения. Это не всегда относится к исполняемым файлам, но почти всегда применяется к общим объектам, таким как расширения Python. Я рекомендую прочитать эссе Ульриха Дреппера на эту тему ( ссылка ).

Я не знаю, на каких платформах это сломано, но если разработчики Python упоминают об этом, это почти наверняка, потому что одна из них укушена этим. Если вам действительно любопытно, попробуйте взглянуть на старое расширение Python и посмотреть, есть ли соответствующее сообщение в журналах фиксации.

Редактировать: Похоже, что большинство модулей Python просто делают обычные вещи и статически инициализируют структуры типов, например, static type obj = { function_ptr ... };. Например, посмотрите на модуль mmap, который загружается динамически.

1 голос
/ 09 августа 2011

Пример окончательно соответствует C99, а AFAIR также C89.

Если с каким-то конкретным (старым) компилятором возникнут проблемы, я не думаю, что предлагаемое решение - это путь. Не навязывайте динамическую инициализацию платформам, которые ведут себя хорошо. Вместо этого особый случай чудаков, которые требуют особого отношения. И постарайтесь свернуть их как можно быстрее.

...