Not logged in, Join Here! or Log In Below:  
 
News Articles Search    
 

 Home / General Programming / MSVC++ : Reincluding headers accidentally Account Manager
 
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.
 
zRXer

March 04, 2005, 12:40 PM

Hello there. This here is my first post on FlipCode, but I've been lurking around here for quite some time. My problem, as the title suggests, is that MSVC keeps including header files more than one time. This results in having multiple definitions of various classes. Now, in each header file I use, I have the standard #ifndef/#define to stop this from happening. It only happens with a few specific files/classes. MSVC then complains that there are function/class redefinitions in two object files. If I compile and link with /FORCE, the resulting executable seems to run fine.

I think the problem is related to the following:
These are the classes that have their function code in the header file along with their class definition. That is, after the class definition, I implement the member functions. Usually I use a separate .cpp file to implement these things, but in a few cases the classes/functions are sufficiently small that I just throw them all together.

So my question is this:
How can I resolve these errors? Should I just split everything into corresponding .cpp/.h files? What are some good methods of organizing your code into files other than this?

Any help would be very much appreciated, thanks.

 
Rasmus Christian Kaae

March 04, 2005, 01:08 PM

header.h:

#ifdef header_h
#define header_h

class IHaveInlinedCodeEvenThoughItIsUgly {
public:
IHaveInlinedCodeEvenThoughItIsUgly() {
cout

 
Max

March 04, 2005, 02:11 PM

You can put the code in the header file if you prefix the function implementation with the inline keyword.

I wouldn't recommend this unless you have a good reason for doing it though.

Max

 
zRXer

March 04, 2005, 03:19 PM

All right, thanks for the help.

 
XycsoscyX

March 05, 2005, 05:08 PM

Is that always true, though, about inlining it? For example, I have some functions in my image class, GetXSize, GetYSize, etc. These simply return the size, which is stored in an int. It doesn't calculate anything, just returns the value. I return it in a functions because the value itself is private, as it would explode and sends bits of silicon everywhere if it where changed on the fly without changing the image data pointer as well. Aaaanyways, these functions are defined in the header and I use __forceinline, but my executable complains that GetXSize and so on are already defined else where, and I am forced to use the /FORCE option to compile it correctly, which is does run fine after that.

So it is better/faster/safer? to just put the body of the function in the cpp file, regardless of if it's just returning the size value like I am doing? Is there are comprehensive listing of the maaaaany places that MSVC will ignore the inline and __forceinline function, or how the body of inlined functions get defined even though, as I understand inline, there is no body of the function, the body actually gets inserted wherever the function get's called?

 
Alex Herz

March 06, 2005, 07:09 AM

By the way..using the /FORCE is evil..don't get attrackted by the dark side!!

 
Danny Chapman

March 06, 2005, 07:28 AM

This should (i.e. I haven't actually tested it!) work:

file.hpp

  1.  
  2. #ifndef FILE_HPP
  3. #define FILE_HPP
  4.  
  5. class tClass
  6. {
  7. public:
  8.   // automatically gets inlined
  9.   int fn1() {return 0;}
  10.   // implementation is marked inline
  11.   int fn2();
  12. };
  13.  
  14. //---- inline implementations ----
  15.  
  16. inline int tClass::fn2()
  17. {
  18.   return 0;
  19. }
  20.  
  21. #endif
  22.  


If you omit the inline from fn2 then the compiler will generate duplicate symbols for it for every header that includes file.hpp. If you add inline the compiler won't, so the code should compile/link, _even_though_ it may internally decide not to inline it (e.g. by default the MSVC debug build disables all inlining).

Incidently, the same nominally inline function may get inlined when it gets used in one place, and not inline in another place. I'm not even sure that __forceinline forces it to be inline (I'd wait until you're absolutely desparately trying to squeeze more performance out of your code before using such non-standard stuff).

If you've got more than a few inline function's you could split them into a separate file (e.g. file.inl) and #include it at the end of the main include file - just makes things neater.

 
Bramz

March 06, 2005, 12:23 PM

inline must do the trick, but I agree with Max that for any function longer than a single instruction this isn't a good idea. The idea should be: by default put the implementation of the functions in the cpp file, and only bring them to the header file when necessary (because of performance reasons, or because you're doing template stuff :)

Bramz

 
Gerald Knizia (cgk)

March 06, 2005, 03:49 PM

Bramz:

inline must do the trick, but I agree with Max that for any function longer than a single instruction this isn't a good idea.

I disagree. The cost of function calls is often underestimated - they actually have a cost and it is significant in many situations (in comparison to the cost of the actual function). Also, at least VC will usually just ignore the inline keyword if you tell it to inline functions that really are not suitable for inlining. So if you are not sure if a function makes a good candidate for inlining, just declare and implement it in the header and leave the choice to the compiler instead of forcing it to be non-inline by implementing it in the .cpp (unless you don't care about the build time of a global optimization build).

Also, possible candidates for inlining are usually very short functions and therefore there is seldom a need to change them. So the additional requirement that all .cpp files that include the header in which they are defined need to be rebuilt on change is not very strong.

 
Bramz

March 07, 2005, 05:07 AM

you're forgetting that argument doesn't matter for 80% of the code ... That's why I said: write non-inline code by default, unless it's better to do otherwise.

http://www.gotw.ca/gotw/033.htm

 
Gerald Knizia (cgk)

March 07, 2005, 01:29 PM

you're forgetting that argument doesn't matter for 80% of the code ... That's why I said: write non-inline code by default, unless it's better to do otherwise.

I'm not forgetting this, I just don't see much reason for making programs slower or more bloated artificially. (Btw: you didn't say "unless it's better to do otherwise", which is of course the right thing to do. You said something along the lines of "never, unless the function is one instruction long" and the gotw you cite even says "never do that")

from the gotw you cite:
2. When and how should you decide to inline a function? Just like any other optimization: After a profiler tells you to, and not a minute sooner. The only time you'd inline right away is when it's an empty function that's likely to stay empty, or you're absolutely forced to, i.e., when writing a non-exported template.

The point is that most optimizations are eighter done right away or never, no matter if they are of algorithmical or implementational nature. So if there is few - or like here - no real cost in doing it right from the start this is exactly what should be done. Because otherwise you risk having to do the code twice (spending even more development time) or producing bad performance (and calling it "fast enought").
I'm not talking about spending a lot of time optimizing non-critical code here, I'm talking about the "should I spend five minutes on this function and get a O(n^2) result or six minutes get a O(n log n) result"-type of decisions in situations where you think the functions _might_ under some circumstances actually play a role in total performance.

This "never optimize before the profiler tells you" attitude has flooded this planet with a lot of bad software. Sure, you can't expect any wonders from inlining code or using expression templates in release builds. But such changes can easily make a difference of factor two or more in speed in some applications.

And I sure don't need a profiler to tell me that in an 2D-array class the [] operator should be inlined!

 
juhnu

March 07, 2005, 10:00 PM

I am personally writing lots of code in the "headers". For many classes it doesn't make much sense to split the implementation between a header and and a .cpp file. It seems many people are doing the splitting just because "they were taught so" without really understanding the real reasons, nor the benefits of such approach. Usually I hear these very same arguments everytime i am talking about this:


1. the splitting provides separation between the interface and its' implementation

the fundamental flaw here is that the private variables and implementation specific inner classes must be exposed in the header and therefore undermining the nice idea of hiding the implementation. Pure abstract interfaces and class factories provide better means of the separation and gives you nice and clean public header files.


2. "coding in headers" increases compilation times.

the full rebuild times with multiple .cpp's are usually longer than including and compiling them all into a one compilation unit. there's a quite big overhead including all the headers needed and spawning the compiler.

however for the partial build this is not necessarily true and can be very well the opposite. Keeping the compilation unit sizes reasonable helps in that.


3. Implementation makes reading the class interface difficult

use a good IDE with a class view window, or check a generated documentation for the interface, I know this is pretty much due to the personal preferences, but Java and C# coders seem to happy at least. Automated documentation pretty much solves this problem.


4. do you have something else to add?



;)


I rather do:

  1.  
  2. --IDevice.h--
  3. class IDevice {
  4. public:
  5. virtual void Do()=0;
  6. };
  7. --Device.cpp--
  8. #include "IDevice.h"
  9. #include <implementation specific things like d3d.h, windows.h>
  10.  
  11. class Device: public IDevice {
  12.  
  13. smart_ptr<IDirect3DDevice9> d3dDevice;
  14.   struct Helper {
  15.     void Bla() {
  16.        //do something here
  17.     }
  18.   };
  19.  
  20. virtual void Do() {
  21.   ..do something here
  22. }
  23.    
  24. };
  25.  

than:
  1.  
  2. --Device.h--
  3. #include <implementation specific things like d3d.h, windows.h>
  4.  
  5. class Device {
  6.  
  7.    smart_ptr<IDrect3DDevice9> d3dDevice;
  8. struct Helper {
  9.   void Bla();
  10. };
  11.  
  12. void Do();
  13. };
  14.  
  15. --Device.cpp--
  16.  
  17. #include "Device.h"
  18.  
  19. void Device::Do() {
  20.   //do something
  21. }
  22. void Device::Helper::Bla() {
  23.   //do something
  24. }
  25.  


note that the first one has much cleaner public header which doesn't need to include implementation specific headers such as d3d.

Juhani

 
This thread contains 12 messages.
 
 
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.