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).
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 am getting flustrated with two errors and I have absolutely no idea what is wrong.
#ifndef ListElements
#define ListElements
#include "RentalObjects.h"
struct RentalList{
ObjectBase* content;
RentalList* Next;
};
#endif
All the time I get this error:
Error 1 error C2143: syntax error : missing ';' before '*'
Error 2 error C4430: missing type specifier - int assumed.
The RentalObjects.h file features a declaration of the ObjectBase class, which looks as follows:
class ObjectBase{
protected:
char Make[16];
char Model[16];
int Year;
float PricePerDay;
Booking* Availability;
public:
void SetMake(char* value);
void SetModel(char* value);
void SetYear(int value);
void SetPrice(float value);
bool DisposeBookings();
bool Book(int Start,int End);
char* GetMake();
char* GetModel();
int GetYear();
float GetPrice();
~ObjectBase();
};
I'd be grateful for a tip.
When declaring pointers or references, you don't need the whole class/struct definition.
Instead of:
#include "RentalObjects.h"
struct RentalList {
ObjectBase* content;
RentalList* Next;
};
you could do:
class ObjectBase;
struct RentalList {
ObjectBase* content;
RentalList* Next;
};
this could get you out of a circular include, which might be what's causing your broblem
main.c
#include "stackg.h"
int main()
{
return 0;
}
stackg.h
#ifndef STACKG_H
#define STACKG_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct stack_gt* stack_gt;
stack_gt stkg_init(
void* (*alloc)(const void* data, const int size),
void (*dealloc)(void* data),
void (*copy)(void* data_d, const void* data_s),
const int size
);
void stkg_free(stack_gt s);
int stkg_is_empty(stack_gt s);
int stkg_is_full(stack_gt s);
const int stkg_size(const stack_gt s);
void stkg_clear(stack_gt s);
int stkg_push(stack_gt s, const void* data);
int stkg_pop(stack_gt s, void* data);
int stkg_peek(stack_gt s, void* data);
#ifdef __cplusplus
}
#endif
#endif
The above program compiles successfully with the GCC compiler, but in MSVC2008 it gives the following error :
error C2040: 'stack_gt *' differs in levels of indirection from 'stack_gt'
What should I tell MSVC to make it compile the program without changing anything in the code?
Edit
Error occurs at line 8 of stackg.h :: typedef struct stack_gt* stack_gt;
Edit 2
If nothing else, I'll go with typedef struct _stack_gt* stack_gt;
The problem is that here:
typedef struct stack_gt* stack_gt;
you are giving stack_gt a different type, while this works fine:
typedef struct stack_gt* stack_gtB;
clang gives us a nicer error message:
error: typedef redefinition with different types ('struct stack_gt *' vs 'stack_gt')
This is covered in the draft C++ standard section 7.1.3 The typedef specifier paragraph 6:
In a given scope, a typedef specifier shall not be used to redefine the name of any type declared in that scope to refer to a different type. [ Example:
class complex { / ... / };
typedef int complex; // error: redefinition
—end example ]
Using the same name though is fine, so this would be ok:
typedef struct stack_gt stack_gt;
covered in paragraph 3:
In a given non-class scope, a typedef specifier can be used to redefine the name of any type declared in that scope to refer to the type to which it already refers. [ Example:
typedef struct s { / ... / } s;
typedef int I;
typedef int I;
typedef I I;
—end example ]
Another idea:
#ifdef __cplusplus
extern "C" {
typedef void * stack_gt
#else
typedef struct stack_gt* stack_gt;
#endif
This is ugly, but you don't need to rewrite any other part of the code, only this header included in C++ . It is only used as an opaque pointer in C++ anyways, and C doesn't notice.
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;
// ...
};
#pragma once
#include "LudoCore/Singleton.h"
class LudoTimer : public Singleton<LudoTimer>
{
friend class Singleton<LudoTimer>;
public:
void Update();
void ShortenDay();
void LengthenDay();
UINT64 GetDeltaTime() const;
float GetPercentageOfDayElapsed() const;
private:
LudoTimer();
~LudoTimer();
UINT64 GetTickCount64() const;
UINT64 GetElapsedSeconds() const;
UINT64 m_DeltaTime;
// Tick Count
UINT64 m_CurrFrameTick;
UINT64 m_LastFrameTick;
int m_SecondsInADay;
static const int SHORTEST_POSSIBLE_DAY = 60;
static const int LONGEST_POSSIBLE_DAY = 86400;
static const int CHANGING_INTERVAL = 600;
};
To me, the above code looks normal. However, I'm new to C++ so I may be missing some nuance. I'm getting a bunch of compiler errors from it, such as:
error C2447: '{' : missing function header (old-style formal list?)
and
error C2236: unexpected 'class'
'LudoTimer'. Did you forget a ';'?
What gives!
Have a look in the other header (LudoCore/Singleton.h). The second error implies that the error is before the class LudoTimer declaration at the top.
My guess is that Singleton.h defines a class, and there's a missing ';' after that class definition.
The error is probably in LudoCore/Singleton.h or something else included earlier. Make sure your class definitions have ; semicolons after them and all that.
Quick test: comment out the #include and stick a template<class C> class Singleton; predeclaration there instead. If the compiler now complains about incomplete types, I'm right, and if not, post more details.
Well, the following compiles fine for me, so the error is very likely not in the code you showed us. I suggest you have a second look at Mike's suggestion that there is an error in Singleton.h.
//#include "LudoCore/Singleton.h"
#include <windows.h>
template< typename T >
class Singleton {};
class LudoTimer : public Singleton<LudoTimer>
{
friend class Singleton<LudoTimer>;
public:
void Update();
void ShortenDay();
void LengthenDay();
UINT64 GetDeltaTime() const;
float GetPercentageOfDayElapsed() const;
private:
LudoTimer();
~LudoTimer();
UINT64 GetTickCount64() const;
UINT64 GetElapsedSeconds() const;
UINT64 m_DeltaTime;
// Tick Count
UINT64 m_CurrFrameTick;
UINT64 m_LastFrameTick;
int m_SecondsInADay;
static const int SHORTEST_POSSIBLE_DAY = 60;
static const int LONGEST_POSSIBLE_DAY = 86400;
static const int CHANGING_INTERVAL = 600;
};
I was wondering if LudoTimer is declared at the point that it is used by Singleton and if a forward declaration would help? I didn't need one in VisualStudio 2005 and like sbi I could compile the code by supplying a declaration of Singleton. If I added a simplistic implementation I could even do:
LudoTimer* timer = Singleton<LudoTimer>::instance();
One more thing:
error C2236: unexpected 'class' 'LudoTimer'. Did you forget a ';'?
You could try adding a semicolon on a blank line after the #include to answer this question. If it helps then you can show that there is a problem in the header file without needing to edit it.