что может снова вызвать ошибку множественного определения после объявления функции inline? - PullRequest
4 голосов
/ 14 декабря 2011

У меня был этот заголовочный файл, содержащий много встроенных функций, после компиляции он говорит: множественное определение функции ***, функция которой выглядит так:

inline int testab(int a, int b)
{
        return a>b;
}

после того, как я добавил static перед inline, ошибка исчезла. Это правильный способ сделать это? Или я что-то упустил? Я думал, что смогу настроить встроенные функции в таком заголовке.

Ответы [ 2 ]

7 голосов
/ 14 декабря 2011

inline или нет, если заголовок скопирован как минимум в два файла, вы больше не можете связывать файлы.

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

Обратите внимание, что нет ограничений на их совместное использование, поэтому вы можете смело писать:

static inline bool testab(int a, int b)
{
        return a>b;
}

Редактировать: Подробнее

inline сообщает компилятору, что вы думаете, что функция достаточно мала, чтобы ее можно было встроить. То есть вы говорите компилятору, что не думаете, что дополнительное пространство для встраивания функции имеет большое значение, в отличие от (небольшого) (возможного) прироста производительности для нее. Большинство компиляторов, однако, достаточно умны, чтобы решить, что самостоятельно и с вашим ключевым словом они просто будут стремиться к немного больше в строке и не обязательно всегда будут вас слушать. Это зависит от компилятора, конечно. Некоторые компиляторы могут полностью игнорировать ключевое слово.

static, с другой стороны, означает, что независимо от области, в которой определена статическая переменная, она будет невидима вне ее. Если в функции есть переменная static, она будет невидима вне ее. Если в файле есть переменная static (то есть статическая глобальная переменная), она будет невидима вне его, что означает, что после компиляции символа там нет, чтобы компоновщик увидел и запутался. Вот почему, если вы написали библиотеку, в которой есть глобальные переменные или функции, которые не должны быть видны за пределами библиотеки, вы должны объявить их как static.

Редактировать 2: Исправление

Очевидно, согласно этому ответу , функции inline не должны экспортировать свои идентификаторы для компоновщика. Тем не менее, к нему можно прикрепить static в любом случае, чтобы сделать его более понятным. Также очевидно, что некоторые компиляторы в любом случае экспортируют идентификатор, поэтому в этих случаях static действительно необходим.

0 голосов
/ 14 декабря 2011

Вам необходимо указать static, если вы определяете функцию в заголовочном файле, в противном случае для этой функции создается несколько определений таблицы символов (по одному в каждом файле .c), и они будут конфликтовать при попытке связать соответствующие объектные файлы. , Чтобы определить встроенную функцию в заголовке, я считаю, вам нужно:

static inline int foo(int x) __attribute__((always_inline))
    {
    return x+1;
    }

не уверен, что это совершенно верно; см .: http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Inline.html#Inline.

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