-
June 11th, 2012, 06:08 PM
#1
What is wrong with my code organization?
First off, let me introduce you to the method of code organization I've been using. I'll have one main .cpp file where the basic functionality of the entire program can be understood. High-level functions called by the main .cpp file are placed in a .h file. Low-level functions called by the high-level functions are placed in other .h files and so on.
No compiler problems until I get to the issue of struct/object recognition among different .h files.
I've encountered problems with global structs being recognized in some compiled .h files, but not in others.
for example:
Code:
#ifndef low_level1
#define low_level1
struct my_struct
{
int x;
int y;
} its_mine;
#endif
Now, if I have several low-level .h files that use its_mine, and I #include "low_level1" in all of these other .h files, eventually I end up with compiler errors like:
Code:
error C2065: 'its_mine' : undeclared identifier
when some of the .h files are being compiled. Now I know what the error message means, it just means that the declaration of its_mine isn't found for some of the .h files even though I used #include "low_level1.h". This doesn't make sense to me why.
I temporarily fixed this by making all my globally used structs into objects and placing them all in an objects.h.
Now I have
Code:
#ifndef objects
#define objects
class my_class
{
public:
int x;
int y;
};
my_class its_mine;
#endif
I used #include "objects.h" in all of the .h files that used these objects and this worked for long enough that I thought that this was a solution to my woes. However, as my project grew I ended up with the same problem.
This isn't a method of code organization I learned from someone, it's just one I've used to serve my needs but I don't understand why compilers (I'm using VS2008) don't like it.
So my question is what is wrong with my code organization (besides the obvious answer everything)?
In case this isn't a question that can be answered without an exact example (some people make it sound like no question is) here are some snippets (I really hope no one thinks it's necessary to ask for all 10+ files and 5000+ lines of code...)
Code:
#ifndef objects
#define objects
class Squares{
int member;
};
#define SquaresY 13
#define SquaresX 6
Squares Square[SquaresY][SquaresX];
#endif
Code:
#ifndef image
#define image
#include "objects.h"
#include "low_level1.h"
#include "low_level2"
void myfunction()
{
if((Square[0][0].member != 0)
{
;
}
}
#endif
sample error:
c:\visual studio\....\image.h(33) : error C2065: 'Square': undeclared identifier
wheras Square is recognized as declared in several other .h files:
low_level1.h,
low_level2.h, etc.
and:
Code:
#ifndef low_level1
#define low_level1
#include "objects.h"
#include "image.h"
#include "low_level2.h"
// Compiler recognizes Square
// Code that uses Square....
#endif
Code:
#ifndef low_level2
#define low_level2
#include "objects.h"
#include "image.h"
#include "low_level1.h"
// Compiler recognizes Square
// Code that uses Square....
#endif
Last edited by notinasia; June 12th, 2012 at 02:51 PM.
-
June 11th, 2012, 11:31 PM
#2
Re: What is wrong with my code organization?
Originally Posted by notinasia
for example:
Code:
#ifndef low_level1
#define low_level1
struct my_struct
{
int x;
int y;
} its_mine;
#endif
Get rid of the "its_mine".
Code:
#ifndef low_level1
#define low_level1
struct my_struct
{
int x;
int y;
};
#endif
Once you do that, then work from there. Very rarely, if ever do C++ programmers create structs (and classes) with a trailing name. All that's needed is the struct or class definition.
If you now need to create a variable of type my_struct, then you do that in your implementation (.cpp) files, not in the header:
Code:
#include "low_level1.h"
int main()
{
my_struct its_mine;
//..
}
Also, if you really want to organize your code, get rid of the global variables. The issue you have has nothing to do with Visual C++ -- you have global variables declared in a header file, and you're including this header in multiple source files. What ends up happening is that the linker will see x number of global variables with the same name, and you can't have that (the linker will complain about multiple definitions of the same global variable).
Either get rid of the usage of global variables, or learn what the extern keyword does with respect to declaration of global variables.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; June 12th, 2012 at 04:04 AM.
-
June 12th, 2012, 01:53 PM
#3
Re: What is wrong with my code organization?
Paul,
I tried
Code:
extern Squares Square[SQUARESY][SQUARESX]
In the function that uses Square[][] in image.h.
I then get
Code:
error C2146: syntax error : missing ';' before identifier 'Square'
However when I do the same thing in the function that uses Square[][] in lowlevel1.h, for example, I get no compiler errors.
I don't understand because there's no consistency. All of my global objects, and object definitions are recognized in all the other .h files except for in "image.h". I had a similar problem when I was using global structs. Everything compiled fine until my project got larger and then I started having similar compiler issues with the global structs. There were no syntax errors or anything, the global stuff just stopped being recognized in some files after the project got large enough...
-
June 12th, 2012, 01:57 PM
#4
Re: What is wrong with my code organization?
I see that I did this incorrectly, I'll see if I can make this work with a .cpp and externs.....
-
June 12th, 2012, 02:30 PM
#5
Re: What is wrong with my code organization?
I have 2 .cpp files now. Objects.cpp is for defining extern global objects declared in Objects.h this didn't cause any more compiler errors, and I can see how this is good for organization, but the globabl objects are still not recognized in image.h,
I have 10 .h files and 2 .cpp files, and 100+ compiler errors resulting from failure to recognize these global objects...... Like I said, one minute it was compiling fine then as the project got larger it just stopped recognizing them in some files but not others
errors are all of this form:
Code:
error C2065: 'Square' undeclared identifier
error C2228: left of '.member' must have class/struct/union
etc. etc.
-
June 12th, 2012, 02:34 PM
#6
Re: What is wrong with my code organization?
and this is how I handled global definition/declartion:
objects.h
Code:
#ifndef objects
#define objects
/// includes
class Squares{
public:
////// members
};
//////////// #defines
extern Squares Square[SQUARESY][SQUARESX];
objects.cpp
Code:
#include "objects.h"
Squares Square[SQUARESY][SQUARESX];
Last edited by notinasia; June 12th, 2012 at 02:49 PM.
-
June 12th, 2012, 02:47 PM
#7
Re: What is wrong with my code organization?
#includes are not written that way. It should be
Code:
#include "objects.h"
Didn't your compiler tell you that?
Edit: When you get compiler errors always resolve the first one first. In many cases the ones that follow are because of the first one.
-
June 12th, 2012, 02:48 PM
#8
Re: What is wrong with my code organization?
Originally Posted by S_M_A
#includes are not written that way. It should be
Code:
#include "objects.h"
Didn't your compiler tell you that?
That is not copied and pasted from my project. The syntax in my project is correct.
-
June 12th, 2012, 02:51 PM
#9
Re: What is wrong with my code organization?
Instead of focusing on quoting focus on cutting & pasting the exact code when posting.
In post 6 you have posted a line that isn't terminated. Is that line copied or is it just a typo as well?
Last edited by S_M_A; June 12th, 2012 at 02:53 PM.
-
June 12th, 2012, 03:05 PM
#10
Re: What is wrong with my code organization?
Originally Posted by notinasia
and this is how I handled global definition/declartion:
You're all over the place here.
First, are you doing this off the top of your head, or are you following guidelines set by experienced C++ programmers? If it's the former and not the latter, then you're going to create a mess.
Second, it is preferable that you write applications with little, if any use of global variables.
Third, if you are going to use globals, start with the simplest of examples to learn how to use extern properly. One and only one source module must have the declaration without the extern keyword. All other modules must declare the global variable as extern.
Also, the issue is not whether the code will compile -- the issue is whether the code will link. That is where improper use of extern will cause errors, at the link stage, not the compile stage.
Code:
#include <iostream>
int x;
void foo();
int main()
{
foo();
std::cout << x;
}
Code:
extern int x;
void foo()
{
x = 10;
}
Compile and link these two modules. You will see that there are no linker errors, and the code behaves as expected.
Also, if you have a lot of globals (again, not recommended), then the trick is to do this:
Code:
#ifndef MYHEADER_H
#define MYHEADER_H
#ifdef MAIN_MODULE
#define EXTERN
#else
#define EXTERN extern
#endif
EXTERN int x;
EXTERN int y;
EXTERN int z;
#endif
Then when you #include "Myheader.h", the file where you do not want extern to be used, just #define MAIN_MODULE at the top of the file:
Code:
#define MAIN_MODULE
#include "MyHeader.h"
int main()
{
}
And all other modules, you don't define MAIN_MODULE. I leave it to you to figure out why this works.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; June 12th, 2012 at 03:07 PM.
-
June 12th, 2012, 03:09 PM
#11
Re: What is wrong with my code organization?
Unrelated to your problem, but will certainly add to confusion, why are you naming your class "Squares" (plural) and your array "Square" (singular)? That's the kind of thing that will drive you nuts later.
-
June 12th, 2012, 03:24 PM
#12
Re: What is wrong with my code organization?
Paul,
Originally Posted by Paul McKenzie
You're all over the place here.
First, are you doing this off the top of your head, or are you following guidelines set by experienced C++ programmers? If it's the former and not the latter, then you're going to create a mess.
I followed a stackoverflow guide: http://stackoverflow.com/questions/1...variables-in-c . I removed the extern declaration in "objects.h" if that is what you were concerned about.
Originally Posted by Paul McKenzie
Also, the issue is not whether the code will compile -- the issue is whether the code will link. That is where improper use of extern will cause errors, at the link stage, not the compile stage.
I figured as much on this part though the errors follow after
Output:
I will try again with the format you gave me
-
June 12th, 2012, 03:49 PM
#13
Re: What is wrong with my code organization?
I now have 1 .cpp and 10 .h's. This is a windows app if that makes a difference for any reason. I'm defining my globals in my main.cpp
main.cpp:
Code:
#define MAIN_MODULE
#include <windows.h>
#include "window_properties.h"
#include "resources.h"
#include "swordfight.h"
#include "play.h"
#include "objects.h"
handles_o handles;
Keys Key[NUM_KEYS] = {0,1,2,3,4};
Pieces Piece[2];
state_o state(0,0,0,0,1,0);
app_o app;
settings_o settings;
#define SquaresY 13
#define SquaresX 6
Squares Square[SquaresY][SquaresX]; // Array of the Game Squares
vector<Squares> Surface;
Squares Actual[2];
Squares Previous[2];
Squares Desired[2];
Squares Next[2];
Squares TopSquares;
Plans Plan[2];
Links_o Links;
/////// Code follows ////////////
In my objects.h I declare the globals:
Code:
#ifndef objects
#define objects
#ifdef MAIN_MODULE
#define EXTERN
#else
#define EXTERN extern
#endif
//#include<vector>
#include "swordfight.h"
#include "object_functions.h"
#include <windows.h>
#include "resources.h"
#include <vector>
#include "image.h"
class handles_o
{
HWND hwnd; // Process handle
HIMAGELIST imagelist; // Imagelist handle
};
EXTERN handles_o handles;
class settings_o
{
settings_o() {executable =DE1; pixels_x = DE2; pixels_y = DE3; colors = DE4;}
string executable;
int pixels_x;
int pixels_y;
char colors;
};
EXTERN settings_o settings;
#define P_THIS 0
#define P_NEXT 1
class Pieces
{
public:
char bottom;
char top;
};
EXTERN Pieces Piece[2];
#define CW 0
#define CCW 1
class state_o
{
public:
void SetPlay(char p){ play = p;}
bool GetPlay(){ return play==1;}
void toggle_play() {play = !play & detect;}
state_o(char p, char d, char v, char dt, char f, char w)
{
play = p; detect = d; valid = v; detectsf = dt; first = f; win = w; fail = 0;
}
char play;
char detect;
char valid;
char detectsf;
char first;
char win;
char fail;
};
EXTERN state_o state;
class app_o
{
public:
unsigned int x;
unsigned int y;
HWND hwnd;
DWORD pid;
HDC dc;
RECT play_rect; // play area
RECT next_rect; // next piece area
RECT sb1_rect; // score board 1 area
RECT sb2_rect; // score board 2
};
EXTERN app_o app;
///////////////////// Remaining declarations follow ///////////////////////////
I understand what the format you gave me does. I still have recognition problems in 2 of my .h files
image.h and configuration.h, both of which include objects.h.
I am doing everything the way you have suggested so it's odd that there are still problems. I will see if there's anything out of the ordinary in those two files (i.e. if there are any global variables defined in them or anything out of the ordinary).
-
June 12th, 2012, 03:55 PM
#14
Re: What is wrong with my code organization?
Originally Posted by notinasia
I now have 1 .cpp and 10 .h's. This is a windows app if that makes a difference for any reason. I'm defining my globals in my main.cpp
You're defeating the purpose of the EXTERN macro by redeclaring those same variables in main.cpp.
Code:
#include "objects.h"
handles_o handles;
The handles_o_ handles is already declared in objects.h. Why are you declaring it again? You do this with several variables in main().
Regards,
Paul McKenzie
-
June 12th, 2012, 04:04 PM
#15
Re: What is wrong with my code organization?
I see. I combined the advice from you with the advice from stackoverflow..
While I'm fixing this.. will the following with initial values also work correctly?
Code:
EXTERN int i = 0;
EXTERN myclass its_mine(/* constructor arguments */);
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|