Reputation: 45
I am currently learning C and this is also my first question here. The problem is as follows. I get this warning when I try to compile this code
#include <stdio.h>
#include "LicenseManager.h"
int main(void)
{
puts("program start");
struct License *license = read();
// other code
}
The read()
Method is in LicenseManager.h declared as struct License *read(void){...}
and the pointer it returns is a reference to static struct License license;
, but when I try to compile the compiler refuses and says
warning: implicit declaration of function 'read' [-Wimplicit-function-declaration]
struct License *license = read();
Even my IDE says that the read()
; method returns an int (when i look at it in the main method, in the actual LicenseManager.h it the IDE correctly says struct License *
.
What I tried:
I tried making a Method prototype struct License *read(void);
above the main method
#include <stdio.h>
#include "LicenseManager.h"
struct License read();
int main(void)
{
puts("program start");
struct License *license = read();
// other code
}
, which resolved that error and got the code to compile, however now I instantly get a
Segmentation Fault
(even before puts("program start");
is invoked).
I tried to change the returnvalue of read()
from a pointer to an actual struct, however that raised the same problems.
Next I tried to change the read()
method to void read(struct License *license)
and give the pointer to the object externally but I still receive the same Segementation Fault every time. before the first line of code is even invoked.
after everything I tried my final code now looks like this:
#include <stdio.h>
#include "LicenseManager.h"
void read(struct License *license);
int main(void)
{
puts("program start");
struct License license;
read(&license);
}
Needless to say. it still does not run. :( what do I do wrong?
So I found out some stuff, thanks to you guys and through some testing. When I use my MingW64 (i am running on windows) console I get Segmentation fault. I wanted to avoid posting large amounts of code here. but I guess I will do it. The Library i am using is an Open source Json lib called cJSON
. LicenseManager.c
#include <stdio.h>
#include "cJSON.c"
#include "cJSON.h"
#include "LicenseManager.h"
#include <time.h>
#define JSON_FILE "license.json"
void interpret(cJSON *json, struct License *license);
// DEFINE VALUES IN JSON FILE
const char *LICENSE_NAME = "printerLicense";
const char *LICENSE_COMPANY_NAME = "name";
const char *LICENSE_PRINTER_ID = "id";
const char *LICENSE_VALID_START = "validFrom";
const char *LICENSE_VALID_END = "validTo";
const char *LICENSE_PERMISSIONS = "permissions";
const char *LICENSE_HARDWARE_ID = "hardwareId";
//############################
char *readFile(void)
{
FILE *f = fopen(JSON_FILE, "rb");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
rewind(f);
char *string = malloc(fsize + 1);
fread(string, 1, fsize, f);
fclose(f);
string[fsize] = 0;
return string;
}
void parseDate(cJSON *json, struct Date *date)
{
fflush(stdout);
unsigned short valYear, valMonth, valDay;
cJSON *child = json;
valYear = child->valueint;
child = child->next;
valMonth = child->valueint;
child = child->next;
valDay = child->valueint;
date->year = &valYear;
date->month = &valMonth;
date->day = &valDay;
}
void setLicenseRights(cJSON *json, struct License *license)
{
cJSON *rights = get_Array_item(json, LICENSE_PERMISSIONS, cJSON_False);
int size = cJSON_GetArraySize(rights);
char *permissions[size];
for (size_t i = 0; i < size; i++)
{
permissions[i] = get_array_item(rights, i);
}
memcpy(license->permissions, permissions, sizeof(permissions));
}
void interpret(cJSON *json, struct License *license)
{
cJSON *licenseJson = json->child;
struct Date validFrom;
parseDate(get_object_item(licenseJson, LICENSE_VALID_START, cJSON_False), &validFrom);
struct Date validTo;
parseDate(get_object_item(licenseJson, LICENSE_VALID_END, cJSON_False), &validTo);
cJSON *companyName = get_object_item(licenseJson, LICENSE_COMPANY_NAME, cJSON_False);
cJSON *hardwareID = get_object_item(licenseJson, LICENSE_HARDWARE_ID, cJSON_False);
cJSON *printerID = get_object_item(licenseJson, LICENSE_PRINTER_ID, cJSON_False);
setLicenseRights(licenseJson, license);
license->companyName = companyName->valuestring;
license->hardwareID = hardwareID->valuestring;
license->printerID = printerID->valuestring;
license->validFrom = &validFrom;
license->validTo = &validTo;
}
//reads the License file. Use this to read the License.
void read(struct License *license)
{
printf("#####################\n");
fflush(stdin);
char *string = readFile();
printf("#####################\n");
fflush(stdin);
cJSON *json = cJSON_Parse(string);
printf("#####################\n");
fflush(stdin);
interpret(json, license);
printf("#####################\n");
fflush(stdin);
cJSON_Delete(json);
free(string);
}
LicenseManager.h
#ifndef DATE
#define DATE
struct Date
{
unsigned int *year, *month, *day;
};
#endif
#ifndef LICENSE
#define LICENSE
struct License
{
char *companyName;
char *printerID;
char *hardwareID;
struct Date *validFrom;
struct Date *validTo;
char *permissions[];
};
#endif
and of course main.c
#include <stdio.h>
#include "LicenseManager.h"
void read(struct License *license);
int main(void)
{
puts("program start");
fflush(stdout);
struct License license;
read(&license);
}
I forgot to include the actual LicenseManager.c file in my main. now I get some other compiler errors which i am likely to be able to fix. So the compiler just assumed that the read method just returns an int, because there was no actual declaration of it. now I just have to deal with some incompatible pointers haha.
Upvotes: 1
Views: 103
Reputation: 23236
The warning:
warning: implicit declaration of function 'read' [-Wimplicit-function-declaration] struct License *license = read();
Is telling you that the explicit prototype provided does not match the prototype you tried to use:
struct License read();
Also, if this prototype is provided in the header file, it should not be re-declared in your source code.
Simply stated, the prototype of the function read
needs to match its intended usage in the shown code:
Here is an adapted version of your code (with some additions to assist building on my system, i.e. a fake struct.)
// implementation of sample struct to allow build without "LicenseManager.h"
struct License
{
int a;
int b;
char account[80];
};
//again, because I do not have "LicenseManager.h", prototype provided here.
struct License *read(void);//corrected prototype
int main(void)
{
puts("program start");
struct License *license = read();//this usage dictates prototype needs of read()
printf("%d\n%d\n%s", license->a, license->b, license->account);
free(license);//free memory once no longer needed.
return 0;
}
struct License *read(void)//example implementation but using proper prototype
{
struct License *new = malloc(sizeof(*new));//create memory
//populate struct with some values:
new->a = 10;
new->b = 20;
strcpy(new->account, "Bains");
return new;
}
Upvotes: 0
Reputation: 1765
Please provide the header code or at least just extract read()
from there and post a complete program here
Please compare the code below to your version and look at possible clues and ask about them
The program shows
Start
read() as "License read()" 35? : 35
read() as "License* read()" 9? : 9
read() as "void read(License*)" -56? : -56
End
The code
#include <stdio.h>
#include <stdlib.h>
typedef struct { int i; } License;
License* pRead(void);
License read(void);
void readV(License* L);
int main(void)
{
puts("Start");
License license = read();
printf("read() as \"License read()\" 35? : %d\n", license.i);
License* p = pRead();
printf("read() as \"License* read()\" 9? : %d\n", p->i);
free(p);
readV(&license);
printf("read() as \"void read(License*)\" -56? : %d\n", license.i);
puts("End");
return 0;
}; // main()
License* pRead()
{
License* p = (License*)malloc(sizeof(License));
p->i = 9;
return p;
};
License read()
{
License L = { 35 };
return L;
};
void readV(License* L) { L->i = -56; };
A small change from your code: a
typedef struct { int i; } License;
was inserted in order to not repeat the keyword struct
everywhere
Upvotes: 1