Home » Community » Forums » » Organizing Code Files in C and C++
  Intel sponsors gamedev.net search:   
[Control Panel] [Register] [Bookmarks] [Who's Online] [Active Topics] [Stats] [FAQ] [Search]

Add Forum to Favorites |  Send Topic To a Friend | View Forum FAQ | Track this topic

Page:   1 2 »»

 Last Thread Next Thread 
 Organizing Code Files in C and C++
Post Reply 
Good job. Now I have a link to point the questions to.

[ GDNet Start Here | GDNet Search Tool | GDNet FAQ | MS RTFM [MSDN] | SGI STL Docs | Google! | Asking Smart Questions ]
Thanks to Kylotan for the idea!


 User Rating: 2027   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Ah, if I only had this article 6 months ago, before I had to learn the things it covers the hard way :/

Great stuff anyway

-Lord Maz-

 User Rating: 1007   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Nice.

A good article followup would be how to do command line compliation and how the compile/link process works.

That's would really get people understanding how to organize the code.

 User Rating: 1017   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Good work Kylotan, there are SO many forums posts on this subject.


Helpful links:
How To Ask Questions The Smart Way | Google can help with your question | Search MSDN for help with standard C or Windows functions


 User Rating: 1071   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Good stuff.

 User Rating: 1249   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Great article - I first learned this from Diana Gruber's book and Borland when I was first learning C++.

I have seen some other projects actally test for the inclusion Guard in the code file. I thought that during compilation, the header file's information was kept in tact (in memory) until the end of compilation.

example:

// foo.cpp

#ifndef INCG_SOMEHEADER_H
#include "someheader.h"
#endif

...


However, it does speed up compilation a little - probably only because the compiler doesn't have to open and close a file to determine whether to include the header's contents. Although it does muddy the code file some.


Great article -


#dth-0


 User Rating: 1121   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

quote:
Original post by xiuhcoatl
I have seen some other projects actally test for the inclusion Guard in the code file.

This makes the source file dependent on knowledge of the internal implementation of the header, which opposes loose coupling. Bad ThingTM. If you receive a header, necessary libraries and documentation, you should have no reason to look through the header to use it. I've never needed to look through the STL headers to make my implementations more robust (I've been through the Dinkumware implementation to make the fixes); have you?

[ GDNet Start Here | GDNet Search Tool | GDNet FAQ | MS RTFM [MSDN] | SGI STL Docs | Google! | Asking Smart Questions ]
Thanks to Kylotan for the idea!


 User Rating: 2027   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Excellent article Kylotan! You covered the basics really well and also provided a little depth for a well rounded article!

As a suggestion on further developing the article, you might want to consider adding a section on variable scope, as it applies to files and translation units. There is the obvious link(!) to the use of extern and additional information regarding concepts like the static keyword at file level. Or perhaps just write a separate article on variable scope! ;-)

Cheers,

Timkin


 User Rating: 1509   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

nice article!!!
it answered all my questions on the subject.

 User Rating: 1250   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Suggested further reading: for experienced developers as well as beginners:

Large Scale C++ Software Design - Lakos

Although some suggestions in the book pre-date common use of namespaces, the ideas are the same.

Many of the examples that klyotan pointed out are also touched upon there as well as more advanced concepts such as what a 'component' is in physical design terms.

Timkin - using 'static' to specify file scope is a deprecated feature in ANSI C++ ( I think ) - the new way is to use an anonymous namespace. It has the same essential effect.

 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

nice..

but personaly I realy dont like splliting files into *.h and *.cpp. I have all the code in one file (except if it's realy long then I split it into some logical parts)

There are more worlds than the one that you hold in your hand...

 User Rating: 1336   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Very handy, I hope you post it on some other c++ sites too, for some reason it's hard to find beginner info on that subject.
dave


 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

After five hard days trying to get my multi-file project working and posting several questions here at gamedev, I have to say that your article helped me with those little things I was missing. Thank you and nice job!!

 User Rating: 1052   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Great article. Came just at the right time for me... I'm doing some C programming (for PalmOS) from a C++/Java background, and this really filled in some gray areas for me. The idea of a translation unit is still a bit fuzzy to me, but a second reading would probably resolve that. Thanks for the help!

 User Rating: 1015    Report this Post to a Moderator | Link

Thanks for all the kind words everybody, and I'm glad that some of you are finding it useful, which was of course the goal. Please keep any suggestions coming in, and I'll try and submit any necessary changes or revisions en masse at a later date.

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions ]

 User Rating: 1905   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Nice article, but there's a little mistake on the first page... CVS allows two developpers to work on the same file at the same time. I should write an article on it, I guess

-MoonJihad

 User Rating: 1015    Report this Post to a Moderator | Link

Not really a mistake as such, but perhaps it's misleading. I know CVS lets 2 people work on the same file at once, and I had intended to point out that CVS provided a solution to this problem. Rather than preventing 2 people working on 1 file, it attempts to merge the changes, as you know. Of course, some would say that this is still a bad idea as each developer may be making changes based on the assumption that the rest of the file is not changing! Maybe you could put that in your suggested article

I will reword this paragraph when I submit the errata list, thanks.

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions ]

 User Rating: 1905   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Nice article!

Global variables...
I use a macro like this:

EXTERN int foo;

And in the beginning of the header:

#ifndef EXTERN
#define EXTERN extern
#endif

So if it isn't defined EXTERN will be extern, meking it a declaration.
And in one source file I do:

#define EXTERN
#include "bar.h"

This way I can have both the definitions and declarations in the
same place... makes it easy to add and remove globals.

Joakim


 User Rating: 1015    Report this Post to a Moderator | Link

Nice article!

Global variables...
I use a macro like this:

EXTERN int foo;

And in the beginning of the header:

#ifndef EXTERN
#define EXTERN extern
#endif

So if it isn't defined EXTERN will be extern, meking it a declaration.
And in one source file I do:

#define EXTERN
#include "bar.h"

This way I can have both the definitions and declarations in the
same place... makes it easy to add and remove globals.

Joakim


 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

yeah, *thinks of a word other than 'nice'* good article. ok, i have one question.

what if i had an instance of a class inside another class, instead of a pointer. so basically this.
// ...
private:
	CLog	m_oDefaultLog;	// instead of CLog* m_pDefaultLog; 
then i do have to include that header file (the one which defines class CLog) inside that header (the one that uses class CLog), right? a class predeclaration wouldn't help here, would it (gives me lots of errors, so i don't think so)? that kind of makes me worry, because it's sort of an infinite loop (one header includes another, which includes the 1st one). even though the inclusion guard lets it compile error-free, it seems a bit wrong to me. it'd be nice if i could keep all include's of other headers inside the source file (CLogManager.cpp), not its header (CLogManager.h).

but then again, i think that any file which includes CLogManager.h should also include CLog.h, without having to write both includes. that makes sense, because if i change CLog into CSmartLog, every file which included CLogManager should 'adapt' and work with the new class without a problem. CLogManager is sort of an interface, which after completion should not change. if something it's a parent of (in this case, CLog) changes, the interface implentation changes, but the implentation stays the same (same thing with a library; if you 'optimize' it, any program written for it should not have to be completetly rewritten to work with the 'change'). i hope you understand what i'm saying.

just a few comments on what i said above would be nice. thanks.

---
shurcool
wwdev


[edited by - shurcool on August 11, 2002 2:02:42 AM]

 User Rating: 1137   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Sorry this reply is late...

quote:
Original post by shurcool
that kind of makes me worry, because it's sort of an infinite loop (one header includes another, which includes the 1st one). even though the inclusion guard lets it compile error-free, it seems a bit wrong to me.

If it compiles, then it's an unnecessary loop which you could probably resolve just by swapping a few things around. After all, a true 2-way dependency would never compile since one of the files must be compiled before the other.

quote:
but then again, i think that any file which includes CLogManager.h should also include CLog.h, without having to write both includes. that makes sense, because if i change CLog into CSmartLog, every file which included CLogManager should 'adapt' and work with the new class without a problem.

That's right: a header file is, as you say, an interface, and should contain everything it requires for that interface to work (linking considerations aside, when in C/C++). No more, no less.

There might be certain exceptions; eg. you may want to split a module's interface up into 2 files if some rarely-used parts of the interface would require including a lot of extra headers, and compile times are prohibitively long. But this, like any other optimisation, should be left until you're certain that you have such a problem.

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions | Organising code files | My stuff ]

 User Rating: 1905   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Thanks alot mate! Very good job indeed.
Problem 4 has been perplexing me for months now.

/me adds article to bookmarks

Thanks, Aaron

 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Hey!
EXCELLENT article! But that's been said a couple of times already, hasn't it?

Well I learnt how to resolve these errors the hard and dirty way, but even so I must admit, I find this article a great reference to turn to, THANKS.

Of course, I would like a few additions:
1) a little more detailed know-how-to-use extern! This explanation I think is necessary , IMHO.
2) You say this:
quote:
Of course, these are just declarations that my_global and SomeFunction exist somewhere. It doesn't actually create them. You still have to do this in one of the source files, as otherwise you will see a new linker error when it finds it cannot resolve one of the identifiers to an actual address. So for this example, you would add "int my_global" to either Code1.cpp or Code2.cpp, and everything should work fine. If it was a function, you'd add the function including its body (ie. the code of the function) into one of the source files.


I *think* It should read "you would add "int my_global" to either Code1.cpp or Code2.cpp, and everything should work fine,Adding the variable definition to both files will yield the same error again"
3)Should this: int my_global = 0; be included in either Code1.cpp OR code2.cpp?
i)I know that not initilizing a variable will NOT affect the working of the code but it IS good practice.
ii)I feel that the difference between *declaration* and *definition* is not apparent here, and the variable is allocated memory only when the storage is actualy allocated when "you create them" by saying
int my_global;
 

By using extern, its only telling the compiler that the variable has been *defined* somewhere else, just that the variable is available within this file for use (so its something like a variable declaration only)

Please excuse my lack of more technical terms and usage of laymans language,

I would love to hear if I made any valid suggestions, will only help me to understand your article a bit better.

 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

quote:
Original post by megajocke
Nice article!

Global variables...
I use a macro like this:

EXTERN int foo;

And in the beginning of the header:

#ifndef EXTERN
#define EXTERN extern
#endif

So if it isn't defined EXTERN will be extern, meking it a declaration.
And in one source file I do:

#define EXTERN
#include "bar.h"

This way I can have both the definitions and declarations in the
same place... makes it easy to add and remove globals.

Joakim



1)The author says:
quote:

the use of macros should be carefully controlled


and also
quote:

But if you need to use a macro for some reason, and you place it in a header file, try not to write macros that could potentially interfere with code in the files that include it


Seems to me that the approach you follow violates both the principles.

2)Also, how do you then define the global variable in your source file (that includes the header file with this EXTERN macro?)
If I try to define the variable in the source file, I get the same linker error that I avoided in the first place.
Any idea why?

3)
Why should you HAVE the variable declaration and definition in the same place? I mean is that why you are using the extern? I thought the use of extern was to do exactly teh opposite of that!


A few clarifications are needed.

 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link
Page:   1 2 »»
All times are ET (US)

Post Reply
 Last Thread Next Thread 
Forum Rules:
You may not post new threads
You may post replies
You may not edit your posts
You may not use HTML in your posts
Jump To:
Administrative Options: