Visual Studio 2012 Express compiler not linking header files together correctly

Eri*_*oma 0 c++ visual-studio visual-c++

I am setting up some framework for a little 2D game. Right now, I just have a few classes, but I am immediately falling into compiler problems.

I have run this program with only the main function, so I can confirm that the Allegro (graphics library) library linking has worked.

I have put all my header files (.h) under the "Header Files" section in the Solution explorer and all my source (.cpp) in the "Source Files" section. I have only modified settings from default as according to this Allegro tutorial: http://wiki.allegro.cc/index.php?title=Windows,_Visual_Studio_2010_and_Allegro_5. It should not have affected anything in a destructive way.

I have several files, so I will list each one. I will skip some code to reduce size and redundancy. When I omit any code or do anything not verbatim, I will put a comment in the code saying so. (EDIT: I actually did not skip any code)

main.cpp

#include "common.h"

int main(int argc, char **argv)
{
   ALLEGRO_DISPLAY *display = NULL;
   World* world = new World(640, 480);

   if(!al_init()) {
      fprintf(stderr, "failed to initialize allegro!\n");
      return -1;
   }

   display = al_create_display(640, 480);
   if(!display) {
      fprintf(stderr, "failed to create display!\n");
      return -1;
   }

   al_clear_to_color(al_map_rgb(0,0,0));

   world->draw(display);

   al_flip_display();

   al_rest(10.0);

   al_destroy_display(display);

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

common.h

#if !defined(COMMON_INC)
#define COMMON_INC

#include "World.h"
#include "Pane.h"
#include <stdio.h>
#include <allegro5/allegro.h>

#endif
Run Code Online (Sandbox Code Playgroud)

World.h

#if !defined(WORLD_INC)
#define WORLD_INC

#include "common.h"
#include "Pane.h"

class World{
public:
    World(int wp, int hp);
    void draw(ALLEGRO_DISPLAY* display);
    void update();


protected:

private:
    Pane* panel;
    int heightPix, widthPix;

};

#endif
Run Code Online (Sandbox Code Playgroud)

World.cpp

#include "common.h"

World::World(int wp, int hp){
    widthPix = wp;
    heightPix = hp;
    panel = new Pane(this, 10, 10, 300, 400);
    return;
}

void World::draw(ALLEGRO_DISPLAY* display){
    panel->draw(display);
    return;
}
Run Code Online (Sandbox Code Playgroud)

Pane.h

#if !defined(PANE_INC)
#define PANE_INC

#include "common.h"

class Pane{
public:
    Pane(World* w, int xv, int yv, int wi, int he);
    World* getWorld();
    int getZ();
    void draw(ALLEGRO_DISPLAY* display);
    ALLEGRO_BITMAP* getBackground();

protected:
    void setXY(int xv, int yv);
    void setWidthHeight(int wi, int he);
    void setZ(int zv);
    void setBackground(ALLEGRO_BITMAP* ba);

private:
    int z;
    int x, y; //pixels
    int width, height; //pixels
    World* world;
    ALLEGRO_BITMAP* background;
};

#endif
Run Code Online (Sandbox Code Playgroud)

Pane.cpp

#include "common.h"

Pane::Pane(World* w, int xv, int yv, int wi, int he){
    this->setWidthHeight(wi, he);
    this->setXY(xv, yv);
    this->world = w;
}

World* Pane::getWorld(){
    return world;
}

void Pane::setXY(int xv, int yv){
    x = xv;
    y = yv;
    return;
}

void Pane::setWidthHeight(int wi, int he){\
    width = wi;
    height = he;
    return;
}

void Pane::setZ(int zv){
    z = zv;
    return;
}

void Pane::draw(ALLEGRO_DISPLAY* display){
    if(background != NULL)
        al_draw_bitmap(background, x, y, 0);
    else{
        background = al_create_bitmap(width, height);

        al_set_target_bitmap(background);

        al_clear_to_color(al_map_rgb(255, 0, 255));

        al_set_target_bitmap(al_get_backbuffer(display));

        al_draw_bitmap(background, x, y, 0);
    }
    return;
}
Run Code Online (Sandbox Code Playgroud)

The compiler produces this error report upon building: (I called the game madscientist because it is supposed to be alchemy-themed)

1>------ Build started: Project: MadScientist, Configuration: Debug Win32 ------
1>  main.cpp
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(8): error C2061: syntax error : identifier 'World'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(9): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(9): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(9): warning C4183: 'getWorld': missing return type; assumed to be a member function returning 'int'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(11): error C2061: syntax error : identifier 'ALLEGRO_DISPLAY'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(12): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(12): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(12): warning C4183: 'getBackground': missing return type; assumed to be a member function returning 'int'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(18): error C2061: syntax error : identifier 'ALLEGRO_BITMAP'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(24): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(24): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(25): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(25): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\world.h(10): error C2061: syntax error : identifier 'ALLEGRO_DISPLAY'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\main.cpp(22): error C2660: 'World::draw' : function does not take 1 arguments
1>  World.cpp
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(8): error C2061: syntax error : identifier 'World'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(9): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(9): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(9): warning C4183: 'getWorld': missing return type; assumed to be a member function returning 'int'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(11): error C2061: syntax error : identifier 'ALLEGRO_DISPLAY'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(12): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(12): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(12): warning C4183: 'getBackground': missing return type; assumed to be a member function returning 'int'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(18): error C2061: syntax error : identifier 'ALLEGRO_BITMAP'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(24): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(24): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(25): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(25): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\world.h(10): error C2061: syntax error : identifier 'ALLEGRO_DISPLAY'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\world.cpp(6): error C2661: 'Pane::Pane' : no overloaded function takes 5 arguments
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\world.cpp(10): error C2511: 'void World::draw(ALLEGRO_DISPLAY *)' : overloaded member function not found in 'World'
1>          c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\world.h(7) : see declaration of 'World'
1>  Pane.cpp
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(8): error C2061: syntax error : identifier 'World'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(9): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(9): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(9): warning C4183: 'getWorld': missing return type; assumed to be a member function returning 'int'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(11): error C2061: syntax error : identifier 'ALLEGRO_DISPLAY'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(12): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(12): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(12): warning C4183: 'getBackground': missing return type; assumed to be a member function returning 'int'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(18): error C2061: syntax error : identifier 'ALLEGRO_BITMAP'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(24): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(24): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(25): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(25): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\world.h(10): error C2061: syntax error : identifier 'ALLEGRO_DISPLAY'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.cpp(3): error C2511: 'Pane::Pane(World *,int,int,int,int)' : overloaded member function not found in 'Pane'
1>          c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(6) : see declaration of 'Pane'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.cpp(9): error C2556: 'World *Pane::getWorld(void)' : overloaded function differs only by return type from 'int *Pane::getWorld(void)'
1>          c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(9) : see declaration of 'Pane::getWorld'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.cpp(9): error C2371: 'Pane::getWorld' : redefinition; different basic types
1>          c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(9) : see declaration of 'Pane::getWorld'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.cpp(10): error C2065: 'world' : undeclared identifier
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.cpp(30): error C2511: 'void Pane::draw(ALLEGRO_DISPLAY *)' : overloaded member function not found in 'Pane'
1>          c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(6) : see declaration of 'Pane'
1>  Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Run Code Online (Sandbox Code Playgroud)

You have all of the info that I do. I will summarize it for you to save the trouble of looking through everything.

  • There are classes separated into header interfaces and source implementations
  • common.h is included by all files. It itself includes all of the class definitions in the other header files
  • When compiled, the compiler does not recognize classes defined in other header files as data types. Errors, as you would expect, cascade down.
  • The real-time error checker does not register any errors. When hovering over the word "World" when it is used as a datatype in Pane, for example, it recognizes the type perfectly. The real-time error checker is the feature that red underlines errors before compiler time.
  • This Visual Studio 2012 Express is new except for the modifications mentioned earlier. The project was created as an empty C++ project. Before many headers and sources were add, the main function compiled correctly.

Thank you for any responses. If you have any questions, please ask. The problems I have with Visual Studio always irk me.

EDITS:

My circular header logic is guarded by the header guards. I don't think this redundancy is a problem.

我尝试从头文件中删除所有包含,除了包含Allegro库.这似乎更好,但仍然有奇怪的问题.为什么包含的行为导致这些数据类型出错仍然是一个谜.这是新的错误日志:

1>------ Build started: Project: MadScientist, Configuration: Debug Win32 ------
1>  main.cpp
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\world.h(16): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\world.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>  World.cpp
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\world.h(16): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\world.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\world.cpp(6): error C2065: 'panel' : undeclared identifier
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\world.cpp(11): error C2065: 'panel' : undeclared identifier
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\world.cpp(11): error C2227: left of '->draw' must point to class/struct/union/generic type
1>          type is ''unknown-type''
1>  Pane.cpp
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\world.h(16): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\world.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>  Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Run Code Online (Sandbox Code Playgroud)

编辑第2轮:

我改变了我的代码,所以common.h只包括stdio和Allegro.所有头文件和源文件都包含common.h,然后包含他们单独使用的任何类头文件.Pane.cpp包括Pane.h和common.h.World.h包括Pane.h和common.h.

错误日志读取:

1>------ Build started: Project: MadScientist, Configuration: Debug Win32 ------
1>  main.cpp
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(9): error C2061: syntax error : identifier 'World'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(10): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(10): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(10): warning C4183: 'getWorld': missing return type; assumed to be a member function returning 'int'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(25): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(25): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>  World.cpp
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(9): error C2061: syntax error : identifier 'World'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(10): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(10): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(10): warning C4183: 'getWorld': missing return type; assumed to be a member function returning 'int'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(25): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\pane.h(25): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\world.cpp(7): error C2661: 'Pane::Pane' : no overloaded function takes 5 arguments
1>  Pane.cpp
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\world.h(16): error C2143: syntax error : missing ';' before '*'
1>c:\users\ethoma\documents\visual studio 2012\projects\madscientist\madscientist\world.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>  Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Run Code Online (Sandbox Code Playgroud)

这就是我现在看到我的包含订单的方式:

  1. 主要包括共同点
  2. common定义了COMMON_INC
  3. 常见的包括stdio和allegro
  4. 主要包括World.h
  5. 世界定义了WORLD_INC
  6. World includes common, which is blocked. But this should be okay because common is already included
  7. World includes Pane
  8. Pane defines PANE_INC
  9. Pane includes common, which is blocked. But this should be okay because common is already included.
  10. Pane includes World. This is blocked because main already included World. Shouldn't this be okay since World was already included. Why do I even have compiler guards if I need to include files many times over, once for each file that uses it?

EDITS ROUND 3: I have learned a lot from the answers and comments here. It turns out that, according to Wikipedia, "circular dependencies are often introduced by inexperienced programmers who need to implement some kind of callback functionality." The mere fact that Pane uses World and World uses Pane is a design flaw. In Java, this was all fine for me. It was very easy; I thought that this was the best way to notify the entity that "possesses" an object of the object's actions.

It turns out that this is a bad design scheme. Objects should not have dependencies to their "possessors". Instead, I need to implement a observer system, where the Pane can tell the World that it has updated its state.

Reading wikipedia cleared up any questions that I had, so I now consider this question finished. Thanks to the contributors for putting up for a learning programmer.

AnT*_*AnT 6

您的头文件无法正确链接.您以循环方式包含了标题.您的头文件包括common.h,而common.h反过来包括其他标题,如World.hPane.h.

任何编译器都无法编译.您必须开发标头层次结构,从低级标头到高级标头,并确保更高级别的标头仅包含更低级别的标头.这样你就可以确保没有圆形内含物.

无论如何,为什么你的common.h包括World.hPane.h?这看起来像是一个明显的错误.common.h是一个低级标题.让我们World.hPane.h包括它,但不包括World.hPane.hcommon.h.

请注意,在这种情况下,标题保护不会解决任何问题.他们只是确保包含周期不会无限.它们打破了循环,但如果存在这样的依赖关系,它们无法帮助您解决声明之间的循环依赖关系.

看看处理时你的情况会发生什么 main.cpp

  1. main.cpp 包括 common.h
  2. common.h 定义 COMMON_INC
  3. common.h 包括 World.h
  4. World.h 定义 WORLD_INC
  5. World.h包括common.h.包括警卫在内的整个过程common.h被跳过,因为COMMON_INC在步骤2中定义了.
  6. World.h 包括 Pane.h
  7. Pane.h 定义 PANE_INC
  8. Pane.h包括common.h.包括警卫在内的整个过程common.h被跳过,因为COMMON_INC在步骤2中定义了.
  9. Pane.h提到的类型World.类型World是未知的,因为我们还没有得到它的定义World.h.错误!

  • @ user93353:包含警卫只会确保不会发生无限循环.包含防护将在一些任意位置拆分包含周期(取决于首先包含哪个头).一个标题最终将包含在第一个和另一个标题中.这种包含顺序可能最终不正确.这正是OP的情况,这就是他收到这些错误消息的原因. (3认同)