Thread: Curiosity: including .cpp files

  1. #1
    Registered User
    Join Date
    Nov 2006
    Location
    Coimbra, Portugal
    Posts
    64

    Curiosity: including .cpp files

    This isn't related to any problem I'm having, but I'd like to understand this issue once and for all.

    When people do something like:
    Code:
    #include "myfile.cpp"
    I often see replies saying "you can't include .cpp files. Only header files!"

    I beg to differ. Here's a little example I prepared:

    hellomain.cpp code
    Code:
    #include <iostream>
    #include "helloworld.cpp"
    
    using namespace std;
    
    int main() {
      helloWorld();
      cin.get();
      return 0;
    }
    helloworld.cpp code
    Code:
    #include <iostream>
    using namespace std;
    
    void helloWorld();
    
    void helloWorld() {
      cout << "Hello World!" << endl;
    }
    Assuming both .cpp files lie in the same directory, I can compile and execute hellomain.cpp just fine! I don't even need to create a project file in Dev-C++ for this to work!

    So the question is... Is there something I'm missing? Why exactly do people say we can only include header files? Is it something else I should know?

    Looking forward to your replies.

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    #include just copies and pastes code for the compiler. In this case it will work, but in a real application where you might want to use HelloWorld() in multiple source files, you'll get multiple definition and possibly other errors.

    Anyway, including cpp files would also mean that the order in which and where the file is included matters. So far I have managed to write almost all projects so that this doesn't matter.
    Last edited by anon; 01-17-2007 at 10:11 AM.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    It is by convention, with the exception that templates might be divided into a header file and "implementation" file, with the latter included in the former.

    This is typically because function and class declarations are placed in header files with a ".h" (or ".hpp") extension, and the implementations of these functions and classes are placed in files with a ".cpp" (and other) extensions.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Ethernal Noob
    Join Date
    Nov 2001
    Posts
    1,901
    You can but you shouldn't. You should want to separate implementation and declaration by using the .h and .cpp files seperately, and only including the .h files when necessary. The compilation and linking process ensures that if code from an included header file is needed, it is linked into the executable. Why do something the linker does for you?

  5. #5
    Its hard... But im here swgh's Avatar
    Join Date
    Apr 2005
    Location
    England
    Posts
    1,688
    Header files as a genreal rule should only include class and function definitions along with the suitable header gaurds for that file. They should not include any "working" C++ code.

    ie: std::cout << "Hello\n";

    The header file is then included into the project at the point it is needed. (usually the corrisponding .cpp file that holds the implementation for the class in the header file )
    Double Helix STL

  6. #6
    Registered User
    Join Date
    Nov 2006
    Location
    Coimbra, Portugal
    Posts
    64
    Quote Originally Posted by anon
    #include just copies and pastes code for the compiler. In this case it will work, but in a real application where you might want to use HelloWorld() in multiple source files, you'll get multiple definition and possibly other errors.

    Anyway, including cpp files would also mean that the order in which and where the file is included matters. So far I have managed to write almost all projects so that this doesn't matter.
    Now I see your point. I have slightly changed my example. Normally, one would put all three files in the same directory and compile:

    g++ -Wall hellomain.cpp helloextra.cpp -o helloworld.exe

    (helloworld.cpp wouldn't be needed, since it's already included in hellomain.cpp)

    But you're right. I get a multiple definition error if I do that.

    You see, the reason I asked this is mainly because of compilers such as gcc and g++. The conventional way requires you to put all .c or .cpp files in gcc or g++, like so:

    g++ -Wall hellomain.cpp helloextra.cpp helloworld.cpp -o helloworld.exe

    where the three .cpp files would only include function implementations and not function prototypes. For the prototypes, one would (possibly) have to create three additional files - hellomain.hpp helloextra.hpp and helloworld.hpp with those prototypes. But then I thought: "Why do we programmers have to bother with separating function prototypes from the actual function implementations? Wouldn't it be more convenient to just store them all in single files rather than two files each?"

    Really, it kind of sucks. My approach would definitely work if g++ discarded multiple definitions of functions, but I guess I'll just have to be content with what I got...

  7. #7
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    >discarded multiple definitions of functions

    And how would it know which one to keep? This error is no different than if you actually declared the same function multiple times.

  8. #8
    Registered User
    Join Date
    Nov 2006
    Location
    Coimbra, Portugal
    Posts
    64
    Quote Originally Posted by Perspective
    >discarded multiple definitions of functions

    And how would it know which one to keep? This error is no different than if you actually declared the same function multiple times.
    Wouldn't matter in this case. helloWorld() has the exact same code on both definitions. I'd like the compiler to just pick one definition and throw the rest of them away. Another way would be to check the actual code of the definitions - if the code were equal, keep one of them; if one definition had different code, show an error or something.

    For example:

    Code:
    //A definition
    helloWorld() {
      cout << "Hello World!" << endl;
    }
    //Another definition (duplicate)
    helloWorld() {
      cout << "Hello World!" << endl;
    }
    No differences between both helloWorld() functions here, right? Just discard one and everything will be just fine.

    Another example:
    Code:
    //A definition
    helloWorld() {
      cout << "Hello World!" << endl;
    }
    //Another definition - this one doesn't have the ! at the end
    helloWorld() {
      cout << "Hello World" << endl;
    }
    Whoopsey! There's a difference between both. Now this is where I'd like to be "greeted" with an error message.

    But, like I said, I doubt g++ has a flag for this, so I might reconsider my programming style in C++. It's no big deal, really. If I have to pay the price of separating functions from their prototypes to use C++ effectively, so be it. Everyone has to pay certain prices when they choose a programming language, right?

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Wouldn't matter in this case. helloWorld() has the exact same code on both definitions. I'd like the compiler to just pick one definition and throw the rest of them away. Another way would be to check the actual code of the definitions - if the code were equal, keep one of them; if one definition had different code, show an error or something.
    In the first place, having such duplicate code probably means that you are not thinking right, or were careless. That the compiler tells you sooner about the potential problem instead of later is a Good Thing, in my opinion.

    Consider the likelihood that two non-trivial functions would be identical. I think that it is not worth the trouble trying to do that kind of duplicate code elimination when most of the time that it happens, you have to resolve it manually anyway.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Don't use simple command lines for compiling. Use a Make-like program like Make itself, SCons, bjam, any of those work very well and the compilation is reduced to invoking the build process as "make" or "bjam" or "scons".
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    Registered User
    Join Date
    Nov 2006
    Location
    Coimbra, Portugal
    Posts
    64
    Quote Originally Posted by CornedBee
    Don't use simple command lines for compiling. Use a Make-like program like Make itself, SCons, bjam, any of those work very well and the compilation is reduced to invoking the build process as "make" or "bjam" or "scons".
    Doesn't solve my problem. I'd still have to separate prototypes from implementations. Sorry, but my point still stands. I apologize if I'm being annoying, but I just can't help it - I hate separating prototypes from functions. Yes, despite the fact that it's the conventional way. Have you ever imagined a project where you'd have 7 files, each requiring prototypes? You'd need 7 extra files, just for the prototypes! I don't know about you, but in my opinion, it looks ugly.

    I know that most of you on this board strongly supports that we should follow the conventions at all costs. But I strongly believe that I do have a point. It's just my opinion. Please don't hate me for it. It's not my intention to make enemies on this message board.

    Thank you all for your help.

  12. #12
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by Mr_Miguel
    Doesn't solve my problem. I'd still have to separate prototypes from implementations. Sorry, but my point still stands. I apologize if I'm being annoying, but I just can't help it - I hate separating prototypes from functions. Yes, despite the fact that it's the conventional way. Have you ever imagined a project where you'd have 7 files, each requiring prototypes? You'd need 7 extra files, just for the prototypes! I don't know about you, but in my opinion, it looks ugly.

    I know that most of you on this board strongly supports that we should follow the conventions at all costs. But I strongly believe that I do have a point. It's just my opinion. Please don't hate me for it. It's not my intention to make enemies on this message board.

    Thank you all for your help.
    I prefer to include small file like stdio.h and be able to compile my project using printf, scanf etc, when to include code for these functions in my own code
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  13. #13
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Quote Originally Posted by Mr_Miguel
    Doesn't solve my problem. I'd still have to separate prototypes from implementations. Sorry, but my point still stands. I apologize if I'm being annoying, but I just can't help it - I hate separating prototypes from functions. Yes, despite the fact that it's the conventional way. Have you ever imagined a project where you'd have 7 files, each requiring prototypes? You'd need 7 extra files, just for the prototypes! I don't know about you, but in my opinion, it looks ugly.

    I know that most of you on this board strongly supports that we should follow the conventions at all costs. But I strongly believe that I do have a point. It's just my opinion. Please don't hate me for it. It's not my intention to make enemies on this message board.

    Thank you all for your help.
    Create a program that generates header files for you. It's simple enough and I'm sure it's been done before -- for c programs you could use cproto, but I don't think cproto works with C++ templates.

    Or you could lump together some prototypes from different files into one header file. (Maybe that's not such a good idea either.)
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  14. #14
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    Quote Originally Posted by Mr_Miguel
    Doesn't solve my problem. I'd still have to separate prototypes from implementations. Sorry, but my point still stands. I apologize if I'm being annoying, but I just can't help it - I hate separating prototypes from functions. Yes, despite the fact that it's the conventional way. Have you ever imagined a project where you'd have 7 files, each requiring prototypes? You'd need 7 extra files, just for the prototypes! I don't know about you, but in my opinion, it looks ugly.
    at the risk of being harsh, tough! This is not a "convention", it is correct usage. If you don't like it, use another language. C/C++ are pretty much the only languages I know that enforce this kind of separation.

    Think of it like this. It is a "convention" to drive with your hands at the "ten to two" position on the steering wheel, but if you don't, you'll probably still get by. However, it's more than a convention to drive on the correct side of the road (depending on your country). You may think that driving on the left is ugly, but if you end up in Ireland/NZ/Australia/UK you have no choice. You may even get away with it on a small empty road but as soon as you hit a city or a motorway.... CRASH!

    Quote Originally Posted by Mr_Miguel
    I know that most of you on this board strongly supports that we should follow the conventions at all costs. But I strongly believe that I do have a point. It's just my opinion. Please don't hate me for it. It's not my intention to make enemies on this message board.

    Thank you all for your help.
    Unfortunately, there's a difference between opinion (i.e. manutd belief that templates don't require an entire book) and error. You can have all the opinions you want, but it doesn't change the fact that you are wrong in this case.

    We don't hate you for it. We're simply trying to educate you. If you persist with this incorrect approach, it will bite you, but I don't have to worry about that. Besides, I just can't bring myself to hate someone over a programming language! (skiing vs. snowboarding, road vs mountain biking, aikido vs judo, these are subjects worthy of hatred! )
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  15. #15
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Have you ever imagined a project where you'd have 7 files, each requiring prototypes? You'd need 7 extra files, just for the prototypes!
    You don't need 7 extra files. If all the functions belong logically together (or even if not, if you prefer being lazy), you can put all the prototypes in one header and include it in all 7 implementation files.

    I often have one header per class, but the methods are distributed among several files (grouped by similar functionality). I dislike source files longer than 100 lines ... coming from a version of BASIC where the entire source must be in one file.

    Create a program that generates header files for you.
    Wow, although I'm considering using some sort of flow-charts or class-diagrams, writing headers is actually the place where I tend to do most of the thinking. Implementation files are just an annoyance where you do bug fixing.

    Also, consider using some IDE, that keeps all the files of a project nicely together and tells the compiler what to do with these for you.
    Last edited by anon; 01-17-2007 at 04:50 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to better manage large .cpp files
    By 39ster in forum C++ Programming
    Replies: 6
    Last Post: 08-25-2008, 08:24 AM
  2. C++ std routines
    By siavoshkc in forum C++ Programming
    Replies: 33
    Last Post: 07-28-2006, 12:13 AM
  3. Replies: 4
    Last Post: 12-14-2005, 02:21 PM
  4. including files in php
    By oskilian in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 07-06-2002, 10:32 AM
  5. Class files (.h and .cpp
    By Todd in forum C++ Programming
    Replies: 7
    Last Post: 02-14-2002, 03:07 PM