CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 22
  1. #1
    Join Date
    Aug 2011
    Posts
    13

    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.

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: What is wrong with my code organization?

    Quote Originally Posted by notinasia View Post
    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.

  3. #3
    Join Date
    Aug 2011
    Posts
    13

    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...

  4. #4
    Join Date
    Aug 2011
    Posts
    13

    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.....

  5. #5
    Join Date
    Aug 2011
    Posts
    13

    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.

  6. #6
    Join Date
    Aug 2011
    Posts
    13

    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.

  7. #7
    Join Date
    Oct 2006
    Location
    Sweden
    Posts
    3,654

    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.
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are, by
    definition, not smart enough to debug it.
    - Brian W. Kernighan

    To enhance your chance's of getting an answer be sure to read
    http://www.codeguru.com/forum/announ...nouncementid=6
    and http://www.codeguru.com/forum/showthread.php?t=366302 before posting

    Refresh your memory on formatting tags here
    http://www.codeguru.com/forum/misc.php?do=bbcode

    Get your free MS compiler here
    https://visualstudio.microsoft.com/vs

  8. #8
    Join Date
    Aug 2011
    Posts
    13

    Re: What is wrong with my code organization?

    Quote Originally Posted by S_M_A View Post
    #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.

  9. #9
    Join Date
    Oct 2006
    Location
    Sweden
    Posts
    3,654

    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.
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are, by
    definition, not smart enough to debug it.
    - Brian W. Kernighan

    To enhance your chance's of getting an answer be sure to read
    http://www.codeguru.com/forum/announ...nouncementid=6
    and http://www.codeguru.com/forum/showthread.php?t=366302 before posting

    Refresh your memory on formatting tags here
    http://www.codeguru.com/forum/misc.php?do=bbcode

    Get your free MS compiler here
    https://visualstudio.microsoft.com/vs

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: What is wrong with my code organization?

    Quote Originally Posted by notinasia View Post
    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.

  11. #11
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    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.

  12. #12
    Join Date
    Aug 2011
    Posts
    13

    Re: What is wrong with my code organization?

    Paul,

    Quote Originally Posted by Paul McKenzie View Post
    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.

    Quote Originally Posted by Paul McKenzie View Post

    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:
    Code:
    Compiling...
    I will try again with the format you gave me

  13. #13
    Join Date
    Aug 2011
    Posts
    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).

  14. #14
    Join Date
    Apr 1999
    Posts
    27,449

    Re: What is wrong with my code organization?

    Quote Originally Posted by notinasia View Post
    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

  15. #15
    Join Date
    Aug 2011
    Posts
    13

    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 */);

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured