Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unusual usage of .h file in C

Tags:

c++

c

During reading article about filtering, I've found some strange using of .h file - use it for filling array of coefficients:

#define N 100 // filter order float h[N] = { #include "f1.h" }; //insert coefficients of filter float x[N]; float y[N];  short my_FIR(short sample_data) {   float result = 0;    for ( int i = N - 2 ; i >= 0 ; i-- )   {     x[i + 1] = x[i];     y[i + 1] = y[i];   }    x[0] = (float)sample_data;    for (int k = 0; k < N; k++)   {     result = result + x[k]*h[k];   }   y[0] = result;    return ((short)result); } 

So, is it normal practice to use float h[N] = { #include "f1.h" }; this way?

like image 540
artsin Avatar asked Nov 10 '14 11:11

artsin


People also ask

What is the purpose of .h files in C?

Header files serve two purposes. System header files declare the interfaces to parts of the operating system. You include them in your program to supply the definitions and declarations you need to invoke system calls and libraries.

Are .h files necessary?

Yes, because it's still based on C. You can answer your own question: Don't use them and try to compile without them. If you can't, then the compilers still require them.

Can we include other than .h file in C?

Yes. We can include files of extension . C also if any function or external variable is defined in other file and we want to use it in the current file. yes .


2 Answers

Preprocessor directives like #include are just doing some textual substitution (see the documentation of GNU cpp inside GCC). It can occur at any place (outside of comments and string literals).

However, a #include should have its # as the first non-blank character of its line. So you'll code

float h[N] = {   #include "f1.h" }; 

The original question did not have #include on its own line, so had wrong code.

It is not normal practice, but it is permitted practice. In that case, I would suggest using some other extension than .h e.g. use #include "f1.def" or #include "f1.data" ...

Ask your compiler to show you the preprocessed form. With GCC compile with gcc -C -E -Wall yoursource.c > yoursource.i and look with an editor or a pager into the generated yoursource.i

I actually prefer to have such data in its own source file. So I would instead suggest to generate a self-contained h-data.c file using e.g. some tool like GNU awk (so file h-data.c would start with const float h[345] = { and end with };...) And if it is a constant data, better declare it const float h[] (so it could sit in read-only segment like .rodata on Linux). Also, if the embedded data is big, the compiler might take time to (uselessly) optimize it (then you could compile your h-data.c quickly without optimizations).

like image 176
Basile Starynkevitch Avatar answered Sep 23 '22 01:09

Basile Starynkevitch


As already explained in previous answers, it is not normal practice but it's a valid one.

Here is an alternative solution:

File f1.h:

#ifndef F1_H #define F1_H  #define F1_ARRAY                   \ {                                  \      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, \     10,11,12,13,14,15,16,17,18,19, \     20,21,22,23,24,25,26,27,28,29, \     30,31,32,33,34,35,36,37,38,39, \     40,41,42,43,44,45,46,47,48,49, \     50,51,52,53,54,55,56,57,58,59, \     60,61,62,63,64,65,66,67,68,69, \     70,71,72,73,74,75,76,77,78,79, \     80,81,82,83,84,85,86,87,88,89, \     90,91,92,93,94,95,96,97,98,99  \ }  // Values above used as an example  #endif 

File f1.c:

#include "f1.h"  float h[] = F1_ARRAY;  #define N (sizeof(h)/sizeof(*h))  ... 
like image 28
barak manos Avatar answered Sep 27 '22 01:09

barak manos