I'm new to C and had some questions around struct instantiation. I have two files :
Index.c
: which instantiates a new Server
structserver/Server.c
which defines the Server
struct, the new_Server()
constructor and the kill_Server()
deconstructorContent of Index.c
:
/* Standard libraries */
#include <stdio.h>
#include <string.h>
/* Project's Custom classes */
#include "./server/Server.c"
/* Configuration value */
#define HOST "127.0.0.1"
#define PORT 80
int main (void) {
unsigned short port = PORT;
unsigned char host[255] = HOST;
Server* server = new_Server(port, host);
return 0;
}
Content of server/Server.c
:
#include <stdlib.h>
/* HOST_NAME_MAX will have to be changed into getconf HOST_NAME_MAX */
#define HOST_NAME_MAX 255
typedef struct {
unsigned short port;
unsigned char host[HOST_NAME_MAX];
} Server;
Server* new_Server (unsigned short port, unsigned char host[]) {
Server* server = malloc(sizeof(Server));
server->port = port;
server->host = host;
return server;
}
void kill_Server (Server* server) {
free(server);
}
When I compile the program, I get the following output :
In file included from src/index.c:6:
src/./server/Server.c:11:9: warning: no previous prototype for function 'new_Server' [-Wmissing-prototypes]
Server* new_Server (unsigned short port, unsigned char host[]) {
^
src/./server/Server.c:14:15: error: array type 'unsigned char [255]' is not assignable
server->host = host;
~~~~~~~~~~~~ ^
src/./server/Server.c:18:6: warning: no previous prototype for function 'kill_Server' [-Wmissing-prototypes]
void kill_Server (Server* server) {
^
2 warnings and 1 error generated.
(I just left out the "server" variable not used warning.)
So here are my questions :
Why am I getting the "missing prototype" warning since I actually did specify the output and method argument types ?
How can I initialise a struct with it's "host" key being an array of chars ?
Is what I'm doing efficient ? Steps :
#define
I read that to get the maximum hostname size you should do "getconf HOST_NAME_MAX". In the shell it works of course and I get 255, but I'd like to store the value in a variable in my C program.
I'm compiling with the following GCC flags :
gcc -g -O0 -Wall -Wextra -std=c89 -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Wold-style-definition -Wdeclaration-after-statement
I know this is (unnecessarily) strict, but I'd like to learn C the hard way and really understand it's ins-and-outs. And I think that stuff like warnings are great for this.
EDIT: I did already read this question How to initialize a structure with flexible array member, but I didn't really understand the answer. It also leaves out the issue about method prototypes.
Well, you should avoid using #include
to include a .c file. The .c
files are supposed to be compiled separately (with common definitions in a .h
file that both include), and then you link the compiled objects together.
The two warnings is bogus, there is no code problem. You could suppress the warning by adding a prototype (just copy line 11 but put a ;
on the end). Same for the second one
The error: server->host = host;
is illegal. Arrays are second-class citizens in C, you cannot copy them using the =
operator. You need to either go memcpy(&server->host, &host, sizeof server->host);
, or strcpy(server->host, host);
.
I think it'd be overkill to have your C program execute getconf
and see what it got; instead, look up what the max value is that getconf
will ever give back to you.