I'm trying to write a singleton class to hold the state of inputs from the user (mouse/keyboard data). The SDL API returns keyboard data as Uint8 pointer array, however, why I try to create the Uint8 pointer, I get these errors at the line w/ the uint8:
error C2143: syntax error : missing ';' before '*'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
I've used Uint8 as a data type without defining it before, so I'm not sure what is causing the issue here. Here is my code:
class InputState {
public:
InputState()
{};
~InputState()
{};
static InputState *getInputState(void)
{
static InputState *state = new InputState();
return state;
};
public:
Uint8 *keys;
struct MouseState
{
int LeftButtonDown;
int RightButtonDown;
int MiddleButtonDown;
int x;
int y;
MouseState ()
{
LeftButtonDown = 0;
RightButtonDown = 0;
MiddleButtonDown = 0;
x = 0;
y = 0;
}
};
MouseState *mouseState;
};
The type Uint8 is a typedef that is defined in one of the SDL header. If you want to use it, you need to include the SDL.h header in your file.
// You need this include if you want to use SDL typedefs
#include <SDL.h>
class InputState {
public:
InputState()
{};
~InputState()
{};
// ...
public:
Uint8 *keys;
// ...
};
Related
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).
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
I have a mask in simulink that has an init argument field. The init argument in my case is a structure. Now I want to use this structure in the .ccp (to make a mex file).
void init()
{
mxArray *initarg = GetInitArg();
...
}
The GetInitArg() is :
#ifndef GET_INIT_ARG
#define GET_INIT_ARG
mxArray *GetInitArg() {
return rtsys->initArg;
}
#endif
When the initarg is an int, I can call it this way in the void init():
int arg = (int)mxGetPr(initarg)[0];
Now, how would I do if initarg is a Matlab structure?
EDIT
I tried using #remus answer.
My struct look like this :
typedef struct
{
const char *task;
aaa_type aaa;
bbb_type bbb;
ccc_type ccc;
} arg_t;
The struct aaa_type, bbb_type and ccc_type are defined like this :
typedef struct
{
double p1;
double p2;
double p3;
double p4;
double p5;
double p6;
} aaa_type;
I try to get the init arg like this :
void init()
{
mxArray *initarg = GetInitArg();
arg_t arg* = (arg_t*)mxGetPr(initarg);
...
}
But at the arg_t line i'm getting two compilation errors:
error C2143: syntax error : missing ';' before '*'
error C2059: syntax error : '='
The list of MEX functions related to accessing structures is below:
mxGetField
mxSetField
mxGetNumberOfFields
mxGetFieldNameByNumber
mxGetFieldNumber
mxGetFieldByNumber
mxSetFieldByNumber
If you have a 1x1 structure, here's how you'd get one of the values:
mxArray *field_name = mxGetField(initArg, 0, "field_name");
Note that the result is another mxArray. From there you want the usual mxGetPr() for double arrays, or other mxGet... for other datatypes.
See the MEX documentation section on C/C++ Matrix Library for API details on these functions: http://www.mathworks.com/help/matlab/cc-mx-matrix-library.html
If you have the structure definition then you could cast the parameter pointer to it (I haven't tested but it should work since the Matlab structure is a contiguous memory block). Let's say you define your structure somewhere in a .h file:
typedef struct {
double a;
double b;
} mystruct_t;
Then:
mystruct_t *arg = (mystruct_t*)mxGetPr(initarg);
And you can access its members:
if (arg->a == 1) // or whatever
i made a code but has errors and wan't able to solve them:-
the following errors are in one of mine header file(code shown below)
error C2143:syntax error : missing ';' before '*'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
Header file code:-
#ifndef _DEVICE_SOURCE_FICARD_HH
#define _DEVICE_SOURCE_FICARD_HH
#ifndef _FRAMED_SOURCE_HH
#include "FramedSource.hh"
#endif
#include <DeviceSource.hh>
typedef struct LtagBufferEntry
{
char *pBuffer;
struct LtagBufferEntry *pNext;
} LBufferEntry;
class FICardDeviceParameters {
public:
(RetEntry*)(*p_lm_lock_fn)( void *data ); //error at this line
void (*p_lm_unlock_fn)( void *data );
int nFICardFrameSize;
//%%% TO BE WRITTEN %%%
};
class DeviceSourceFICard: public DeviceSource {
public:
static DeviceSourceFICard* createNew(UsageEnvironment& env, FICardDeviceParameters fi_params,
DeviceParameters params);
protected:
DeviceSourceFICard(UsageEnvironment& env, FICardDeviceParameters fi_params, DeviceParameters params);
// called only by createNew(), or by subclass constructors
virtual ~DeviceSourceFICard();
private:
// redefined virtual functions:
virtual void doGetNextFrame();
private:
void deliverFrame();
private:
DeviceParameters fParams;
LBufferEntry *pData;
char * pRetData;
//int nFICardFrameSize;
FICardDeviceParameters fiParams;
};
#endif //_DEVICE_SOURCE_FICARD_HH
Defination of RetEntry:-
typedef struct tagRetBuffer
{
char *pBuffer;
int nDataLn;
} RetEntry;
void InitBufferHandling();
void TransferBuffer( void *pBuffer );
RetEntry *lm_lock_fn( void *data );
void lm_unlock_fn( void *data );
int initLm555Settings(void);
void play();
void afterPlaying(void*);
void init_play();
void StartRTPProcess(void);
How to fix them...
The problem is that the compiler does not know what RetEntry is in the expression:
(RetEntry*)(*p_lm_lock_fn)( void *data );
You must either include the header that provides the definition or else declare it in your current header. From the code below it seems to be a typedef to tagRetBuffer, so to declare it in the current translation unit you will need to declare the struct and the typedef:
struct tagRetBuffer;
typedef tagRetBuffer RetEntry;
Now, I would suggest that you avoid those typedef's altogether, in C++ the compiler will search for types if needed. You can just do:
struct RetEntry
{
char *pBuffer;
int nDataLn;
};
And then use RetEntry anywhere as if it was a typedef'ed name. Note that there are differences, but that in 99% of the cases you will not notice. And when you do notice it might even be to your advantage (for example, you cannot declare a typedef, so you need to declare the typedef'ed name and then redefine the typedef as per the first suggestion here).
I am getting a very confusing compiler error when building the following test code.
f:\data\sdks\smctc-1.00\examples\ik_pf\msvc\MarkerSampler.inl(16): error C2143: syntax error : missing ';' before 'MarkerSampler<MarkerT>::sample2'
f:\data\sdks\smctc-1.00\examples\ik_pf\msvc\MarkerSampler.inl(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
Note sample builds without error, but sample2 is causing the problem. The only difference being one explicitly details the return type without the use of a typedef and the other uses the typdef'ed version.
.h file
#pragma once
#ifndef __MARKERSAMPLER_H_INCLUDED__
#define __MARKERSAMPLER_H_INCLUDED__
#include <vector>
#include <string>
#include <qthread.h>
#include <Wm5Vector3.h>
#include "UtilityFunctions.h"
#include "Marker.h"
#include "MarkerSet.h"
template <class MarkerT>
class MarkerSampler : public QThread
{
typedef std::vector<MarkerT> MarkerVector ;
typedef MarkerSet<MarkerT> MarkerSetT ;
typedef std::vector<MarkerSetT> MarkerSetVector ;
public :
MarkerSampler(const std::string inputDataDirectory, const unsigned int nSamples, const unsigned int startFrame, const unsigned int nFramesToUse) :
inputDataDirectory_(inputDataDirectory), nSamples_(nSamples), startFrame_(startFrame), nFramesToUse_(nFramesToUse) {seed = -time(NULL) ;}
~MarkerSampler() {}
std::vector<MarkerSet<MarkerT> > sample(const double scaleFactor = 1.0, const double noiseSD = 0.0) ;
MarkerSetVector sample2(const double scaleFactor = 1.0, const double noiseSD = 0.0) ;
protected:
void run();
private:
int seed ;
const std::string inputDataDirectory_ ;
const unsigned int nSamples_ ;
const unsigned int startFrame_ ;
const unsigned int nFramesToUse_ ;
} ;
#include "MarkerSampler.inl"
#endif
.inl file
template <class MarkerT>
std::vector<MarkerSet<MarkerT> > MarkerSampler<MarkerT>::sample(const double scaleFactor, const double noiseSD)
{
....
}
template <class MarkerT>
MarkerSetVector MarkerSampler<MarkerT>::sample2(const double scaleFactor, const double noiseSD)
{
....
}
The missing ; part of that error is slightly misleading, the compiler actually just doesn't recognize the MarkerSetVector type. I think this is because it's typedef'd inside the MarkerSampler class.
If you explicitly state the scope of the typedef it should fix the error. Though (depending on your compiler at least) you may also need to add in the typename keyword, since MarkerSetVector is a dependant type. Here's a fixed example:
template <class MarkerT>
typename MarkerSampler< MarkerT >::MarkerSetVector MarkerSampler<MarkerT>::sample2(const double scaleFactor, const double noiseSD)
{
....
}