Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm an aspiring game developer, I work on occasional indie games, and for a while I've been doing something which seemed like a bad practice at first, but I really want to get an answer from some experienced programmers here.

Let's say I have a file called enumList.h where I declare all the enums I want to use in my game:

// enumList.h

enum materials_t { WOOD, STONE, ETC };
enum entity_t { PLAYER, MONSTER };
enum map_t { 2D, 3D };
// and so on.

// Tile.h
#include "enumList.h"
#include <vector>

class tile
{
    // stuff
};

The main idea is that I declare all enums in the game in 1 file, and then import that file when I need to use a certain enum from it, rather than declaring it in the file where I need to use it. I do this because it makes things clean, I can access every enum in 1 place rather than having pages openned solely for accessing one enum.

Is this a bad practice and can it affect performance in any way?

share|improve this question
1  
Source structure cannot affect performance - it'll still be compiled down to the same, no matter where the enums are. So really this is a question about where it would be best to put them, and for small enums, one file doesn't sound too taboo. –  Ruirize Dec 8 '12 at 10:37
    
I was asking in more extreme cases, a game can have many enums and they can be pretty big, but thanks for your comment –  Bugster Dec 8 '12 at 10:38
4  
It won't affect application performance, but it will have a negative effect on compile time. For instance, if you add a material to materials_t files that don't deal in materials will have to be rebuilt. –  Steven Burnap Dec 9 '12 at 5:00
8  
it's like putting all the chairs in your house in the chair room, so if you want to sit down, you know where to go. –  kevin cline Jan 8 '13 at 0:24
add comment

7 Answers 7

up vote 28 down vote accepted

I really think it is a bad practice. When we measure code quality, there's something we call "granularity". Your granularity suffers severely by putting all those enums in one single file and thus maintainability suffers, too.

I'd have a single file per enum to find it quickly and group it with the behavioural code of the specific functionality (e.g. materials enum in folder where material behaviour is etc.);

The main idea is that I declare all enums in the game in 1 file, and then import that file when I need to use a certain enum from it, rather than declaring it in the file where I need to use it. I do this because it makes things clean, I can access every enum in 1 place rather than having pages openned solely for accessing one enum.

You might think it is clean, but in fact, it is not. It's coupling things that do not belong together functionality- and module-wise and decreases the modularity of your application. Depending on the size of your code base and how modular you want your code to be structured, this might evolve into a bigger problem and unclean code/dependencies in other parts of your system. However, if you just write a small, monolithic system, this does not necessarily apply. Yet, I would not do it like this even for a small monolithic system.

share|improve this answer
1  
+1 for mentioning granularity, I took the other answers in consideration but you make a good point. –  Bugster Dec 8 '12 at 11:31
    
+1 for single file per enum. for one it's easier to find. –  mauris Dec 8 '12 at 13:08
7  
Not to mention that adding a single enum value used in one place will cause every file in your entire project to have to be rebuilt. –  Steven Burnap Dec 9 '12 at 4:59
    
good advice. you changed my mind anyway.. I always liked going CompanyNamespace.Enums.... and getting an easy list, but if the code structure is disciplined, then your approach is better –  Matthew Evans Jan 9 at 17:36
add comment

Yes, it's bad practice, not because of performance but because of maintainability.

It makes things "clean" only in the OCD "collect similar things together" way. But that's actually not the useful and good kind of "cleanliness".

Code entities should be grouped to maximize cohesion and minimize coupling, which is best achieved by grouping them into largely independant functional modules. Grouping them by technical criteria (such as putting all enums together) achieves the opposite - it couples code that has absolutely no functional relatioship and puts enums that might be used only in one place into a different file.

share|improve this answer
2  
True; 'only in the OCD "collect similar things together" way'. 100 upvotes if I could. –  Dogweather Jan 9 at 20:05
    
I'd help edit the spelling if I could, but you didn't make enough errors to get over the SE 'edit' threshold. :-P –  Dogweather Jan 9 at 20:08
    
interesting that almost all web frameworks require files to be collected by type instead of by feature. –  kevin cline Feb 14 at 6:48
    
@kevincline: I wouldn't say "almost all" - just those that are based on convention-over-configuration, and typically, those also have a module concept that allows grouping code functionally. –  Michael Borgwardt Feb 14 at 10:12
add comment

Well, this is just data (not behaviour). The worst that could possibly/theoretically happen is that the same code is included and compiled more than once producing a relatively larger program.

It is just plain impossible that such includes can add more cycles to your operations, given that there isn't any behavioural/procedural code inside them (no loops, no ifs, etc.).

A (relatively) larger program can hardly affect performances (speed of execution) and, in any case, is just a remote theoretical concern. Most (maybe all) compilers manage includes in a way that prevent such problems.

IMHO, the advantages that you get with a single file (more readable and more manageable code) largely exceed any possible drawback.

share|improve this answer
4  
You make a very good point that I think all the more popular answers are ignoring -- immutable data doesn't have any coupling at all. –  Michael Shaw Dec 8 '12 at 16:36
2  
I guess you have never had to work on projects that would take a half hour or longer to compile. If you have all your enums in one file and change a single enum, it's time for a long break. Heck, even if it only took a minute, that's still too long. –  Dunk Dec 10 '12 at 21:40
2  
Anyone working in module X under version control must get module X and the enum every time they wish do work. Further, it strikes me as a form of coupling if, every time you change the enum file, your change potentially effects every single module in your project. If your project is large enough that all or most team members do not understand every chunk of the project, a global enum is pretty dangerous. A global immutable variable isn't even close to as bad as a global mutable variable, but it's still not ideal. That said, a global enum is probably mostly ok on a team with <10 members. –  Brian Dec 11 '12 at 0:07
add comment

To me it all depends on the scope of your project. If there is one file with say 10 structs and that are the only ones ever used, I'd be perfectly comfortable having one .h file for it. If you have several different types of functionality, say a units, economy, buildings, etc I would definitely split things up. Create a units.h where all structs that deal with units reside. If you want to do something with units somewhere you need to include units.h sure, but it also is a nice "identifier" that something with units is probably done in this file.

Look at it this way, you don't buy a supermarket because you need a can of coke ;)

share|improve this answer
add comment

I'm not a C++ dev, so this answer will be more generic to OOA&D:

Typically, code objects should be grouped in terms of functional relevance, not necessarily in terms of language-specific constructs. The key yes-no question that should always be asked is, "will the end coder be expected to use most or all of the objects that they get when consuming a library?" If yes, group away. If not, consider splitting the code objects up and placing them closer to other objects that need them (thereby increasing the chance that the consumer will need everything they are actually accessing).

The basic concept is "high cohesion"; code members (from methods of a class all the way up to classes in a namespace or DLL, and DLLs themselves) should be organized such that a coder can include everything they need, and nothing they don't. This makes the overall design more tolerant of change; things that must change can be, without affecting other code objects that did not have to change. In many circumstances it also makes the application more memory-efficient; a DLL is loaded in its entirety into memory, regardless of how much of those instructions are ever executed by the process. Designing "lean" applications therefore requires paying attention to how much code is pulled into memory.

This concept applies at virtually all levels of code organization, with varying degrees of impact on maintainability, memory-efficiency, performance, build speed, etc. If a coder needs to reference a header/DLL of rather monolithic size just to access one object, which doesn't depend on any other object in that DLL, then that object's inclusion in the DLL should probably be rethought. However it is possible to go too far the other way as well; a DLL for every class is a bad idea, because it slows build speed (more DLLs to rebuild with associated overhead) and makes versioning a nightmare.

Case in point: if any real-world use of your code library would involve using most or all of the enumerations that you're putting into this single "enumerations.h" file, then by all means group them together; you'll know where to look to find them. But if your consuming coder could conceivably need only one or two of the dozen enumerations you are providing in the header, than I would encourage you to put those into a separate library and make it a dependency of the larger one with the rest of the enumerations. That allows your coders to get just the one or two they want without linking to the more monolithic DLL.

share|improve this answer
add comment

This sort of thing becomes an issue when you have multiple developers working on the same code-base.

I have certainly seen similar global files becoming a nexus for merge collisions and all sorts of grief on (larger) projects.

However, if you are the only one working on the project, then you should do whatever you are most comfortable with, and only adopt "best practices" if you understand (and agree with) the motivation behind them.

It is better to make some mistakes and learn from them than to risk getting stuck with cargo cult programming practices for the rest of your life.

share|improve this answer
add comment

Yes, it is bad practice to do so on a big project. KISS.

Young coworker renamed a simple variable in a core .h file and 100 engineers waited 45 minutes for all their files to rebuild, which affected everyone's performance. ;)

All projects start small, balloon over the years, and we curse those who took early shortcuts for creating technical debt. Best practices, keep global .h content limited to what's necessarily global.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.