Предупреждение о подавлении встраивания
Вопрос
Я получаю внутреннее предупреждение, такое как :
warning: inlining failed in call to ‘symbol_Arity’: call is unlikely and code size would grow
Чтобы избавиться от этого, я изменил makefile, удалив -Winline, чтобы избавиться от этого.Я не получаю никаких встроенных предупреждений.Но я не знаю, насколько разумно это делать с точки зрения производительности.Кто-нибудь, пожалуйста, может подсказать мне по этому поводу?
Добавлено еще немного информации:
вот это предупреждение:
search.c: In function ‘prfs_InsertInSortTheories’:
list.h:254: warning: inlining failed in call to ‘list_Delete’: call is unlikely and code size would grow
search.c:187: warning: called from here
list.h:254: warning: inlining failed in call to ‘list_Delete’: call is unlikely and code size would grow
search.c:189: warning: called from here
и соответствующий код является:
из списка.h
254 static __inline__ void list_Delete(LIST L)
255 {
256 LIST Current;
257
258 Current = L;
259 while (!list_Empty(Current)) {
260 L = list_Cdr(L);
261 list_Free(Current);
262 Current = L;
263 }
и из поиска.c
176 LIST approx;
177 l = clause_Length(Clause);
178 for (i = clause_FirstSuccedentLitIndex(Clause); i < l; i++) {
179 lit = clause_GetLiteral(Clause,i);
180 if (clause_LiteralIsMaximal(lit) &&
181 symbol_IsBaseSort(term_TopSymbol(clause_LiteralSignedAtom(lit)))) {
182 if (prfs_DynamicSortTheory(Search) != (SORTTHEORY)NULL
183 && clause_NumOfSuccLits(Clause) == 1 &&
184 clause_NumOfAnteLits(Clause) == 0)
185 {
186 copy = clause_Copy(Clause);
187 list_Delete(clause_ParentClauses(copy));
188 clause_SetParentClauses(copy,list_Nil());
189 list_Delete(clause_ParentLiterals(copy));
190 clause_SetParentLiterals(copy,list_Nil());
191 clause_SetNumber(copy,clause_Number(Clause));
192 sort_TheoryInsertClause(prfs_DynamicSortTheory(Search),Clause,
193 copy,clause_GetLiteral(copy,i));
194 }
Решение
Единственная "проблема" заключается в том, что вы пытаетесь заставить компилятор делать что-то неэффективное.
Использование ìnline
вместо того , чтобы __inline__
, и уважайте решения компиляторов о том, что должно быть встроено, а что нет.Не пытайтесь форсировать это, если только вы уже не профилировали код и не обнаружили, что это узкое место, и проверено, что встраивание действительно ускорит, а не замедлит работу с кодом.
По сути, это то, о чем говорится в предупреждении:"вы просите меня сделать что-то глупое, что замедлит работу кода.Я собираюсь проигнорировать это".
И, конечно, вы можете проигнорировать (или заставить замолчать) предупреждение, но лучшее решение - просто не заставлять его делать какие-либо глупости в первую очередь.Не используйте специфичный для компилятора __inline__
, и использовать inline
если вам это нужно, и доверяйте компилятору решать, что вставлять.
Другие советы
Удалить static __inline__
из функции в заголовочном файле и замените ее на inline
- стандартное ключевое слово C++.Вы не должны получать предупреждение из-за этого.
Я наткнулся здесь после компиляции некоторого старого кода с -Werror -Winline - предупреждение, которое я хочу включить по умолчанию, потому что оно обнаруживает существенные ошибки, где вы забыли операторы присваивания и т.д.
Однако для конкретной функции мне абсолютно необходимо, чтобы она всегда была встроенной, и, следовательно, мне нужен был способ подавить предупреждение только для этого блока кода.
#pragma GCC diagnostic ignored "-Winline"
Это был очевидный выбор, но на самом деле он не отменяет это предупреждение.Решение заключается в использовании атрибута always_inline:
inline bool function() __attribute__((always_inline));
inline bool function() { /*something*/ };
Это позволит избавиться от предупреждения и фактически всегда принудительно встраивать
Я не вижу в этом проблемы!
Насколько я понимаю, задержки производительности быть не должно, потому что компилятор обрабатывает встроенную функцию как обычную!
Посмотрите, что скажет GCC!
-Выигрышная линия
Предупреждать, если функция не может быть встроенной и она была объявлена как встроенная.Даже при использовании этой опции компилятор не будет предупреждать о сбоях встроенных функций, объявленных в системных заголовках.Компилятор использует различные эвристические методы, чтобы определить, следует ли встроить функцию.Например, компилятор учитывает размер встраиваемой функции и объем встраивания, который уже был выполнен в текущей функции.Таким образом, кажущиеся незначительными изменения в исходной программе могут привести к появлению или исчезновению предупреждений, выдаваемых -Winline.