undeclared identifier - c++

Need a second set of eyes. I am getting the following error:
1>c:\users\thom\documents\cworkspace\barnaby\barnaby\timezone.h(15): error C2065: 'TransitionTimeInfo' : undeclared identifier
Here is the line of code on which I'm receiving the error:
Timezone(std::vector<LeapSecondsInfo> &leapSecondsVector, std::vector<unsigned char> &localTimeTypes, std::vector<P6::UINT8> &stdWallIndicators, &std::vector<unsigned long> &transitionTimes, std::vector<TransitionTimeInfo> &transitionTimesInfo, std::vector<P6::UINT8> &utcLocalIndicators){
This is the line for the constructor for my class. This file has the following include:
#include "stdafx.h"
And here is the salient part of the stdafx.h:
#include "targetver.h"
#include "barnaby.h"
#include "LeapSecondsInfo.h"
#include "p6types.h"
#include "Timezone.h"
#include "TransitionTimeInfo.h"
And here is TransitionTimeInfo.h:
class TransitionTimeInfo
{
public:
TransitionTimeInfo(long gmtOffset, bool daylightSavings, unsigned int abbreviationIndex){
setAbbreviationIndex(abbreviationIndex);
setDaylightSavings(daylightSavings);
setGmtOffset(gmtOffset);
}
virtual ~TransitionTimeInfo(void) {};
unsigned int getAbbreviationIndex(){
return abbreviationIndex;
}
void setAbbreviationIndex(unsigned int newVal){
abbreviationIndex = newVal;
}
bool isDaylightSavings(){
return daylightSavings;
}
void setDaylightSavings(bool newVal){
daylightSavings = newVal;
}
long getGmtOffset(){
return gmtOffset;
}
void setGmtOffset(long newVal){
gmtOffset = newVal;
}
private:
long gmtOffset;
bool daylightSavings;
unsigned int abbreviationIndex;
};
What's more, if I click on the type name and hit F12 (Visual C++) it takes me to this file.
Any ideas?
Thanks.

Change the order of includes:
#include "TransitionTimeInfo.h"
#include "Timezone.h"
The Timezone.h uses TransitionTimeInfo but the "TransitionTimeInfo.h" is included after it.
Ideally, You should always follow the rule:
Each file should include all the header files it needs and not rely on them getting included indirectly through some other files.
So, You should include "TransitionTimeInfo.h" in "Timezone.h".

Related

Why the compiler is generating errors which aren't errors at all

I was trying to write my own VM implementation in C++ from the excellent book Crafting Interpreters.
The book builds a stack based virtual machine, of which I am writing a C++ version
So here is the code where the compiler is yelling at me.
object.h
#pragma once
#include "common.h"
#include "value.h"
#include "chunk.h"
#define OBJ_TYPE(value) (AS_OBJ(value)->type)
#define IS_CLOSURE(value) isObjType(value, OBJ_CLOSURE)
#define IS_FUNCTION(value) isObjType(value, OBJ_FUNCTION)
#define IS_NATIVE(value) isObjType(value, OBJ_NATIVE)
#define IS_STRING(value) isObjType(value, OBJ_STRING)
#define AS_CLOSURE(value) ((ObjClosure*)AS_OBJ(value))
#define AS_FUNCTION(value) ((ObjFunction*)AS_OBJ(value))
#define AS_NATIVE(value) (((ObjNative*)AS_OBJ(value))->function)
#define AS_STRING(value) ((ObjString*)AS_OBJ(value))
#define AS_CSTRING(value) (((ObjString*)AS_OBJ(value))->chars)
typedef enum {
OBJ_CLOSURE,
OBJ_FUNCTION,
OBJ_NATIVE,
OBJ_STRING,
OBJ_UPVALUE
} ObjType;
struct Obj {
ObjType type;
Obj* next;
};
struct ObjString :Obj {
int length;
char* chars;
uint32_t hash;
};
struct ObjFunction :Obj {
int arity;
int upvalueCount;
Chunk chunk;
ObjString* name;
};
struct ObjUpvalue :Obj {
Value* location;
};
struct ObjClosure :Obj {
ObjFunction* function;
ObjUpvalue** upvalues;
int upvalueCount;
};
typedef Value(*NativeFn)(int, Value*);
struct ObjNative :Obj {
NativeFn function;
};
ObjUpvalue* newUpvalue(Value* slot);
ObjClosure* newClosure(ObjFunction* function);
ObjFunction* newFunction();
ObjNative* newNative(NativeFn function);
ObjString* takeString(char* chars, int length);
ObjString* copyString(const char* chars, int length);
void printObject(Value value);
static inline bool isObjType(Value value, ObjType type) {
return IS_OBJ(value) && AS_OBJ(value)->type == type;
}
common.h
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#define DEBUG_PRINT_CODE
#define DEBUG_TRACE_EXECUTION
#define UINT8_COUNT (UINT8_MAX + 1)
value.h
#pragma once
#include "common.h"
#include "object.h"
typedef enum {
VAL_BOOL,
VAL_NIL,
VAL_NUMBER,
VAL_OBJ
} ValueType;
#define IS_BOOL(value) ((value).type == VAL_BOOL)
#define IS_NIL(value) ((value).type == VAL_NIL)
#define IS_NUMBER(value) ((value).type == VAL_NUMBER)
#define IS_OBJ(value) ((value).type == VAL_OBJ)
#define AS_OBJ(value) ((value).as.obj)
#define AS_BOOL(value) ((value).as.boolean)
#define AS_NUMBER(value) ((value).as.number)
#define BOOL_VAL(value) (Value {.type = VAL_BOOL, .as = {.boolean = value}})
#define NIL_VAL (Value {.type = VAL_NIL, .as = {.number = 0}})
#define NUMBER_VAL(value) (Value {.type = VAL_NUMBER, .as = {.number = value}})
#define OBJ_VAL(object) (Value {.type = VAL_OBJ, .as = {.obj = (Obj*)object}})
struct Value {
ValueType type;
union {
bool boolean;
double number;
Obj* obj;
} as;
bool operator==(Value b);
};
struct ValueArray {
int count;
int capacity;
Value* values;
ValueArray();
~ValueArray();
void write(Value value);
};
void printValue(Value value);
void freeValueArray(ValueArray* array);
chunk.h
#pragma once
#include "common.h"
#include "value.h"
typedef enum {
OP_CONSTANT,
OP_NIL,
OP_TRUE,
OP_FALSE,
OP_POP,
OP_GET_LOCAL,
OP_SET_LOCAL,
OP_GET_GLOBAL,
OP_DEFINE_GLOBAL,
OP_SET_GLOBAL,
OP_GET_UPVALUE,
OP_SET_UPVALUE,
OP_EQUAL,
OP_GREATER,
OP_LESS,
OP_NEGATE,
OP_ADD,
OP_SUBTRACT,
OP_MULTIPLY,
OP_DIVIDE,
OP_NOT,
OP_PRINT,
OP_JUMP,
OP_JUMP_IF_FALSE,
OP_LOOP,
OP_CALL,
OP_CLOSURE,
OP_CLOSE_UPVALUE,
OP_RETURN
} OpCode;
struct Chunk {
int count;
int capacity;
uint8_t* code;
int* lines;
ValueArray constants;
Chunk();
~Chunk();
void write(uint8_t byte, int line);
int addConstant(Value value);
};
When compiling these files along with some other files, I got the following error message
Build started...
1>------ Build started: Project: Clox, Configuration: Debug x64 ------
1>chunk.cpp
1>D:\Ankit\Programming\C++\Clox\object.h(45,8): error C3646: 'chunk': unknown override specifier
1>D:\Ankit\Programming\C++\Clox\object.h(45,13): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>D:\Ankit\Programming\C++\Clox\object.h(51,7): error C2143: syntax error: missing ';' before '*'
1>D:\Ankit\Programming\C++\Clox\object.h(51,7): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>D:\Ankit\Programming\C++\Clox\object.h(51,17): error C2238: unexpected token(s) preceding ';'
1>D:\Ankit\Programming\C++\Clox\object.h(61,15): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>D:\Ankit\Programming\C++\Clox\object.h(61,16): error C2065: 'NativeFn': undeclared identifier
1>D:\Ankit\Programming\C++\Clox\object.h(61,24): error C2513: 'int': no variable declared before '='
1>D:\Ankit\Programming\C++\Clox\object.h(61,24): fatal error C1903: unable to recover from previous error(s); stopping compilation
1>INTERNAL COMPILER ERROR in 'C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\bin\HostX64\x64\CL.exe'
1> Please choose the Technical Support command on the Visual C++
1> Help menu, or open the Technical Support help file for more information
1>Done building project "Clox.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I can't understand why these errors are coming out.
You have a cycle in your include files.
object.h => chunk.h => value.h => object.h
So you are getting to a declaration were not all the other types have defined (because #pragma once have prevented the includes happening recursively).
You need to break the cycle by using forward declarations in one of these files and removing a #include.
It's hard to reproduce the problem without all the files. But I think this can be solved with the following change (in value.h)
1: Remove this include:
#pragma once
#include "common.h"
// -> Remove this line #include "object.h"
2: Add a forward declaration:
struct Obj; // Forward declare the class Obj
struct Value {
ValueType type;
union {
bool boolean;
double number;
Obj* obj;
} as;
bool operator==(Value b);
};
The general rule of including from a header file are:
Be judicious, only include what you need.
If you don't need the full type information, forward declare rather than include.
i.e. If you only use a pointer then forward declare the class.
This will probably mean that the source file will need an extra include line but that's OK as you normally don't include source file you don't end up with cycles.
Side-Note there are a couple of other odd things you are doing.
Putting typedef in-front of all your structures.
`typedef struct Value { /* STUFF */} Value;
This is C code and not needed in C++. You can simply do:
`struct Value { /* STUFF */};
and have the same effect.
Don't use macros when normal function's can be used.
// There is no type checking here.
// This is literally text replacement and can go wrong so easily.
#define IS_BOOL(value) ((value).type == VAL_BOOL)
// This is type checked.
// Will more than likely be inclined by the compiler so is
// no more expensive.
inline bool isBool(Value const& value) {return value.type == VA_BOOL;}
Don't use macros when const expression can be used.
#define UINT8_COUNT (UINT8_MAX + 1)
static constexpr std::uint8_t UINT8_COUNT = (UINT8_MAX + 1);
More macro magic that is not correctly type checked:
#define BOOL_VAL(value) (Value {.type = VAL_BOOL, .as = {.boolean = value}})
In this case a proper set of constructors will solve this problem. And you don't need to rely on putting the correct macro in place the compiler will check the types and assign use the correct value.
Don't create your own array types:
struct ValueArray {
int count;
int capacity;
Value* values;
ValueArray();
~ValueArray();
void write(Value value);
};
The standard has some good alternatives already defined and that work very efficiently (std::vector<> or std::array<> and a few others).

trying to use struct on aheader file and includeed it in the main and the class file

i used struct in aheader file and i included it in the main.cpp and in the class.h and it's cpp but i got some errors the errors are
Error 1 error C2511: 'void fkingatm::test1(user [])' : overloaded member function not found in 'fkingatm'
Error 2 error C3861: 'test1': identifier not found
Error 3 IntelliSense: identifier "test1" is undefined
STRUCT_HEADER.h
#ifndef STRUCT_HEADER
#define STRUCT_HEADER
struct user {
int arr[10];
};
#endif
main.cpp
#include "STRUCTHEADER.h"
int main(){
user users[10];
test1(users);
fkingatm.h (the class file)
#ifndef FKINGATM_H
#define FKINGATM_H
#include "STRUCTHEADER.h"
class fkingatm
{
public:
void test1(user);
};
#endif
fkingatm.cpp
#include "fkingatm.h"
void fkingatm::test1(user users[10]){
for (int i = 0; i < 10; i++){
cin >> users[0].arr[i];
}
for (int i = 0; i < 10; i++){
cout<< users[0].arr[i]<<endl;
}
}
Your main.cpp evaluates as: (Assuming STRUCT_HEADER isn't #defined before STRUCT_HEADER.h and that you just misspelled your STRUCTHEADER.h in this question )
struct user {
int arr[10];
};
int main(){
user users[10];
test1(users);
Since #include only pastes whatever the contents of the file you put in front of it on the line it's written on. It won't see your definition of test1.
You should try:
#include "fkingatm.h"
#include "STRUCTHEADER.h"
int main(){
user users[10];
fkingatm f;
f.test1(users);
return 0;
}
Now, that solves the 2nd and 3rd Error you had. For the 1st error, you will need to edit the declaration of your void
void test1(user);
to
void test1(user[10]);
edit:
That is because you're using your test1(user user[10]) as one that takes a user[10] and not a user. And user[10] is different type and data on its own. Different data in the sense that user[10] is actually a pointer(a number that represents a memory address) and user is a class/struct(Which is only a namespace and doesn't really have an exact physical representation in memory).

ERROR C2143: Syntax error: missing ';' before '<' C++

I am having trouble in my C++ code where I have to make a binary heap. It works fine as long as I had the "main" function inside of my "MyHeap.h" file but my professor wants it to run in a separate test file. For some reason the code doesn't want to run whenever I try to put the main function outside of the "MyHeap.h" file. When it runs I get the following error:
error C2143: syntax error: missing';' before '<'
I looked at my code and this is where it says there is an error but I can't see anything.
// MyHeap.h
#ifndef _MYHEAP_H
#define _MYHEAP_H
#include <vector>
#include <iterator>
#include <iostream>
class Heap {
public:
Heap();
~Heap();
void insert(int element);
int deletemax();
void print();
int size() { return heap.size(); }
private:
int left(int parent);
int right(int parent);
int parent(int child);
void heapifyup(int index);
void heapifydown(int index);
private:
vector<int> heap;
};
#endif // _MYHEAP_H
So like I said whenever I have the the int main function right after the private class, it will work just fine. Now when I implement it into my test file which is this:
#include "MyHeap.h"
#include <vector>
#include <iostream>
int main()
{
// Create the heap
Heap* myheap = new Heap();
myheap->insert(25);
myheap->print();
myheap->insert(75);
myheap->print();
myheap->insert(100);
myheap->print();
myheap->deletemax();
myheap->print();
myheap->insert(500);
myheap->print();
return 0;
}
It keeps popping up the errors, any ideas on I could go about fixing this problem so that my code can run from a test file?
Use std::vector instead of vector.
The compiler is complaining it doesn't know about vector.
Since it lives in std namespace, the safest solution is to prefix with std.

unable to initialize Static const string

I have a class "GameOverState" which has a private member
static const std::string s_gameOverID;
In GameOverState.cpp I am initialising as :
const std::string GameOverState::s_gameOverID = "GAMEOVER";
I am getting the following errors:
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2440: 'initializing' : cannot convert from 'const char [9]' to 'int'
error C2377: 'std::string' : redefinition; typedef cannot be overloaded with any other symbol
error C2373: 's_gameOverID' : redefinition; different type modifiers
error C2143: syntax error : missing ';' before 'GameOverState::s_gameOverID'
I have a PlayState class/PauseState class which have the same implementation which are working fine. How do I fix this bug??
GameOverState.h
#pragma once
#include "GameState.h"
#include "PlayState.h"
#include "MenuState.h"
#include "PauseState.h"
#include "AnimatedGraphic.h"
#include <string>
class GameObject;
class GameOverState : public GameState
{
public:
virtual void update();
virtual void render();
virtual bool onEnter();
virtual bool onExit();
virtual std::string getStateID() const { return s_gameOverID; }
private:
static void s_gameOverToMain();
static void s_restartPlay();
static const std::string s_gameOverID;
std::vector<GameObject*> m_gameObjects;
}
GameOverState.cpp
#include "GameOverState.h"
const std::string GameOverState::s_gameOverID = "GAMEOVER";
void GameOverState::s_gameOverToMain()
{
TheGame::Instance()->getStateMachine()->changeState(new MenuState());
}
void GameOverState::s_restartPlay()
{
TheGame::Instance()->getStateMachine()->changeState(new PlayState());
}
bool GameOverState::onEnter()
{
if (!TheTextureManager::Instance()->load("assets/gameover.png", "gameovertext", TheGame::Instance()->getRenderer()))
{
return false;
}
if (!TheTextureManager::Instance()->load("assets/main.png", "mainbutton", TheGame::Instance()->getRenderer()))
{
return false;
}
if (!TheTextureManager::Instance()->load("assets/restart.png", "restartbutton", TheGame::Instance()->getRenderer()))
{
return false;
}
GameObject* gameOverText = new AnimatedGraphic(new LoaderParams(200, 100, 190, 30, "gameovertext"), 2);
GameObject* button1 = new MenuButton(new LoaderParams(200, 200, 200, 80, "mainbutton"), s_gameOverToMain);
GameObject* button2 = new MenuButton(new LoaderParams(200, 300, 200, 80, "restartbutton"), s_restartPlay);
m_gameObjects.push_back(gameOverText);
m_gameObjects.push_back(button1);
m_gameObjects.push_back(button2);
std::cout << "entering PauseState\n";
return true;
}
You're missing the semicolon after the definition of GameOverState.
The preprocessor runs before compilation and basically just copy pastes the content of the header in the source file, altough we can't see that. An error resulting from a broken header can thus be pretty misleading.
It's legal to have class definitions inside a variable definition and the position of specifiers (like static) is not limited to the beginning of a declaration, either (for example, int const static x = 0; is fine).
So, your code looks like this to the compiler:
class GameOverState {} static const std::string GameOverState::s_gameOverID = "GAMEOVER";
Hopefully the errors make more sense now.
As everyone else has said, you're probably missing the #include line in your header if your other two classes are working fine. It's presuming and expecting an int, so that seems the case.
Make sure #include<string> is in your header

C2011: 'struct' type redefinition and C2027: use of undefined type

In a file named types.h, I have defined
struct entry {
entry( int a, int t ) : addr(a), time(t) {}
int addr;
int time;
};
In another file I want to use the struct like this in compress.h:
#include "types.h"
#include <vector>
class Compress {
public:
void insert( int a, int t )
{
theVec.clear();
for (int i = 0; i < 10; ++i)
theVec.push_back( entry(a, t) );
}
private:
std::vector< entry > theVec;
};
In the main file, I wrote
#include "compress.h"
int main()
{
Compress *com = new Compress;
com->insert(10, 100);
return 0;
}
However at the line of push_back, I get these errors
error C2011: 'entry' : 'struct' type redefinition
see declaration of 'entry'
error C2027: use of undefined type 'entry'
see declaration of 'entry'
How can I fix that?
In your types.h file you should have something like this:
#ifndef TYPES_H
#define TYPES_H
struct ...
#endif
This will prevent the compiler from parsing the include file mulitple times if you include it more than once, which would cause multiple definitions.
The name itself doesn't matter, but you should make sure that it is unique and not defined by some other include file as well.
You may want to check the include guard of types.h.
Try to have the file start with the line
#pragma once
// your declarations