开发者

Should you include source code in a header file?

开发者 https://www.devze.com 2023-02-02 12:24 出处:网络
I am working on porting some source code to a linux system, and as expected, some stuff is broken. One thing that is throwing an error for me right now, is that someone has a .h and a .cpp file that b

I am working on porting some source code to a linux system, and as expected, some stuff is broken. One thing that is throwing an error for me right now, is that someone has a .h and a .cpp file that both use fclose()

The compiler is complaining about fclose() being undeclared in the header file.

here was the function declaration in th开发者_运维百科e header file:

void closeFile() { if (fp) fclose(fp); }

Now, I think this is bad style, but also - how did they get this working before? Did their version of the compiler allow this kind of behavior?

Should I fix this by including stdio in the header, or move the whole thing to the cpp?


It's not bad style, you can put source code in header files, and some times you're forced to, in particular:

  • When defining a template class/function.

  • When defining an inline function.

Anyway you shouldn't put a free (defined outside a class scope) non-inline function in a header file, since that would be compiled any time a source file include such header (and this will give you a linking error).

If you're getting an error that states fclose hasn't been declared, it's probably because cstdio (or stdio.h) wasn't declared before that piece of code. Put an #include <cstdio> at the beginning of the header file.


Just to add 2 things about the other answers, remember inline is not an order, is more a guess of what the compiler should do, unless you force inline. Most compilers can decide when to inline a function, even if you did not declare it inline. It's not a must, it is a should.

Sometimes you really need to include such function/structs/classes definitions in the header, and sometimes they are not trivial or that simple. But those definitions are usually some auxiliar functions you need and you just don't want to include them on the main file, just to organize things better.

The best examples I ever seen (ok, and I didn't see those many) about this practice is game source code (that's my main interest :) ).

By the way, I usually do not put any declaration on header files (except structs and enums), I put them on separated files, unless if:

  • There are only a few declarations/aux functions to be made; or
  • These declarations are functions that I will use in another contex (of the same project, in the case) and I just think it's better to treat them as a separated 'auxiliar library' (within the same context).

Hope it helps somewhat.


Keep in mind that header files aren't compiled by themselves (usually). They are #included into source files and the definitions available when the header file is parsed are whatever was included in the source file above the header file in question.

Regardless of whether the header file is an appropriate place for the implementation of closeFile(), your header file should #include everything it needs at the top of itself. So, add #include <stdio.h> at the top of the header file.

(Note that if this is code intended to be compiled into the Linux kernel itself, you may need a different header than stdio.h. Often application-level headers aren't suitable to be used in the kernel sources.)


fclose() will be undefined if you haven't included stdio.h either in this header or before it everywhere this header is used. That is why the error occurs.

I personally see nothing wrong with the code being allowed to be in a header file, however, if it is, and you're using C99, you should declare it

inline void closeFile() { if (fp) fclose(fp); }

This means multiple compiled objects won't have closeFile() symbols (because of inline) and the inline hints to the compiler that this shouldn't be left as a function call but substituted inline which is probably want you want for speed.


The headers are included by textual substitutions (that is the whole content of the header is substituted to the #include declaration). So if there is only one .cpp file that include this particular header, this is equivalent with having the function defined in the .cpp file. I think this is the reason why it was working (at link time).

The C standard only define the header that must be included to have a function available but does not forbid the system header to include one another. So it is possible that on some system, the stdio.h header was implicitly included by another header (and thus no error reported by the compiler).

Personally, I would move such code to the .cpp file, as it will be less brittle (the header can be included by multiple .cpp files, the header will not require a previous inclusion of the stdio.h header) and will allow for quicker recompilation if the implementation must be changed (to add logging or proper error handling, as closing a file can fail).

0

精彩评论

暂无评论...
验证码 换一张
取 消