forward declaration of struct DIR - c++

I somehow messed up the includes, but weren't able to actually find the error:
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef DEBUG
#define DLOG(x) printf(x)
#define PLOG(x,y) printf(x,y)
#else
#define DLOG(x)
#define PLOG(x,y)
#endif
harddrive::Results* harddrive::search_for(char* start,char* target,char** ignore,int size) {
PLOG("work directory: %s",start);
DIR* curr_dir = opendir(start);
Results* local = new Results;
if(!curr_dir) {
printf(" opendir() failure, probably no real directory: %s",start);
errno = 0;
return NULL;
}
struct dirent* elem;
while( (elem = readdir(curr_dir)) ) {
//form URI
char* uri = form_uri(start,curr_dir->d_name); //here is the actual error
struct stat st;
lstat(elem->d_name,&st);
if( S_ISDIR(st.st_mode) ) {
if( !do_ignore(uri,ignore,size) )
local = merge(local,search_for( form_uri(start,elem->d_name), target,ignore,size));
}
else if( S_ISREG(st.st_mode) ) { //this is line 41
Compiler output:
Directory.cpp: In function ‘harddrive::Results* harddrive::search_for(char*, char*, char**, int)’:
Directory.cpp:34:38: error: invalid use of incomplete type ‘struct DIR’
/usr/include/dirent.h:128:16: error: forward declaration of ‘struct DIR’
€:I am sorry for the inconvenience but i pasted an old error code, before I started switching around lines, but now it is correct.

curr_dir->d_name should be elem->d_name.
As the error says, you're incorrectly trying to dereference a pointer to the opaque type DIR.

DIR* is an opaque handle, you can't access its internals. You probably meant to access elem instead of curr_dir
i.e. change
form_uri(start,curr_dir->d_name);
to
form_uri(start,elem->d_name);

dirent.h says:
/* This is the data type of directory stream objects.
The actual structure is opaque to users. */
typedef struct __dirstream DIR;

Related

Why does this code give a 'expected primary-expression before ',' token' compile error?

I am getting the following error message stated in title when compiling and don't know what's wrong. I am trying to pass an array of structs into a function. It is failing with the following error:
Error message error: expected primary-expression before ',' token
gpio.h
#ifndef __GPIO_H__
#define __GPIO_H__
#include <stdint.h>
#include "settings.h"
int open(config *configureGpio, bool *result);
#endif
settings.h
#ifndef __SETTINGS_H__
#define __SETTINGS_H__
#include <stdint.h>
#define OUTPUT 1
#define INPUT 0
#define HIGH 1
#define LOW 0
struct config
{
int nPin;
bool bOut;
bool bIHigh;
};
config gpioConfig[4] =
{
{8, OUTPUT, LOW},
{4, INPUT, LOW},
{3, INPUT, LOW},
{2, INPUT, LOW}
};
#endif
gpio.cpp
#include "gpio.h"
int open(config *configureGpio, bool *res)
{
return 0;
}
main.cpp
#include "gpio.h"
#include "settings.h"
int main() {
bool res = false;
open(config, &res);
}
This line is wrong:
open(config, &res);
config is no variable but a type. You might want to use gpioConfig instead.
BTW:
I am not sure if open is a good function name as it might collide with this open function.
Also defining a global array in a header file isn't really good style.
You cannot pass a data-type as a parameter but pass the variables. Also when passing arrays be cautious about falling into the array decaying to pointer. So you should pass the size as a separate parameter.
So your code can look like this:
int open(config *configureGpio, const int size, bool *res){
for(int i(0); i < size; i++)
;// do something
return 0;
}

Can't pass shared pointer as parameter to function definition?

If I place a function declaration with a shared pointer as a parameter and its definition in the header, everything compiles fine, but attempting to separate them into a .hpp and .cpp file causes compilation errors like:
Use of undeclared identifier 'std' //Solved via including <memory> & <cstdint>
Variable has incomplete type 'void' //Solved via including <memory> & <cstdint>
Use of undeclared identifier 'uint8_t' //Solved via including <memory> & <cstdint>
For example:
For this main: main.cpp
#include <iostream>
#include "example1.hpp" //Switch out with "example2.hpp"
int main(int argc, const char * argv[]) {
std::shared_ptr<uint8_t> image = 0;
foo(image);
return 0;
}
This Works:
example1.hpp
#ifndef example1_hpp
#define example1_hpp
#include <stdio.h>
void foo(std::shared_ptr<uint8_t> variable) { }
#endif /* example1_hpp */
This does not work:
example2.cpp
#include "example2.hpp"
void foo(std::shared_ptr<uint8_t> variable) { }
example2.hpp
#ifndef example2_hpp
#define example2_hpp
#include <stdio.h>
void foo(std::shared_ptr<uint8_t> variable);
#endif /* example2_hpp */
How do I separate the declaration and definition for this function into separate files successfully?
You have wrong includes. <stdio.h> is a C header. To use shared_ptr you need to include <memory>, to use uint8_t you need to include <cstdint>.

C++: Accessing data of dynamic structures within extern function

I have a problem with passing dynamically allocated structures to a function and accessing it's content.
The program uses mex to pass data from Matlab to C++. I use Visual Studio.
The structure I define in a header in 'InOut.h'
#include <string>
#include <cstdint>
#include <cstdlib>
struct sObjects {
std::string Type;
float *Position;
};
typedef struct sObject sObject;
In the main function I than allocate the structure is in 'MainFcn_Mex.cpp'
#include "MainFcn_Mex.h"
// ...
// get number of Objects from Matlab
int N_Obj = mxGetNumberOfElements(prhs[1]);
sObjects *Objects = new sObjects[N_Obj];
for (int k=0; k<N_Obj; k++) {
// get the pointer pointer map
pMap = mxGetField(prhs[1],k,"Type");
Objects[k].Type = mxArrayToString(pMap);
// get the pointer pointer map
pMap = mxGetField(prhs[1],k,"Position");
// setting pointer to the first Element
Objects[k].Position = (float*)mxGetPr(pMap);
mexPrintf("Objects(%d,1).Type: %s \n", k+1, Objects[k].Type);
}
create_Objects(Objects, N_Obj);
The function create_Objects is in a differente file 'create_Objects.cpp' and included via 'MainFcn_Mex.h':
#include <stdio.h>
#include <direct.h>
#define _USE_MATH_DEFINES
#include "math.h"
#include <cmath>
#include "mex.h"
#include "matrix.h"
#include <cuda.h>
#include <cuda_runtime.h>
#include "device_launch_parameters.h"
#include "InOut.h"
void create_Objects(sObjects *Objects, int N_Obj);
The content of 'create_Objects.cpp' so far is:
#define _USE_MATH_DEFINES
#include "math.h"
#include <cmath>
#include "InOut.h"
#include "mex.h"
void create_Objects(sObjects *Objects, int N_Obj)
{
for (int k=0; k<N_Obj; k++) {
mexPrintf("Objects(%d,1).Type: %s \n", k+1, Objects[k].Type);
}
}
Visual Studio tells me:
"error C2676: binary '[' : 'sObjects' does not define this operator or
a conversion to a type acceptable to the predefined operator"
Why can I access the data in the main function and not in seccondary functions?
How can I access a dynamically allocated structure in other functions, when its size isn't known at compile time?
Thanks a lot for your time!
It looks like you are trying to use struct directly as a typedef. Simply add typedef to your struct definition, will turn it into a type.
Like this:
... #include "mex.h"
typedef struct sObjects {
std::string Type;
float *Position;
};
(Otherwise you should use the full struct keyword as in void create_OpticsObjects(struct sObjects &Objects, int N_Obj).)
Your function prototypes don't need the extern qualifier.
You don't need extern unless you want globals variables. You seem to want simply global structs or types in your example, so extern is not required.
Using extern for globals
What you could be referring to is an instance of your object (or a pointer to your object), and that can be made global by using extern. as in this excerpt from the header file:
... #include "mex.h"
typedef struct sObjects {
std::string Type;
float *Position;
};
extern sObjects *pointerToOnesObjects;
Then in ONE source file, you need to declare the 'real' variable as in (this is good to initialise it here):
sObjects *pointerToOnesObjects = NULL;
With this method your variable pointerToOnesObjects is now available globally (in all your source files that use the same header file).

C++ stat.h incomplete type and cannot be defined

I am having a very strange issue with stat.h
At the top of my code, I have declarations:
#include <sys\types.h>
#include <sys\stat.h>
And function prototype:
int FileSize(string szFileName);
Finally, the function itself is defined as follows:
int FileSize(string szFileName)
{
struct stat fileStat;
int err = stat( szFileName.c_str(), &fileStat );
if (0 != err) return 0;
return fileStat.st_size;
}
When I attempt to compile this code, I get the error:
divide.cpp: In function 'int FileSize(std::string)':
divide.cpp:216: error: aggregate 'stat fileStat' has incomplete type and cannot be defined
divide.cpp:217: error: invalid use of incomplete type 'struct stat'
divide.cpp:216: error: forward declaration of 'struct stat'
From this thread: How can I get a file's size in C?
I think this code should work and I cannot figure out why it does not compile. Can anybody spot what I am doing wrong?
Are your \'s supposed to be /'s or am I just confused about your environment?
UNIX MAN page:
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int stat(const char *restrict path, struct stat *restrict buf);
If you're on Windows (which I'm guessing you might be because of the \'s), then I can't help because I didn't even know that had stat.

Invalid use of incomplete type 'DIR'

I'm trying to compile this code, which works fine on Windows, on Linux (Code::Blocks):
/* Edit: Includes */
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <...>
/**/
/* === */
/* Function code */
DIR *dp;
dirent *ep;
string name_parent;
dp = opendir(somepath);
name_parent = dp->dd_name; //error
/**/
Since path names on Windows are not case sensitive, I can read a user input like "c://program files" and get the "correct" path "C:\Program Files*" (except for the asterisk - or "F://" -> "F:*"). I also use this variable to get a directory listing with absolute path values, since ep->d_name (after some readdir() of course) returns a path relative to somepath.
On Linux, I get a compiler error (for "dp->dd_name"):
error: invalid use of incomplete type 'DIR'
Did I forget something?
Or is there a logical error?
Edit: I've added the includes (that I'm already using) above.
/* Edit: Includes */
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <...>
/**/
/* === */
/* Function code */
DIR *dp;
dirent *ep;
string name_parent;
dp = opendir(somepath);
ep = readdir(dp);
name_parent = ep->d_name;
/**/
The variable d_name exists in the struct dirent which gives the name of the directory
You didn't declare the type of DIR! On Posix systems, you would have said,
#include <sys/types.h>
#include <dirent.h>
However, on Windows, you don't have these features. Instead, you could use the Windows API filesystem functions.
yes. you missed including header files.
dirent.h
The internal structure of a DIR is unspecified, so you should never rely on it and expect your code to be portable.
The glib source for Windows says this about DIR:
/*
* This is an internal data structure. Good programmers will not use it
* except as an argument to one of the functions below.
Apparently, the type DIR is not defined at the point you're trying to use it. Maybe you forgot an #include?
It is not about to forget including some headers or definition now I've faced this problem but not error it was warning.
My files.h;
class Files
{
public:
explicit Files(const char *p_path = 0);
~Files();
/* .... */
private:
std::string path;
}
My files.cpp;
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <sys/types.h> // I added this line with #Kerrek SB's advice but nothing changed
#include <dirent.h>
#include <files.h>
static DIR *p_dir = NULL;
static struct dirent *p_ent = NULL;
Files::Files(const char *p_path)
{
if (p_path == NULL)
{
std::cerr << "PATH is NULL" << std::endl;
exit(EXIT_FAILURE);
}
path = p_path;
p_dir = opendir(p_path);
if (p_dir == NULL)
{
std::cerr << "Cannot open " << path << std::endl;
exit(EXIT_FAILURE);
}
}
Files::~Files()
{
if (p_dir)
{
/* Here is my warning occuring in this line and the definition
line p_dir 'static DIR *p_dir = NULL' */
delete p_dir; // After changing this line with 'free(p_dir);' warnings gone.
p_dir = NULL;
}
}
The warning at the definition line (static DIR *p_dir = NULL;) is 'p_dir' has incomplete type and the warning at the delete line (delete p_dir;) is possible problem detected in invocation of delete operator: [-Wdelete-incomplete].
After changing the delete p_dir; with free(p_dir); the both warnings are gone.
I don't know it's exact reason but it sounds like DIR * type acting like void *. I'm just taking a wild guess.
Hope this helps.