Я не уверен, как встроить функции в c (C99 и далее). В разделе 18.6 «Программирование на С, современный подход» (К. Н. Кинг, 2-е издание) или, например, 3 в этом учебнике (в разделе «Стратегии использования встроенных функций»), определение встроенной функции дается в файле заголовка (.h), затем функция снова указывается как extern в файле источника (.c).
Например, что я делаю: в заголовке "stencil.h"
#ifindef _STENCIL_H
#define _STENCIL_H
inline double D1_center_2ndOrder(double vp1, double vm1, double dr)
{
return (vp1-vm1) / (2.0 * dr) ;
}
#endif
Затем в соответствующем исходном файле "stencil.c" определяется
#include "stencil.h"
extern double D1_center_2ndOrder(double vp1, double vm1, double dr) ;
Я сделал это, а затем в файле "main.c" я назвал среднее:
#include <stdio.h>
#include <stdlib.h>
#include "stencil.h"
int main(int argc, char *argv[])
{
double vp1 = 1 ;
double vp2 = 2 ;
dr = 0.1 ;
double der_v = D1_center_2ndOrder(vp1, vm1, dr) ;
printf("der_v\t%f\n", der_v) ;
return 0 ;
}
Я компилирую все с помощью следующего make-файла
CC = gcc
CFLAGS = -Wall -lm -std=gnu11
OBJECTS = main.o stencil.o
DEPS_MAIN = stencil.h
test: $(OBJECTS)
$(CC) -o collapse $(OBJECTS) $(CFLAGS)
main.o: main.c $(DEPS_MAIN)
$(CC) -c main.c
stencil.o: stencil.c stencil.h
$(CC) -c stencil.c
И тогда я получаю следующую ошибку компилятора:
gcc -c main.c
gcc -c stencil.c
gcc -o test main.o stencil.o -Wall -lm -std=gnu11
stencil.o: In function `D1_center_2ndOrder':
stencil.c:(.text+0x0): multiple definition of `D1_center_2ndOrder'
main.o:main.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
make: *** [collapse] Error 1
Когда я определяю функцию в исходном файле .c "stencil.c" и объявляю ее в заголовочном файле, я не получаю вышеуказанную ошибку. Я использую версию gcc:
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28).
Мои вопросы:
(1) Почему тогда «Программирование на C, современный подход» и учебные пособия по встраиванию функций, которые я нахожу в Интернете, предлагают определить функцию в заголовочном файле и снова перечислить ее как extern в исходном файле? Это приводит к ошибке компилятора.
(2) Когда я объявляю встроенную функцию в заголовочном файле, а затем определяю как extern в исходном файле, будет ли компилятор по-прежнему включать мою функцию?