2

while working on a personal project on a new language, I 've come across a annoying compiling time error where a static member of my constants.h (constants class) doesn't find the class name (Quark which is a derived class of Particle, those two in the same file "Particle.h") used in parameter...

Here is the compilation error output:

1>f:\bibliotheques\documents\visual studio 2013\projects\particlefuzzer\launcher\constants.h(41): error C2065: 'Quark' : undeclared identifier
1>f:\bibliotheques\documents\visual studio 2013\projects\particlefuzzer\launcher\constants.h(41): error C2923: 'std::vector' : 'Quark' is not a valid template type argument for parameter '_Ty'
1>f:\bibliotheques\documents\visual studio 2013\projects\particlefuzzer\launcher\constants.h(45): error C2065: 'Quark' : undeclared identifier
1>f:\bibliotheques\documents\visual studio 2013\projects\particlefuzzer\launcher\constants.h(45): error C2923: 'std::vector' : 'Quark' is not a valid template type argument for parameter '_Ty'
1>f:\bibliotheques\documents\visual studio 2013\projects\particlefuzzer\launcher\constants.h(45): error C3861: 'Quark': identifier not found
1>f:\bibliotheques\documents\visual studio 2013\projects\particlefuzzer\launcher\constants.h(45): error C2514: 'std::vector' : class has no constructors
1>f:\bibliotheques\documents\visual studio 2013\projects\particlefuzzer\launcher\constants.h(46): error C2663: 'std::vector<_Ty,_Alloc>::vector' : 8 overloads have no legal conversion for 'this' pointer
1>f:\bibliotheques\documents\visual studio 2013\projects\particlefuzzer\launcher\constants.h(50): error C2065: 'Quark' : undeclared identifier
1>f:\bibliotheques\documents\visual studio 2013\projects\particlefuzzer\launcher\constants.h(50): error C2923: 'std::vector' : 'Quark' is not a valid template type argument for parameter '_Ty'
1>f:\bibliotheques\documents\visual studio 2013\projects\particlefuzzer\launcher\constants.h(50): error C3861: 'Quark': identifier not found
1>f:\bibliotheques\documents\visual studio 2013\projects\particlefuzzer\launcher\constants.h(50): error C2514: 'std::vector' : class has no constructors
1>f:\bibliotheques\documents\visual studio 2013\projects\particlefuzzer\launcher\constants.h(51): error C2663: 'std::vector<_Ty,_Alloc>::vector' : 8 overloads have no legal conversion for 'this' pointer

Here the crashing code: constants.h

#pragma once
#include "stdafx.h"
#include <vector>
#include "Particle.h"

class constants
{
public:

    static enum nucl
    {
        proton = 0
        ,neutron = 1
    };

    static std::vector<Quark> getNuclVal(nucl type)
    {
        if (type == nucl::proton)
        {
            std::vector<Quark> result({ Quark(std::string("up")), Quark(std::string("up")), Quark(std::string("down")) });
            return result;
        }
        else
        {
            std::vector<Quark> result({ Quark(std::string("up")), Quark(std::string("down")), Quark(std::string("down")) });
            return result;
        }
    };
// More functions and constants
};

Particle.h

#pragma once
#include <vector>
#include "Entity.h"
#include "constants.h"

class Particle : public Entity
{
private:
// some stuff
public:
// some stuff
};

class Quark : public Particle
{
public:
    Quark(std::string &const);
};

and there is my Quark class definition in Particle.cpp

#include "stdafx.h"
#include "Particle.h"
#include "constants.h" 
#include <string>
#include "Entity.h"

Particle::Particle(std::string &const name, Size size)
: Entity::Entity()
, m_charge(0) //en e
, m_mass(0) //en electron Volt (eV)/c²
, m_Size(size)
, m_name(name)
{
};

Quark::Quark(std::string &const name) // declaration stuff
    : Particle(name, Size::Sub_Atomic)
{
    constants::quark type = constants::getQuarkByName(m_name);
    setMass(constants::getMass(type));
    setCharge(constants::getCharge(type));

}

// various stuffs

There is my precompiled header which include every sources I need in my program (to let you see compilation order) stdafx.h

#pragma once

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>
#include <vector>
#include <iostream>
#include <cstdlib>
#include <string>


// TODO: reference additional headers your program requires here
#include "Math.h"

#include "SciNumber.h"
#include "PhyEngine.h"
#include "Options.h"
#include "ConfigFile.h"
#include "Chameleon.h"
#include "Entity.h"
#include "Particle.h"
#include "constants.h"

I wonder if I need to separate my derived classes of Particle to specific files or not (It would add a lot of files..... T-T), what do you think about it?

here is my class diagram (open with Visual studio) to help you visualize the whole project: download it here via my dropbox

4
  • 4
    You have a circular include dependency. constants.h includes Particle.h which includes constants.h. Commented Apr 16, 2015 at 20:43
  • It simply means, that you created circular dependency. If you have such problems now (you "project" doesn't look like a big one for now) - good luck. Design comes first, then goes coding, not the other way. Commented Apr 16, 2015 at 20:56
  • "crash" refers to runtime failures, not compilation errors Commented Apr 16, 2015 at 21:04
  • What is in Entity.h? (no, I can't go to the site you linked to). Second, why does Particle.h require an include of constants.h? I see no use of anything in constants.h in the Particle.h file. Commented Apr 16, 2015 at 21:05

2 Answers 2

3

You have a circular dependency in your headers. Particle.h includes constants.h and constants.h includes Particle.h. You'll need break the loop.

You get the error because when Particle.h is included, it'll at first include constants.h. Then constants.h will try to include Particle.h. #pragma once will prevent infinite recursion, but also means that rest of the Particle.h is not yet included before the contents of the constants.h. Thus the compiler complains about missing declarations.

You should be able to break the loop by breaking your headers and possibly classes into smaller ones*. The static member functions of constants are not strictly related to each other, are they? In fact, from what I've seen, it should probably be a namespace rather than a class**. Stuff in namespace can be conviniently declared in separate headers while a class must be defined entirely in one.

*Assuming you actually need to. If Particle.h doesn't depend on constants.h, then simply remove the include.

**I may be wrong about that since you didn't show the entire class.

Break off the part of constants that depends on Quark (and anything that depends on anything that depends on Quark, recursively) into another class in another header and don't include that one inside Particle.h. Or break off parts of Particle.h that depend on constants.h and don't include that one in constants.h.

stdafx.h also includes constants.h which in turn includes stdafx.h. You'll need to fix all circular includes.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks ! really! :D I cleaned my include tokens, changed constants from class to namespace and moved his needed methods into particles.h. :D After some corrections and adaptations, it compile great and works again! Really thanks a lot! ^^
0

Try moving

#include "constants.h"

to the bottom of Particle.h. What currently happens is that Particle.h goes through constants.h before it has declared the types.

constants.h is not re-including particle.h because of pragma #once (without which you would have circular dependencies and nothing would work anyway).

You also don't need the #include "constants.h" in stdafx.h as it is already included in Particle.h

I hope this helps!

3 Comments

It's not a solution. The only solution is to remove circular dependency. Also, headers included in pre-compiled header should not have any dependencies or be dependent in a the same order they are included.
Yes, getting rid of the circular dependency is the best way. However, assuming that pragma #once works the same way as traditional header guards, this is not the problem here. Regarding the includes in stdafx.h I am merely pointing out that it is not necessary not wrong
Yep, that is true. Good design is definitely different.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.