How to separate functions between .h and .c files - c++

I am attempting to separate my function prototypes and the actual implementantions between .h and .c files to make it easier to see what functions I have.
my compiler, visual studio, has removed the curly green underline from under the function prototypes in the header files implying it is seeing the implementations in the .c file, but when I try to compile it I get 100+ errors all saying stuff like "syntax error: missing ';' before '*'" or "syntax error: missing ')' before '*'" or "syntax error: missing '}' before '*'" both in the .h and .c files. They are mostly pointing to the parameters in the prototypes, but I could not go trough all to know for sure.
Is there some other special way to do this?
I tried:
Making them extern
Changing guards to a name i know for sure isnt already used
I do not know what else I can try.

The first thing you could try is posting your code so we can see it :-)
However, the error syntax error: missing ';' before ... almost always shows up because you have an unknown type, as per the following:
int main() {
NOTYPE *x;
return 0;
}
Since you're moving function prototypes into a header, it may be that they're using types that still exist in the C file. Those type declarations must exist before use, or you will get that error.
That (function prototypes with unknown types) is not the only reason that error occurs but I can almost guarantee it'll be a similar issue, trying the use a type not yet declared.
As per other information posted here, you can also get this problem with circular dependencies, such as with:
typedef struct { TWO *two; } ONE; // don't know anything about TWO here.
typedef struct { ONE *one; } TWO;
If the dependency was only one way, then you could just ensure the order of the two definitions was correct. With a circular dependency, you have to introduce an incomplete definition (really a declaration) to allow it to work:
typedef struct TWO; // declare that TWO exists.
typedef struct { TWO *two; } ONE; // define ONE, we know TWO exists.
typedef struct { ONE *one; } TWO; // define ONE, we know all about ONE.
Note that this only works if you declare a pointer to the incomplete type, you won't be able to do:
typedef struct TWO;
typedef struct { TWO two; } ONE;
because the definition of ONE requires a complete type.

I have figured out the error.
The problem was that I had a circular dependency with 2 structures and I tried to fix it by defining them both before implementing them, but that obviously did not work.
this was my code:
typedef struct A;
typedef struct B;
typedef struct {
B* blist;
}A;
typedef struct {
A* a_parent;
}B;
The following stackoverflow answer helped me fix my errors:
Resolve circular typedef dependency?

Related

C++ error: expected initialiser before 'class'

When I compile the program I am working on I get:
expected initializer before 'class'
error in my Class.h file. I looked up the error message on the internet, but couldn't find the exact error, although similar errors seem to be caused by missing semicolons but I don't see why I need one. This is the code the error points to, I have no other functions or classes before it.
class Account
{
public:
double dAccountBalance;
double dAccountChange(double dChange);
};
In the Class.cpp file the double dAccountChange(double dChange) function is defined. I don't think this is where the error is coming from but this is the code;
double Account::dAccountChange(double dChange)
{
dAccountBalance += dChange;
return 0.0;
}
When I change the code in Class.h to look like this,
;
class Account
{
public:
double dAccountBalance;
double dAccountChange(double dChange);
};
it doesn't generate an error message, but I can't work out why I need the semicolon before it as the only code I have before it are the following pre-processor lines.
#ifndef CLASS_H_INCLUDED
#define CLASS_H_INCLUDED
Any ideas on why the error is generated?
Most likely, in the header file you include immediately before class.h, you'll have something like:
class xyzzy {
int plugh;
}
without the closing semi-colon. That will make your code sequence:
class xyzzy {
int plugh;
}
class Account
{
public:
double dAccountBalance;
double dAccountChange(double dChange);
};
which is clearly invalid. Inserting a semi-colon in class.h before the first line will fix it, but it's clearly the wrong place to put it (since it means every header file you include immediately after that one would need a starting semicolon - also, it's part of the definition in the first header and should be there).
Now that may not be the exact code sequence but it will be something very similar, and the underlying reason will be a missing piece of text in the previous header.
You should go back and put it in the earlier include file.
For example, consider:
include1.h:
class xyzzy {
int plugh;
}
include2.h:
class twisty {
int little_passages;
};
main.cpp:
#include "include1.h"
#include "include2.h"
int main (void) {
return 0;
}
Compiling this produces:
include2.h:3: error: multiple types in one declaration
but placing the semicolon at the end of include1.h (or start of include2.h though we've already established that's not a good idea) will fix it.
The problem is in one of the other headers, one that you #include ahead of class.h.
If you show us the top of your main cpp file, it might give a clue.

Extern unnamed struct object definition

I got a global object of type "unnamed-struct" and i'm trying to define it. I don't want to pollute my global namespace with such useless type (it will be used only once).
Global.h
extern struct {
int x;
} A;
Is there any correct way to define such object?
I was trying this:
Global.cpp
struct {
int x;
} A = { 0 };
But VS2012 throws "error C2371: 'A' : redefinition; different basic types". Thanks.
One possible solution: create another file Global_A.cpp that does not include Global.h, and define A there. By the equivalent-definition rule this will be valid, as long as the anonymous struct definitions are equivalent.
This is still a bad idea, and most compilers will warn about it e.g. (gcc): warning: non-local variable `<anonymous struct> A' uses anonymous type.
There is no way to do just this simply because it would be error prone: some time in the future someone (probably even you) may want to modify this structure's definition and he might forget to do this in the header and source files accordingly. So you will have to invent a name for this structure and use its name the source file and leave its definition up to the header.
I don't know if this helps you, and this my first post... So take it easy.
I just ran into this issue and what I did was I added a function that manipulates the struct to the file that contained the anonymous struct. That way I can call that function from any file in my project, and it manipulates the values in the struct for me.
Here is an example:
header.c has this anonymous struct:
struct
{
char line1[80];
char line2[80];
char line3[80];
} header;
I want to manipulate those values in "interface.c" because I am making a command line interface in another file. My first instinct was to use an extern, but it seems like adding the following function to header.c is just as good or better (Some people discourage the use of externs when avoidable).
void changeHeaders(char *one, char *two, char *three);
void changeHeaders(char *one, char *two, char *three)
{
strcpy(header.line1, one);
printf("\nHeader 1: %s", header.line1);
strcpy(header.line2, two);
printf("\nHeader 2: %s", header.line2);
strcpy(header.line3, three);
printf("\nHeader 3: %s", header.line3);
}
Now as long as I include the prototype for that function I can manipulate those struct variables from any file by using that function. Hope that helps someone.

C++ undeclared identifier

I want to create a sea ​​battle game. I have two classes: Ship and Cell.
#pragma once
#include"stdafx.h"
#include"Globals.h"
#include<vector>
#include"MCell.h"
class Ship
{
private:
int lenght;
int oriantation;
vector<Cell*> cells;
vector<Cell*> aroundCells;
...
#pragma once
#include<vector>
#include"MShip.h"
class Cell
{
private:
bool haveShip;
bool selected;
bool around;
int x;
int y;
Ship* ship;
And i have got many error like those:
1>projects\seewar\seewar\mship.h(13): error C2065: 'Cell' : undeclared identifier
1>projects\seewar\seewar\mship.h(13): error C2059: syntax error : '>'
1>projects\seewar\seewar\mship.h(14): error C2065: 'Cell' : undeclared identifier
What's wrong with the code?
Well your problem lies that when you include MCell.h you include MShip.h which references Cell defined in MCell.h. However MShip.h refers to MCell.h which won't get included because of the pragma once. If the pragma once wasn't there then you'd get an inifinite loop that would stack overflow your compiler ...
Instead you could use a forward declaration.
ie remove the #include "MCell.h" from MShip.h and replace it with, simply, "class Cell;" All your circular references issues will this go away :)
Your header files depend on each other. However one of them will have to be read before the other. So you need to rewrite one of them (or both of them) to not depend on the other. You can do that by forward-declaring the classes instead of including the header file that defines them.
So in MShip.h you should put a declaration class Cell; instead of including MCell.h and/or vice versa.
You need to forward declare the classes.
Ship.h
class Cell; //forward declaration
class Ship
{
//....
};
Cell.h
class Ship; //forward declaration
class Cell
{
//....
};
and remove the circular inclusion. You don't need to include one header in another since you're not working with complete types, but pointers. Full class definition is required when you use concrete objects of the type. In the case of pointers, you don't.

C++ question... definition doesn't recognize vectors specified in declaration

I'm working on a class assignment that started small, so I had it all in one file. Now it's gotten bigger and I'm trying to separately compile main, functions, and classes (so all the classes are together in one .h and one .cpp) I have one class B, which is the parent of a lot of others and comes first in the file. One of its data members isn't working now that I'm using separate compilation, which is causing dozens of errors.
In .h
class A;
class B {
public:
B (){}
A* myptr;
void whatever();
vector<A*> myAs; //this one is the problem
};
In .cpp
void B::whatever() {
vector<A*> newvector; //no problem!
myptr = &something; //no problem!
for (vector<A*>::iterator iter = myAs.begin(); iter != myAs.end(); ++iter) {
//error!
}
}
I get errors: either "myAs was not declared in this scope" or "class B has no member myAs."
I've included < vector >, forward-declared class A as you see above, and I definitely remembered to include the .h at the top of the .cpp! Is there something about vectors or classes and separate compilation that I don't understand? This is in Xcode, BTW.
It's not just vector. It's std::vector because it is within the namespace called std. That's why the compiler moans. It doesn't know what vector<A*> means. Say std::vector<A*> instead.
Do not add using namespace std; now into the header because of this. It may be OK for the assignment to put it into the .cpp file to save typing if you wish. But it's a really bad idea to put such a line into a header: Because you don't know which files will need your header in future. The situation can quickly get out of hand as the amount of files including your header grows with time. The header should therefor include only the names and headers that it really needs so that it causes as little name conflicts as possible - whereas that using namespace std; line would make all names of std visible directly.

What does this error mean: "error: expected specifier-qualifier-list before 'type_name'"?

I've been working on the Cell processor and I'm trying to create a struct that will hold an spe_context_ptr_t, which will be used within the thread to launch an spe context and will also hold a pointer to something else that will be passed to the spu context from within the thread (currently I'm trying to just make it a generic pointer, but in actuality it will be a pointer to another structure I've defined). When I try and compile, I get the following error:
spu/../common.h:38: error: expected specifier-qualifier-list before 'spe_context_ptr_t'
// here is the offending line(s)
typedef struct _PTHREAD_BLOCK {
spe_context_ptr_t * context; // Error happens here
uintptr32_t args;
} PTHREAD_BLOCK;
The compiler doesn't know that spe_context_ptr_t is a type. Check that the appropriate typedef is in scope when this code is compiled. You may have forgotten to include the appropriate header file.
I had the same error message but the solution is different.
The compiler parses the file from top to bottom.
Make sure a struct is defined BEFORE using it into another:
typedef struct
{
char name[50];
wheel_t wheels[4]; //wrong, wheel_t is not defined yet
} car_t;
typedef struct
{
int weight;
} wheel_t;
For iPhone cocoa-touch projects:
I had this problem and thanks to Eric Farraro's comment, I was able to get it resolved. I was importing a class WSHelper.h in many of my other classes. But I also was importing some of those same classes in my WSHelper.h (circular like Eric said). So, to fix this I moved the imports from my WSHelper.h file to my WSHelper.m file as they weren't really needed in the .h file anyway.
I got it with an import loop:
---FILE B.h
#import "A.h"
#interface B{
A *a;
}
#end
---FILE A.h
#import "B.h"
#interface A{
}
#end
You have to name your struct like that:
typedef struct car_t {
char
wheel_t
} car_t;
I was able to sort this out using Gorgando's fix, but instead of moving imports away, I commented each out individually, built the app, then edited accordingly until I got rid of them.
this error basically comes when you use the object before using it.