2016-11-23 4 views
0

У меня есть функция (давайте назовем ее void foo(void) {}), что я хочу быть inline.But я определил ее внутри .cpp-файла.
Я не могу переместить функцию в заголовок, потому что он использует другие функции из .cpp.ссылка на extern включена, но не определена



EDIT:
ниже код так же, как реальный не использует C++ функции. Я могу четко добавить:

#ifdef __cplusplus 
extern "C" 
#endif 

Если я хотел бы, чтобы преобразовать код в C99 мне нужно только изменить свои свойства проекта (или Makefile, если вам нравится) не код. Я также спрашиваю о C++, потому что он может решить мою проблему, а c99 не может.
поэтому теги C и C++ в моем вопросе оправданы. код портативный
см: When to use extern "C" in C++?



EDIT # 2
Ok я понимаю, что я должен положить foo() определение файла внутри заголовка. Как я могу позвонить func_a() и func_b() из foo(), не перемещая их в файл заголовка? Есть ли обходной путь?



Пример
file.c/.cpp:

int func_a (int a, int b, int c) {/*...*/}; 
double func_b (double a, double b, double c) {/*...*/}; 

void foo (int a, double b) { // unction definition 
    //... 
    int myInt = func_a(a, 2, 3); 
    //... 
    double myDouble = func_b(1.5f, b, 3.5f); 
    //... 
} 

file.h:

// Something before. 

void foo (int a, double b); // function declaration 

// Something after. 



Хочу отметить из:

  • Я работаю с Visual Studio 2015.
  • Я пишу относительно большой проект (~ 7000 строк кода). Это симуляция физической системы.
  • file.h включен во многие другие единицы компиляции.
  • foo(int, double) мал и вызывает другие функции из file.cpp
  • Я хочу сделать foo(int, double) инлайн из-за соображения оптимизации (я в конечном итоге с помощью __forceinline__)
  • Я зову foo() много, много раз по моей программе. Также он используется внутри нескольких циклов (по 100 кбайт итераций каждый), поэтому для этого символа foo() не является встроенным.
  • Мне больны только заголовки.



Я попытался:
file.c/.cpp:

extern inline 
void foo (int a, double b) {\*...*\}; // Definition 

file.h:

extern inline 
void foo (int a, double b); // Declaration 

, но я получаю предупреждение:

warning : extern inline function "foo" was referenced but not defined 

И я не понимаю, почему я получаю это предупреждение.



Есть ли способ:

  • Keep определение foo() в моем файле .cpp? Но все-таки сделать это рядный
  • движение foo() к file.h, держать func_a() и func_b() внутри file.cpp, но сделать func_a() и func_b() символы «видны» в foo() (! И только foo()!) От file.cpp
  • любой другой обходной ?


Сори я все еще учусь CPP, и я не знаю, если мой вопрос ясен, или даже можно сделать функцию инлайн из .cpp файла.

+2

C не C++ не C. Не добавлять несвязанные метки! – Olaf

+0

@olaf, как вы видели, я не использую функции C++. extern «C» - это то, что я часто использую в своем коде. 'foo()' скорее всего, в конечном итоге также будет использовать его. Я говорил о C++, потому что meaby C++ может решить эту проблему, а c не может – cukier9a7b5

+0

Просьба указать ссылку на стандарт C, где указан этот конструктор. Вы также не показываете это в своем коде. Прочтите [ask] и укажите [mcve]. – Olaf

ответ

3

В C++, то inline ключевого слова означает следующее:

  • тело функции должен присутствовать в каждом исходном файле, который использует эту функцию.
  • Функциональные «тела» во всех исходных файлах должны быть токенами-маркерами, а сущность-сущность идентична.
  • Компилятор & линкер должен убедиться, что они хорошо с функцией, имеющей эти «несколько тел»

Это все, что он делает. На практике это означает, что он позволяет и заставляет выставить тело функции в файл заголовка.

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

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

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

  1. продлить ваше время сборки, и
  2. позволяет компоновщик встроенных функций в места вызова через исходные файлы

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


В вашем конкретном случае использовать __forceinline__, вы будете иметь определить foo в файле заголовка. Для этого требуется определение foo, чтобы увидеть объявления func_a и func_b. Для предотвращения пространства имен Polution, вы можете объявить эти функции в пределах foo:

inline void foo(int a, double b) { // function definition 
    int func_a(int, int, int); 
    double func_b(double, double, double); 

    //... 
    int myInt = func_a(a, 2, 3); 
    //... 
    double myDouble = func_b(1.5f, b, 3.5f); 
    //... 
} 
+0

Большое спасибо. Я надеялся, что могу оставить свое определение функции внутри файла src. Поэтому есть ли способ сделать 'func_a()' и 'func_b()' видимыми для 'foo()' из файла src? BTW этот код будет в конечном итоге с '__forceinline__' не' inline' ключевым словом soo, я смогу заставить мой компилятор встроить его везде. – cukier9a7b5

+0

@ cukier9a7b5 Можете ли вы просто объявить (не определять) функции в файле заголовка? – Angew

+0

Тогда я закончу библиотеку только для заголовков. И мне это не нравится. Кроме того, я объявлю много символов, которые я не буду использовать для них, они не должны быть видны вне 'file.cpp', я здесь думаю об инкапсуляции кода. – cukier9a7b5