2016-11-02 6 views
8

Я хотел бы точно понять, почему макрос видимости libC++ для встроенной функции использует __forceinline или __attribute__((__always_inline__)) как часть атрибутов, которые он связывает с встроенными функциями.Почему libcxx применяет __forceinline или GCC эквивалентно его уже скрытым встроенным функциям?

Для получения дополнительной информации см:

Если эти встроенные функции будут помечены как __visibility__("hidden") в любом случае, почему необходимо дополнительно заставить компилятор встраивать их ?

Я думал об этом немного, и у меня есть несколько гипотез, но ни одна не кажется вполне удовлетворительным для меня:

  • Это для того, чтобы символ не случайно стал частью ABI. Если при создании библиотеки компилятор решил не встраивать функцию, она потенциально может стать внешним символом и, следовательно, частью ABI. Но будет ли атрибут hidden достаточным? Точно так же, не нужно ли только принудительное включение функции при построении библиотеки? Потребителям все равно.
  • Это должно гарантировать, что функция никогда не имеет определения, чтобы избежать проблем с ODR, когда компилятор не хочет встроить функцию в библиотеку и не хочет встроить функцию в код, созданный клиентом библиотеки, что приводит к двум различным определениям. Но разве это не ожидаемый (и принятый) результат использования visibility("hidden")?
  • Это что-то особенное для дизайна libC++ как реализации стандартной библиотеки.

Я спрашиваю об этом, потому что я работаю над созданием библиотеки C++, для которой я надеюсь когда-нибудь стандартизировать ABI, и я использую libC++ в качестве руководства. До сих пор он работал хорошо, но этот вопрос вызвал некоторые царапины на голове.

В частности, у нас были сообщения пользователей, жалующихся на то, что MSVC отказался соблюдать атрибут __forceinline, что приводит к предупреждениям. Наше предлагаемое решение состоит в том, чтобы расширение нашего аналога с INLINE_VIBIBITY включало только __forceinline (или эквивалент GCC) при создании библиотеки, предполагая первое объяснение выше.

Однако, поскольку мы не полностью уверены в том, что мы понимаем, что причиной форсирования встроенных функций является __forceinline или __attribute__((__always_inline__)), мы в первую очередь не решаемся принять это решение.

Может ли кто-нибудь дать окончательный ответ на вопрос, почему libC++ чувствует необходимость принудительно встроить свои встроенные функции, даже если они уже украшены как скрытые видимости?

ответ

4

Я, вероятно, в лучшем положении, чтобы обратиться к этому, поскольку я тот, кто это сделал. И вам может не понравиться ответ. :-)

Когда я создавал libC++, моей единственной целью был macOS (OS X). Это было до того, как libC++ был открыт с открытым исходным кодом. И моя главная мотивация для принудительного inline - контролировать ABI дилиба, который будет вытеснен версиями ОС. Принудительная встроенная функция никогда не будет отображаться в dylib, и поэтому я могу рассчитывать на то, что она живет исключительно в заголовке (у которого была другая система доставки, чем выпуски ОС).

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

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

+0

Мне нравится этот ответ, и спасибо, что нашли время ответить. Похоже, что мы, вероятно, продолжим и переоценим, не является ли наше грузирование __forceinline ненужным и его нужно удалить. Похоже, все могло бы быть. Кроме того, если вы заинтересованы в том, чтобы найти подход, который мы принимаем или предоставляем какие-либо отзывы, библиотека, о которой идет речь, является libmongocxx: https://github.com/mongodb/mongo-cxx-driver/tree/master – acm