error: unknown type name ‘Point’ - c

When I try to compile a C file under 64-bit Linux using command:
gcc -o strain_from_faults_new strain_from_faults_new.c gen.h eqf.h
I met the following errors:
eqf.h:16:3: error: unknown type name ‘Point’
Point loc;
^
eqf.h:32:3: error: unknown type name ‘Point’
Point p[33];
^
eqf.h:44:3: error: unknown type name ‘Point’
Point p[33];
^
eqf.h:61:3: error: unknown type name ‘Point’
Point xy[NSEG];
^
It seems that type 'Point' is not defined, but it does defined in the file
gen.h
struct point {
double x;
double y;
};
typedef struct point Point;
I don't know why it have such an error, since this C file can be compiled in other computers. Is this 32bit-64bit compatible issue?
Any comment(s) would be highly appreciated!
According to the comments I #include "gen.h" in eqf.h file, but it not doing well. Since the two head files gen.h eqf.h have already been included in the C file strain_from_faults_new.c, the compiler have errors:
In file included from eqf.h:12:0,
from strain_from_faults_new.c:6:
gen.h:11:8: error: redefinition of ‘struct point’
struct point {
^
In file included from strain_from_faults_new.c:5:0:
gen.h:11:8: note: originally defined here
struct point {
^
Does anybody have any ideas?
Well, following are the entire codes:
gen.h
#define MAX_NAME 50
#define MAXNAME 50
#define EARTH_RADIUS 6371.0
#define MU (3.0e11)
#define PI 3.1415927
#define D2R 0.0174532
#define SUNIT (1.0e-9)
#define KAPA 0.25
#include <stdio.h>
struct point {
double x;
double y;
};
typedef struct point Point;
extern int enclose(Point *, int, Point);
extern int enclose2(Point *, int, Point, Point);
extern int lenclose(Point *p, int n, Point p1);
extern int lenclose2(Point *p, int n, Point p1, Point p2);
extern double azimuth(double, double);
extern double atan2d(double, double);
extern double sind(double);
extern double cosd(double);
extern double dsign(double);
extern double dmax(double, double);
extern double dmin(double, double);
extern double diag_len(Point p[]);
extern void make_tensor(double z[][3], double, double, double);
extern void read_a_line(FILE *);
extern void strip_a_line(FILE *);
extern char *get_a_string(FILE *f, char* str);
extern int line_to_string(FILE *f, char* str);
extern int in_region(int node[], int N, int p);
extern double convert_date_to_year(int);
eqf.h
#define MAXP 10
#define MAXN 400
#define MAXB 1000
#define MAXF 37000
#define MAXE 1000
#define TYPE_F 1
#define TYPE_E 0
#define T 149
#define DEPTH 15.0
#define NSEG 2074
#include <stdio.h>
#include "gen.h"
struct earthquake {
int date;
Point loc;
double mom[3][3];
double m0;
int type;
};
struct merr {
double m[3][3];
};
struct mom {
double m0;
double mxx;
double myy;
double mxy;
};
struct region {
Point p[33];
double area;
double t0;
struct earthquake event[50];
int ne;
struct earthquake *e[100];
double strainrate[9];
double strain[9];
double strainr[9];
double strain0[9];
};
struct regionf {
Point p[33];
double area;
int ix;
int iy;
int ia;
};
struct fault {
double strike;
double rake;
double dip;
double rate;
double ratemin;
double ratemax;
char name[50];
int date;
int n;
Point xy[NSEG];
};
extern void test();
extern void read_faults(FILE *inf, struct fault *f);
extern void test_mom();
extern void print_event (FILE *inf, struct earthquake e);
extern int bydate(struct earthquake *, struct earthquake *);
extern void sort_event(FILE *);
extern int write_mom_tensor(struct earthquake *, int *, double);
extern void fill_regionf(struct regionf *, int *);
extern void fill_region(struct region *, int *);
extern void print_mom_in_region(struct region *b, int nb);
extern double strain_rate(double ex, double ey, double exy);
extern double strain_rate_var(double ex, double ey, double exy, double dex, double dey, double dexy, double cxy, double cxxy, double cyxy);
strain_from_faults_new.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "gen.h"
#include "eqf.h"
void deal_with_options(int, char **);
int no_faults, n_events;
double sdepth;
double ub = 0.01;
char faultin[25];
FILE *strain1;
int main(int argc, char *argv[]) {
Point p[MAXN], p1[10];
struct fault f[MAXF];
struct regionf b[MAXB];
double plat=0.0, plon=0.0, prat=0.0;
int n=0, i, j, nb=0, np, num, ia, k, l, nrect=0, nfree=0, ix=0, iy=0;
FILE *faults, *strain0;
sdepth = DEPTH*1.0e5;
strcpy(faultin, "fault.in");
deal_with_options(argc, argv);
if( (faults = fopen(faultin, "r")) == NULL ) {
printf("Error: File %s does not exist.\n", faultin);
exit(-1);
}
if( (strain0 = fopen("spline_fit.dat", "r")) == NULL) {
printf("Error: File spline_fit.dat cannot open\n");
exit(-1);
}
if( (strain1 = fopen("strain_from_faults.dat", "w")) == NULL) {
printf("Error: File strain_from_faults.dat cannot open\n");
exit(-1);
}
fscanf(strain0, "%d%d%d", &ix, &iy, &num);
fscanf(strain0, "%d", &nfree);
fprintf(strain1, "%10d %10d %10d\n", ix, iy, num);
fprintf(strain1, "%10d\n", nfree);
for(i=nfree; i<num; i++) {
if(fscanf(strain0, "%d%lf%lf%lf", &np, &plat, &plon, &prat) != 4) {
printf("Error: format error in spline_fit.dat\n");
exit(1);
}
fprintf(strain1, "%10d %10.3f %10.3f %12.6e\n", np, plat, plon, prat);
}
fscanf(strain0, "%d", &nrect);
fprintf(strain1, "%10d\n", nrect);
close(strain0);
for(i = 0; i < nrect; i += MAXB) {
nb = i;
printf("Working on regions %d to %d ...\n", i, i+MAXB);
fill_regionf(b, &nb);
read_clip_faults(faults, f, b, nb);
}
return 0;
}
int read_clip_faults(FILE *inf, struct fault *f, struct regionf *b, int nb) {
int i, j, k, l, ib, jj, kk, ii, n, nf;
double x, y, dx, dy, d, mt[3][3], c, theta;
double sd, md, strainrate[9];
double clip_seg = 0.05;
struct mom m1;
struct mom m0;
struct merr m2;
struct fault f0;
Point p[100], p0;
i=0;
fseek(inf, 0, SEEK_SET);
while( (k = fscanf(inf, "%d%lf%lf%lf%lf%lf%s",
&n, &(f[i].rake), &(f[i].dip), &(f[i].ratemin),
&(f[i].rate), &(f[i].ratemax), f[i].name)) == 7) {
printf("Fault no. %d, %s\n", i, f[i].name);
f[i].rate = f[i].rate;
f[i].ratemin = f[i].ratemin;
f[i].ratemax = f[i].ratemax;
f[i].n = 0;
for(j=0; j<n; j++) {
if( (l = fscanf(inf, "%lf%lf", &(p[j].y), &(p[j].x))) != 2) {
printf("Error at fault %s, line %d in fault.in\n", f[i].name, j);
exit(1);
}
}
jj=0;
for(j=0; j<n-1; j++) {
k = 0;
while( k < nb && (l = enclose(b[k].p, 33, p[j])) == 0)
...
Following Mike Kinghan's comments, I added
#ifndef GEN_H
#define GEN_H
and
#endif
in the head and tail of the gen.h file, respectively. But it not doing well, here are the errors:
/tmp/ccteT25z.o: In function `read_clip_faults':
strain_from_faults_new.c:(.text+0x6a4): undefined reference to `enclose'
strain_from_faults_new.c:(.text+0x7c5): undefined reference to `enclose'
strain_from_faults_new.c:(.text+0xa14): undefined reference to `enclose'
strain_from_faults_new.c:(.text+0xa7b): undefined reference to `dsign'
strain_from_faults_new.c:(.text+0xaae): undefined reference to `dsign'
strain_from_faults_new.c:(.text+0xad9): undefined reference to `dsign'
strain_from_faults_new.c:(.text+0xb5a): undefined reference to `dsign'
...

you need to #include "gen.h" in eqf.h

If you read this:
In file included from eqf.h:12:0,
from strain_from_faults_new.c:6:
gen.h:11:8: error: redefinition of ‘struct point’
struct point {
^
In file included from strain_from_faults_new.c:5:0:
gen.h:11:8: note: originally defined here
struct point {
^
it tells you that struct point is defined twice in the same translation
unit, strain_from_faults_new.c, which is an error.
You have defined struct point in gen.h at line 11.
You have included gen.h at line 5 in strain_from_faults_new.c
You have also included gen.h at line 12 in eqf.h.
And finally you have included eqf.h at line 6 in strain_from_faults_new.c,
thereby including the definition of struct point again.
To avoid such problems, use header guards a.k.a include guards in every header you write,
e.g.
gen.h
#ifndef GEN_H
#define GEN_H
struct point {
double x;
double y;
};
typedef struct point Point;
#endif
This makes it harmless to include a header more than once in a translation unit.
And, don't pass header files in the compiler commandline:
gcc -o strain_from_faults_new strain_from_faults_new.c gen.h eqf.h
^^^^^ ^^^^^
A header file gets compiled by being #include-ed in a .c file, which
copies it into the translation unit.

You need to add #include "gen.h" in eqf.h and compile your program with the command:
gcc -o gen.h eqf.h strain_from_faults_new strain_from_faults_new.c;
Compiler will compile your program file according to your file input order.

Related

microECC - dereferencing pointer to incomplete type

When I try to compile this project I receive an error like this:
dereferencing pointer to incomplete type ‘const struct uECC_Curve_t’ uECC_generate_random_int(r, curves[0]->n, BITS_TO_WORDS(curves[0]->num_n_bits));
I searched several times on Stackoverflow a method to solve this error without success. May I ask you what is wrong in this operation? Why cannot I recover the EC curve parameter n in this manner curves[0]->n?
#include "uECC.h"
#include <stdio.h>
#include <string.h>
void vli_print(char *str, uint8_t *vli, unsigned int size)
{
printf("%s ", str);
for (unsigned i = 0; i < size; ++i)
{
printf("%02X ", (unsigned)vli[i]);
}
printf("\n");
}
int main()
{
uint8_t private[32] = {0};
uint8_t public[64] = {0};
unsigned int r[21];
const struct uECC_Curve_t *curves[1];
int num_curves = 0;
#if uECC_SUPPORTS_secp160r1
curves[num_curves++] = uECC_secp160r1();
#endif
uECC_generate_random_int(r, curves[0]->n, BITS_TO_WORDS(curves[0]->num_n_bits));
memset(public, 0, sizeof(public));
if (!uECC_make_key(public, private, curves[0]))
{
printf("uECC_make_key() failed\n");
}
vli_print("Provided public key = ", public, sizeof(public));
vli_print("Private key = ", private, sizeof(private));
return 0;
}
uECC.h
struct uECC_Curve_t;
typedef const struct uECC_Curve_t * uECC_Curve;
uECC.c (I call it during the compilation with gcc, e.g. gcc -o test test.c uECC.c)
struct uECC_Curve_t {
wordcount_t num_words;
wordcount_t num_bytes;
bitcount_t num_n_bits;
uECC_word_t p[uECC_MAX_WORDS];
uECC_word_t n[uECC_MAX_WORDS];
uECC_word_t G[uECC_MAX_WORDS * 2];
uECC_word_t b[uECC_MAX_WORDS];
void (*double_jacobian)(uECC_word_t * X1,
uECC_word_t * Y1,
uECC_word_t * Z1,
uECC_Curve curve);
#if uECC_SUPPORT_COMPRESSED_POINT
void (*mod_sqrt)(uECC_word_t *a, uECC_Curve curve);
#endif
void (*x_side)(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve);
#if (uECC_OPTIMIZATION_LEVEL > 0)
void (*mmod_fast)(uECC_word_t *result, uECC_word_t *product);
#endif
};

function pointer not working for int

Im trying to use the power of function pointers, it all went fine until i tried to make the function pointer use a 2nd argument as type int.
The code below generates an error, which is displayed below
In an header file:
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct UnitTag {
int x;
int y;
void (*move)(Unit, int);
} Unit;
Error:
error: expected ‘)’ before ‘int’
void (*move)(Unit, int);
^
void (*move)(Unit); works all fine, which surprises me how adding an argument can cause an error.
I call my struct in a C file, by including header and then doing:
Unit units[UNITCOUNT];
units[0].move(&units[0], 1);
Update:
adding:
typedef struct UnitTag Unit
Causes the error to dissapear, however I can no longer use the function as before.
error: incompatible type for argument 1 of ‘units[i].move’
units[0].move(&units[0], 0);
^
note: expected ‘Unit’ but argument is of type ‘struct UnitTag *’
If I'm getting you, you can simply use struct keyword:
#include <stdio.h>
typedef struct UnitTag {
int x;
int y;
void (*move)(struct UnitTag, int);
} Unit;
void Test (struct UnitTag test1, int test2)
{
printf("Test1.x: %d\n", test1.x);
printf("Test1.y: %d\n", test1.y);
printf("Test2 : %d\n", test2);
}
int main(void)
{
Unit units[100];
units[0].move = Test;
units[0].x = 1;
units[0].y = 2;
units[0].move(units[0], 3);
}
Output:
Test1.x: 1
Test1.y: 2
Test2 : 3
If you want to pass struct by referebce, simply:
#include <stdio.h>
typedef struct UnitTag {
int x;
int y;
void (*move)(struct UnitTag*, int);
} Unit;
void Test (struct UnitTag *test1, int test2)
{
test1->x = 4;
test1->y = 5;
}
int main(void)
{
Unit units[100];
units[0].move = Test;
units[0].x = 1;
units[0].y = 2;
units[0].move(&units[0], 3);
printf("units[0].x: %d\n", units[0].x);
printf("units[0].y: %d\n", units[0].y);
}
Output is:
units[0].x: 4
units[0].y: 5
You need the prototype for Unit before using it.
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct UnitTag Unit;
typedef struct UnitTag {
int x;
int y;
void (*move)(Unit, int);
} Unit;
int main(void)
{
return 0;
}
After the clarification what you wanted to do. It probably makes more sense to give a pointer to Unit, so that the move command which returns void can change something about your object.
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct UnitTag Unit;
typedef struct UnitTag {
int x;
int y;
void (*move)(Unit *, int);
} Unit;
Unit test;
/* some function that corresponds to the interface */
void myMove(Unit *u, int i)
{
u->x = u->x + i;
}
int main(void)
{
/* initialize test struct */
test.x = 0;
test.y = 0;
test.move = myMove;
test.move(&test, 5);
printf("Values after move are (x, y) = (%i, %i).\n", test.x, test.y);
return 0;
}

get size of hidden struct C

I'm trying to get the size of a struct that was defined in a different source file (other.c) to keep it hidden.
In the other.h:
typedef struct X x_t;
In the other.c:
struct X{
int y;
int z;
};
Now I want in the main.c to get the size of this struct.
#include "other.h"
int main(){
x_t *my_x;
my_x = malloc(sizeof(struct x_t));
return 0;}
But this gives me following error:
error: invalid application of ‘sizeof’ to incomplete type ‘struct x_t’
Can anybody help me? Thank you!
The whole purpose of having a hidden struct is to carefully control their construction, their destruction, and access to the contents.
Functions to construct, destruct, get the contents, and set the contents have to be provided to make the hidden struct useful.
Here's an example of what the .h and .c files could be:
other.h:
typedef struct X x_t;
x_t* construct_x(void);
void destruct_x(x_t* x);
void set_y(x_t* x, int y);
int get_y(x_t* x);
void set_z(x_t* x, int z);
int get_z(x_t* x);
other.c:
struct X {
int y;
int z;
};
x_t* construct_x(void)
{
return malloc(sizeof(x_t));
}
void destruct_x(x_t* x)
{
free(x);
}
void set_y(x_t* x, int y)
{
x->y = y;
}
int get_y(x_t* x)
{
return x->y;
}
void set_z(x_t* x, int z)
{
x->z = z;
}
int get_z(x_t* x)
{
rteurn x->z;
}

How can i access variables in structs in C to print?

**> Is there a way to access a variable that come from other struct? When
i try this code,i am getting this compile error.
**
test.c: In function ‘readRecordsFromFile’:
test.c:70:18: error: expected expression before ‘kdnode’
printf(" %f\n",kdnode.data.latitude);
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <math.h>
#define rec_size 112
typedef struct _Node kdnode;
typedef struct _Record record;
static void readRecordsFromFile(char *filename);
struct _Record{
int plateNumber;
long *name[32];
double area;
int population;
int density;
int popcitycenter;
long region;
double latitude;
double longtitude;
};
struct _Node
{
//kdnode left;
//kdnode right;
record data;
bool type;
double x;
double y;
int pagenumber;
};
int main(){
readRecordsFromFile("data.dat");
return 0;
}
static void readRecordsFromFile(char *filename)
{
FILE* inputFile;
inputFile = fopen(filename, "rb");
int i;
if(!inputFile) {
printf("Could not open file");
return;
}
int length,record_count;
fseek(inputFile,0,SEEK_END);
length=ftell(inputFile);
fseek(inputFile,0,SEEK_SET);
record_count = length/sizeof(record);
kdnode kd;
fread(&kd,rec_size,2,inputFile);
printf("%d",ftell(inputFile));
for (i = 0; i < record_count; i++)
{
printf(" %f\n",kdnode.data.latitude);
}
fclose(inputFile);
}
typedef struct _Node is typedefed as knode. knode represents a data type and it's not an identifier, so this
printf(" %f\n",kdnode.data.latitude);
has to be
printf(" %f\n", kd.data.latitude);
You should also check return values for functions like fread() for example.

How to modify a struct content through 2 layer of functions?

Suppose I have the following code:
typedef otherStruct_t struct_t[X][Y];
void foo1(struct_t * mystruct); //declaration in main()
main()
{
struct_t mystruct = {0};
foo1(&mystruct);
...
}
void foo1(struct_t * mystruct)
{
foo2(&mystruct, number);
...
}
in other .c file.
void foo2(struct_t ** mystruct, int number)
{
(*mystruct[x][y])-> number = number;
}
I read some posts regarding pointer of pointer in struct and this what I came up with.
It compiles, but the caller struct is not modified, and sometime cause seg. fault as well.
Where is my mistake? Thank you!
There are couple of ways to do it. In the following code you can remove the comment around
#define NO_PTR_USE 1
to do it without using pointer(s). If using pointers, then you have to remember as #Oli Charlesworth pointed out, [] has higher precedence than *.
/* #define NO_PTR_USE 1 */
#define X 10
#define Y 10
#define ax 1
#define ay 5
struct foo {
int number;
};
typedef struct foo struct_t[X][Y];
void
#if NO_PTR_USE
foo1(struct_t mystruct),
foo2(struct_t mystruct, int x, int y, int n);
#else
foo1(struct_t *mystruct),
foo2(struct_t *mystruct, int x, int y, int n);
#endif
main()
{
struct_t mystruct = {0};
#if NO_PTR_USE
foo1(mystruct);
printf("No pointer was used.\n");
#else
foo1(&mystruct);
printf("Pointer was used.\n");
#endif
printf("mystruct[%d][%d].number = %d\n",
ax, ay, mystruct[ax][ay].number);
}
void
#if NO_PTR_USE
foo1(struct_t mystruct)
#else
foo1(struct_t *mystruct)
#endif
{
foo2(mystruct, ax, ay, 1234);
}
void
#if NO_PTR_USE
foo2(struct_t mystruct, int x, int y, int n)
#else
foo2(struct_t *mystruct, int x, int y, int n)
#endif
{
#if NO_PTR_USE
mystruct[x][y].number = n;
#else
(*mystruct)[x][y].number = n;
#endif
}
Normally, once you've got a pointer, you don't pass it by address. Think of FILE *fp = fopen(...);. You don't use fprintf(&fp, ...);, do you?
Same here:
typedef struct foo struct_t[X][Y]; // Nasty piece of work - don't do it!
extern void foo1(struct_t *t);
extern void foo2(struct_t *t);
int main(void)
{
struct_t data = {0};
...
foo1(&data);
...
return 0;
}
void foo1(struct_t *t)
{
...
foo2(t);
...
}
Other file:
void foo2(struct_t *t)
{
...
stuct foo x = (*t)[i][j];
...
}
Note that a struct_t is a 2D array of structures, so a struct_t * is a pointer to an array of structures. Therefore, you have to get the access notation correct, as shown in foo2() above. And that's one reason why you probably don't want to use that type. You'd be better off, almost certainly, using:
typedef struct bar
{
struct foo data[X][Y];
} bar;
And you can then pass bar *bp values around, and access the data using bp->data[i][j].

Resources