Passing structs by pointer in C89 - c

I am working with a C89 compiler and I'm coming across some pointer typing error.
Calling code:
struct cpu_state_type cpu_state;
//Stuff here....
foo()
{
print_out_cpu(&cpu_state);
}
Print_out_cpu is defined elsewhere and the H file is #included in.
struct cpu_state_type
{
int r[12];
};
void print_out_cpu(struct cpu_state_type *c);
I get error:
error: incompatible type for argument 1 of 'print_out_cpu'
As best as I can understand,&cpu_state returns type cpu_state_type*, so I am confused.

Are you sure the prototype has the * in it? If I compile (gcc -std=c89) the following code, I get that exact error:
struct cpu_state_type {
int r[12];
};
// note that it is the structure as the param here (not the pointer)
void print_out_cpu(struct cpu_state_type c);
struct cpu_state_type cpu_state;
foo()
{
print_out_cpu(&cpu_state);
}

I don't see any problems, so I wonder if it's an error in your include statement or in the file, etc.
It'll be difficult to determine the cause of the error without seeing more of the source. Try creating a source file like:
#include struct cpu_state_type cpu_state;
void foo() {
print_out_cpu(&cpu_state);
}
If that doesn't trigger the problem, keep adding things until it does.
If it does trigger the problem, extract the pertinent parts of the header file into your source (and remove the #include) and try again.

Related

How can I use a declared but undefined function in C regardless?

So what I want to do is I want to create a kind of framework for myself in the future but I realized I can't do something. It goes like this:
void whenPressedQ();
void whenPressedW();
...
void checkPressQ(){
whenPressedQ();
printf("Q was pressed");
}
...
void whenPressedW(){
doThings();
}
Later I will define these functions and choose which of them to use.
Problem is I can't do this for the other functions if I haven't defined them below. I get an "undefined function" error. Is there any way I can solve this? I've tried using pointers to functions and check if it's null but it's the same thing.
You can pass pointers to callback functions, or wrap them in structures, then have the library pass back a pointer to a function that matches the signature later, even one that you will write in the future. This was how the first C++ compilers implemented virtual methods of objects.
If you just want the code to compile while you’re getting around to the unimplemented functions, you can create dummy stub functions to shut the linker up.
Update
Here are some examples of what I mean. Your question is somewhat ambiguous. If what you are asking is how you can declare functions that you intend to implement later, and still be able to compile the program, the answer is to provide stubs. Here’s a MCVE of your interface:
#include <stdio.h>
#include <stdlib.h>
/* In older versions of C, a declaration like void doThings() would turn
* type-checking of function arguments off, like for printf().
*/
void whenPressedQ(void);
void whenPressedW(void);
void doThings(void); // Added this declaration.
void checkPressQ()
{
whenPressedQ();
printf("Q was pressed.\n"); // Don't forget the newline!
}
void whenPressedW()
{
doThings();
}
// Stub implementations:
void whenPressedQ(void)
// FIXME: Print an error message and abort the program.
{
fflush(stdout); // Don't mix the streams!
fprintf( stderr, "Unimplemented function whenPressedQ() called.\n" );
exit(EXIT_FAILURE);
}
void doThings(void)
// Is nothing a thing?
{}
// Test driver:
int main(void)
{
whenPressedW();
whenPressedQ(); // fails;
// Not reached.
return EXIT_SUCCESS;
}
If you want to let the program dynamically select which function to call, that is more complicated, but you can do it with callbacks. Here’s a simple example.
#include <stdio.h>
#include <stdlib.h>
// This would ordinarily go in a .h file:
typedef const char*(*callback_t)(void); // The type of a callback function.
extern callback_t get_the_answer(void);
// This would ordinarily go in a .c file:
int main(void)
{
callback_t ask_the_question = get_the_answer();
printf( "The answer to life, the Universe and Everything is %s.\n",
ask_the_question()
);
return EXIT_SUCCESS;
}
// This would ordinarily go in another .c file:
static const char* the_answer_is(void)
{
return "42";
}
callback_t get_the_answer(void)
{
return &the_answer_is;
}
The error you are getting a linker error. If you are not trying to build an executable, then you can just compile and do not link. On Linux / OS X, you can pass the -c flag to clang or gcc. On Windows, you can pass the /c flag to cl.exe when compiling.
You can then link the object files directly later, or build a static or dynamic library out of them.

I can't use <nameofmystructure>* this as an argument to a function

this is the code i'm having trouble with:
typedef const char* sun_date_t;
typedef const char* sun_time_t;
typedef struct sun_t {
int luminosity;
/* private */
sun_date_t date;
sun_time_t time;
sun_time_t sunrise;
sun_time_t sunset;
pthread_t tid;
pthread_mutex_t mutex;
} sun_t;
void sun_parse_data (sun_t* this, FILE* f){.....}
as you see, i define an structure and after i try to pass it as a pointer to this "sun_t", but the compiler says i need to write ',' or '....' before 'this'. Any ideas how to solve it?
You must be compiling as C++ since this is a keyword in C++ in C it is not but it is probably not a good idea to use this as a variable name in case you want to port the code later on.
The code compiles fine as a C program: see it live but we see the same error when we attempt to compile as a C++ program: see it live:
error: expected ',' or '...' before 'this'

libwebsockets: Dereferencing pointer to incomplete type error

I'm using libwebsockets and I can't compile a demo code implemented by myself.
I created the context:
struct libwebsocket_context *context;
...
context = libwebsocket_create_context(&info);
and when I try to access the members of the struct libwebsocket_context, defined in private-libwebsockets.h:
struct libwebsocket_context {
struct pollfd *fds;
struct libwebsocket **lws_lookup; /* fd to wsi */
int fds_count;
int max_fds;
int listen_port;
...
};
For example,
printf("%d\n", context->listen_port);
The compiler returns,
error: dereferencing pointer to incomplete type
Thanks!
It seems that "struct libwebsocket_context" is not known for gcc - that's why this error occures. Are you sure that definition of this structure is included from .h file? I'd suggest you to insert for example #warning or #error with some message near definition of this struct (in .h file) and try to recompile your program. Your #error or #warning message should appear while compilation. If not - it means that gcc will not also see this struct.
The fact that the struct definition is in private-libwebsockets.h suggests that you are not supposed to use the struct members directly. You can #include that header to get access to the private implementation details of the library but you probably should not do it.

why do i need to include a .h header file in the .c file of the same name?

So I'm following along in Head First C and we're on a chapter where we learn to compile multiple files together. One of them is encrypt.c.
#include "encrypt.h"
void encrypt(char *message)
{
char c;
while (*message) {
*message = *message ^ 31;
message++;
}
}
The encrypt.h file repeats the first line with a semicolon at the end, so why do I need it? I understand why I would need header files to fix the problem of using a function before it's defined, so I could understand #including it in a file that uses encrypt.c, but why would I need it inside encrypt.c? Is it just one of those "because" reasons?
If the contents of encrypt.c are shown in their entirety, then you don't need the header. But it's still a good idea to include it because:
If one function in the file uses another, then the order of definition matters because the callee must be defined before the caller. It's even possible to have two functions A and B where each calls the other, in which case you cannot get the code to compile without at least one forward declaration. Including the header with the forward declarations solves these problems.
Consuming the header just like your client code does is a good way to have the compiler point out discrepancies between the signatures in the forward declarations and the actual function definitions. If undetected this kind of problem can lead to "interesting" behavior at runtime and lots of hair-pulling.
You're right, if that's all encrypt.h declares, you don't need to include it in the .c file.
You mostly do it for consistency.
Imagine that you change encrypt.c to void encrypt(char *message, int i) { }
If you don't include encrypt.h you won't notice that the other files in your application haven't been updated to pass the new parameter. If you update encrypt.h and encrypt.c at the same time the compiler can do checking for you.
It's good style.
Sometimes, C-file with function implementation and C-file with function usage shares common declarations - types/structures, This shares declarations places at the H-file.
For ex.
[enc.h]
typedef enum {S,F} Res;
EN encode();
[enc.c]
#include "enc.h"
Res encode() { ... }
[other.c]
Res res;
res = encode();
It is prototyping the function
http://en.wikipedia.org/wiki/Function_prototype
Then you include the header in a another *.c-file the compiler knows in this way that anywhere else is the function definition.
This ist like:
#include <stdio.h>
int main (void)
{
afun();
return 0;
}
void afun (void)
{
printf("hello\n");
}
Now the compiler doesn't know what to do with afun() in the main function. Because it was'nt defined. So it will lead into an compiler error.
So you add the declaration at the beginning or bevore the first usage:
#include <stdio.h>
void afun(void);
int main (void)
{
afun();
return 0;
}
void afun (void)
{
printf("hello\n");
}
Know the compiler knows the deklaration of afun and hopes anythere else the function is defined. With header files it is possible to use precompiled c-code. The only thing the compiler is needed is the deklaration of the function.

Strange makefile build error

I'm working on this very simple part of code, but somehow the build error is pretty strange to me.
I have these files in the project: main.c, http_request.h, http_request.c; and a simple Makefile.
1. http_request.h
/* STRUCTURES */
struct http_param {
char key[MAX_BUFFER];
char *value;
};
struct http_request {
int size;
struct http_param data[MAX_PARAM];
};
/* FUNCTIONS */
int parse_http_request(apr_pool_t *pool, const char *args, struct http_request *req); /* (A) */
2. http_request.c
#include <http_request.h>
...// something else goes here, it's fine
int
parse_http_request(apr_pool_t *pool, const char *args, struct http_request *req) /* (B) */
{
3. Makefile
-I$(PROJECT_DIR)/include
this directory contains http_request.h.
Then I build, it raises this error:
/project/src/http_request.c:14: warning: 'struct http_request' declared inside parameter list
/project/src/http_request.c:14: warning: its scope is only this definition or declaration, which is probably not what you want
/project/src/http_request.c: In function 'parse_http_request':
The error points to (A) and (B) as I mentioned in source code above.
Could anyone help to find out what the problem is?
Thanks.
I suspect, seeing that you use apr_pool_t, that you also have apache includes in your include path. apache also provides a file called http_request.h and that one gets included instead of the one you have.
use
#include "http_request.h"
instead of
#include <http_request.h>

Resources