Calling a function (linked in C) - c

I'm trying to call a function from a .h and another .c file
trying to call the function in a line like this:
image = getImage(filename,&dim);
I have defined image at the top of main function as,
QTnode* image;
from the struct
struct imgnode{
int numb; //number of the image
int dim; //dimension of the image
char filename[20]; //name of file
QTnode *qt;
Imgnode *next;
Imgnode *prev;
};
the function is in another .h called
QTnode *getImage(char *filename, int *dim );
but the compiler tells me filename is undeclared. Any help?

LOL i helped my friend working on this yesterday. COMP1917 assignment hmm?
you are supposed to pass in the filename you read from the stdin rather than the filename in the struct in this assignment
Back to C, defining a structure doesn't mean that you have that structure and have those members inside the structure. You still declare and create a structure instance by doing this:
struct imgnode node;
then you can access the member by doing this:
node.filename
or more commonly:
struct imgnode* nodePtr;
nodePtr->filename

image = getImage(filename,&dim);
// ^^^^^^^^ Check where this variable declared.
// If declared check whether it is accessible from this scope.
Compiler don't know what the variable filename being passed an argument in the current translation unit. filename should be some where declared and should be accessible at the point of the function call. Check it.
If you are trying to access the struct members then you should have instance to access them.
image = getImage(strucInstance.filename,&(strucInstance.dim) );

What you usually do is something like this
So you have a function defined in foo.c as
void foo()
{
/* do nothing */
}
You put this line in a header file - guarded by include guards
void foo();
Now you include that header file in your other c file and the function should be able to resolve at compile time

Related

Access value of struct data member from other file

I have a data member in computer.h called "status" that I calculate a value for in computer.c. I would like to access this exact value and print it in a different file called display.c.
The problem is I'm not exactly sure how I can access that variable. I'm not allowed to change the parameters of display_status() and I'm assuming creating a new computer_data struct to access the status member in that function will just create a new local variable and won't work.
I'm not exactly sure how I can access the value of computer_data->status in display.c and would appreciate any help. Would I create a getter function for status specifically or something?
computer.h
struct computer_data {
struct param *status;
}
computer.c
static void computer_assign_status(){
struct computer_data *computer = computer_get_data();
computer->status = calculateStat();
}
display.c
#include "computer.h"
void display_status(){
struct computer_data *computer = computer_get_data();
printf("computer->status: %d /n", computer->status);
}
Note: Also computer_get_data() as a function is defined as "struct computer_data *computer_get_data()"
Using a get function is a good start. You just have to make it known in the other file.
In computer.h add a declaration:
struct computer_data {
struct param *status;
}
struct computer_data *computer_get_data(void);
Then you can use it in display.c.
But, of course for printing status you cannot use %d format specifier as it is a pointer to a struct.
Also in computer.c you have an error:
struct void computer_assign_status(){
That should just be void as return type.
Would I create a getter function for status specifically or something?
This totally depends on your needs. If you want to hide everything else that might be in that struct from a caller, then you might provide a function only returning pointer to the status part. Otherwise you can just do it as now where you return pointer to whole data struct.
None of your examples accesses any data defined in another compilation unit. BTW your examples are written sloppy: as an example struct void. Put some more effort when asking questions here
You can only access global (more precisely static storage with external linkage) variables defined in other compilation units.
in computer.h
struct computer_data {
struct param *status;
}
extern struct computer_data computer;
in computer.c
#include "computer.h"
struct computer_data computer;
void computer_assign_status(void)
{
computer.status = calculateStat();
}
in display.c
#include "computer.h"
void display_status()
{
printf("computer->status: %d /n", computer.status);
}
In display.c do:
extern struct computer_data * computer = computer_get_data()
instead.
This works because with the extern keyword the compiler you're using will be forced to look for the variable in an external file.

Returning a struct and passing a struct to functions

I am trying to return a struct which is defined as below:
EXAMPLE.C
struct test
{
int x;
int y;
int z;
};
struct test t1,t2;
I don't even have to explain the function, because I am getting error while declaring the function in the header file.
EXAMPLE.H
test calculate(int percent,int distance);
int modify(struct test x1);
So I will return the struct t1 in the function calculate and i will pass the struct t2 into the function modify. I am not sure what am I doing wrong, but I am getting syntax error
Firstly, your struct type is called struct test. Not just test, but struct test. Two words. You used the proper type name in your modify function. You used the proper type name in the declaration of t1 and t2. Why did you suddenly shorten it to a mere test in case of calculate?
Secondly, it appears that you are trying to use a yet-undeclared struct type in your function declarations, since the functions are declared in .h file and struct type is declared in .c file. Something like this can be done properly, but this is generally not a good idea (unless you are trying to implement an opaque type). And most likely this is not what you are trying to do. So, why are you declaring your struct type in .c file? A better idea would be to declare it in .h file as well, above your functions.

Structs: what should go a header and what should go in the source?

If I have a source file mystruct.c and a corresponding header file, what is the proper way to define it in each file?
assume I have a structure:
typedef struct my_struct {
int a;
} MyStruct;
should it be placed like this in the header? or should it look more like this:
source file:
struct my_struct {
int a;
};
header file:
typedef struct my_struct MyStruct;
I have the same question about enums and unions.
Im basically looking for the standard way of defining these things so that they can be used in many other files without having to worry about redefinition errors.
Defining the contents of your struct in the .c file and just declaring the struct to exist in the header means that you need to provide a function to create the struct, e.g.
rc = my_struct_create(&s);
It has the advantage that you can change the contents of your struct without having to recompile dependent code - this is because the struct is opaque, the only way to create it is with your function and the only way to access any members of the struct will be through functions you define.
I'd personally recommend that approach for library code. Otherwise it really depends on what you're trying to achieve.
In the .h file, you would put the structure definition, and the function prototypes:
point.h
typedef struct {
int x, y;
} point;
point *initpt(int, int);
In the .c file, you would implement the functions:
point.c
point *initpt(int x, int y)
{
point *p;
p->x = x;
p->y = y;
return p;
}
It depends if the structure members are part of the public API or not. If the users of the API are not supposed to access the structure members, leave the structure definition to the .c file only. If they are supposed to know the implementation of the structure (for example because you want to allow them to access the members of the structure) put the structure definition in the .h. By principle be more restrictive first, and then if you have too, you can still change it later.

Using static on typedef struct

I use the following code a lot in C:
typedef struct
{
int member;
} structname;
Now i'm trying to keep that struct definition local to a particular source file, so that no other source file even knows the struct exists. I tried the following:
static typedef struct
{
int member;
} structname;
but GCC whines because of an illegal access specifier. Is it even possible to keep a struct's declaration private to a source file?
If you declare the typedef struct within a .c file, it will be private for that source file.
If you declare this typedef in a .h file, it will be accesible for all the .c files that include this header file.
Your statement:
static typedef struct
Is clearly illegal since you are neither declaring a variable nor defining a new type.
All declarations are always local to a particular translation unit in C. That's why you need to include headers in all source files that intend to use a given declaration.
If you want to restrict the use of your struct, either declare it in the file in which you use it, or create a special header that only your file includes.
A structure definition is private to a source file unless placed in a shared header file. No other source file can access the members of the struct, even if given a pointer to the struct (since the layout is not known in the other compilation unit).
If the struct needs to be used elsewhere, it must be used only as a pointer. Put a forward declaration of the form struct structname; typedef struct structname structname; in the headerfile, and use structname * everywhere else in your codebase. Then, since the structure members appear only in one source file, the structure's contents are effectively 'private' to that file.
Hernan Velasquez's answer is the correct answer: there are several problems with your code snippet. Here's a counter-example:
/* This should go in a .h if you will use this typedef in multiple .c files */
typedef struct {
int a;
char b[8];
} mystructdef;
int
main (int argc, char *argv[])
{
/* "static" is legal when you define the variable ...
... but *not* when you declare the typedef */
static mystructdef ms;

"parameter has incomplete type" warning

I have this in a C file:
struct T
{
int foo;
};
the C file has an include to an h file with those lines:
typedef struct T T;
void listInsertFirst(T data, int key, LinkedList* ListToInsertTo);
the function listInsertFirst is the one I'm getting the warning on. How can I fix it?
As we've found out in the comments, the problem was that the definition of struct T occurred after the definition of T in the header. You really have things backwards here. The header should be defining all the types and function prototypes and your C files should be using them.
What you want to be doing instead is change the signature of your insert function to receive a pointer to your data and the size of the data. Then you can allocate some memory for the data, copy it and store it. You don't need a specific type, just declare it a void *.
void listInsertFirst(void *data, size_t data_size, int key, LinkedList* ListToInsertTo);
Then the caller would do something like this:
struct T { int foo; };
struct T x = { ... };
int someKey = ...;
LinkedList *someList = ...;
listInsertFirst(&x, sizeof x, someKey, someList);
When you include the header file, the compiler knows that T is a structure of unknown size and that listInsertFirst wants one as its first argument. But the compiler cannot arrange a call to listInsertFirst as it doesn't know how many bytes to push on the stack for the T data parameter, the size of T is only known inside the file where listInsertFirst is defined.
The best solution would be to change listInsertFirst to take a T* as its first argument so your header file would say this:
extern void listInsertFirst(T *data, int key, LinkedList* ListToInsertTo);
Then you get an opaque pointer for your T data type and, since all pointers are the same size (in the modern world at least), the compiler will know how to build the stack when calling listInsertFirst.
Are you sure it is the first parameter that is the problem? To be sure, try changing the parameter type from T to int temporarily. More than likely, the third parameter is actually the problem.
Many compilers don't point at the problem in these sorts of issues very well.
Try to move the structure definition to the h file, before the typedef.
Define struct T in header, not in .c file;
Choose different names for structure and typedef.

Resources