Problem in compiling a C code with MSVC++6.00

B

Babak

Hi Everyone,

I've written a standard C code for a simple finite element analysis
in MSVC++ . When I save the file as a cpp file, it compiles and runs
perfectly, but when I save it as a c file, there are lots of errors and
warnings in compiling stage. I am really confused about this problem
because I'm not even familiar with C++ and my code only includes simple
C functions. Can anybody please tell me what's my mistake? Is there any
other way rather than changing the extension of the file from .cpp to
..c during the save stage to let the compiler know that this is just a C
file and not a C++?

As another question I also need to compile my code with gcc, but the
compilation is not successful and it gives the following error: "
Incompatible types in initialization". Can you pls tell me how to write
and save my code so that it will be OS independent. Is there any
settings in MSVC++ that should be changed or the problem is with my
code.

Here is my entire code (Sorry it's a little lengthy!). I would be
very grateful if somebody can have a look at it and give me some hints.

Babak


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
struct element {
int p1;
int p2;
int p3;
int er;
};

struct node {
float x;
float y;
};
void checkfile (FILE *);
void read_node_data (FILE *, struct node *);
void read_element_data (FILE *,FILE *, struct element *, int *);
void ss(struct node*,struct node*, struct node*, int *, float * ,int
*,float *);
void assembly(int *, int *,int *, float *, float **, float *, float *);

int main(void) {

FILE *fp;
FILE *ft;
FILE *fer;
FILE *ftest;
int i;
int j;
int NUMNODE=0;//number of nodes
int NUMELE=0;//number of elemnts
char *str;
struct node *nd;
struct element *ele;
int *g;

str=(char *)malloc(sizeof(char)*80);
fp=fopen("femesh2_p.txt", "r");
ftest=fopen("nodeindex_2.txt", "w");
checkfile (fp);
checkfile (ftest);
while (!feof(fp)) {
fgets (str,77,fp);
fprintf(ftest, "%d %s \n", NUMNODE+1, str);
NUMNODE ++;
}
fcloseall();
ft=fopen("femesh2_t.txt", "r");
checkfile (ft);
while (!feof(ft)) {
fgets (str,79,fp);
NUMELE ++;
}
fclose(ft);
free(str);
//allocating enough memory for reading P,T and er and g arrays
nd=(struct node*)malloc(sizeof(struct node) * NUMNODE);
if (!nd) {
printf("cannot allocate memory for nodes!");
exit(1);
}
ele=(struct element*) malloc(sizeof(struct element) * NUMELE);
if (!ele) {
printf("cannot allocate memory for elements!");
exit(1);
}
g=(int *) malloc(sizeof(*g) * NUMELE);
if (!g) {
printf("cannot allocate memory for charge density!");
exit(1);
}

float **K;
K = (float **) malloc( NUMNODE * sizeof( float*));
if( K != NULL)
for( i = 0; i < NUMNODE; i++){
K =(float *) malloc( NUMNODE * sizeof( float) );
if( K == NULL) {
printf("cannot allocate memory for global stiffness
matrix!");
exit (1);
}
}

float *b;
b= (float *) malloc (NUMNODE * sizeof (float *));
if (b==NULL) {
printf ("cannot allocate memory for Right Hand Side Vector!");
exit (1);
}

// next we initialze elements of K and b to zero
for ( i = 0; i < NUMNODE; i++) {
for ( j = 0; j < NUMNODE; j++)
K[j]=0;
b=0;
}


// reading and storing node information (P array)

fp=fopen("femesh2_p.txt", "r");
checkfile (fp);
for (i=0; i<NUMNODE; i++)
read_node_data(fp,nd+i);
fclose(fp);
ft=fopen("femesh2_t.txt", "r");
checkfile(ft);
fer=fopen("femesh2_er.txt", "r");
checkfile(fer);
// reading and stroing element information (T and er arrays)
for (i=0; i<NUMELE; i++)
read_element_data(ft, fer, ele+i, g+i);
//printf ("%d \n",*(g+i));
fcloseall();
// Now that all the information are available, we'll proceed to
calculate
//stiffness matrix for each element
float Me[3][3]={NULL};
float be [3] [1]={NULL};
for (i=0; i<NUMELE; i++) {
ss((nd+((ele+i)->p1)-1),(nd+((ele+i)->p2)-1),(nd+((ele+i)->p3)-1),&((ele+i)->er),&Me[0][0],
g+i, &be[0][0]);
int n1=(((ele+i)->p1)-1);
int n2=(((ele+i)->p2)-1);
int n3=(((ele+i)->p3)-1);
assembly (&n1,&n2,&n3,&Me[0][0], K, &be[0][0], b);
}

//The next step is to apply boundary conditions to global stiffness
matrix
for (i=0; i<NUMNODE; i++) {
float param=(((nd+i)->y) * ((nd+i)->y) + (((nd+i)->x)-10) *
(((nd+i)->x)-10));
if ( param > (0.74 * 0.74) && param < (0.75 * 0.75) && ((nd+i)->y)!=0
) {
K = 1e+8;
b = 0;
printf("%d \n" ,i+1);

}
}
//
fp=fopen("SS2.DAT","w");
ft=fopen("LOAD2.DAT","w");
checkfile(fp);
checkfile(ft);

for(i=0;i<NUMNODE;i++) {
for(j=0;j<NUMNODE;j++) {
if (j==(NUMNODE-1))
fprintf(fp,"%f \n", K[j]);
else
fprintf(fp,"%f ", K[j]);

}

fprintf(ft,"%f \n ", b);
}
fcloseall();


//printf ("%f \n", K[70][70]);
//printf ("%f \n", b[70]);

free(g);
free (ele);
free(nd);
for ( i = 0; i < NUMNODE; i++)
free(K);
free(K);
free(b);
return 0;
}
// This function checks if the specified file is opened or not!
void checkfile (FILE * f)
{
if(!f) {
printf("can't open the file");
exit(1);
}
}

// This function reads the node coordination
void read_node_data (FILE * input, struct node *nod)
{
fscanf (input,"%f", &(nod->x));
fscanf (input,"%f", &(nod->y));
}
//This function reads element information
void read_element_data (FILE * f1,FILE * f2, struct element * element,
int *charge)
{
fscanf(f1,"%d", &(element->p1));
fscanf(f1,"%d", &(element->p2));
fscanf(f1,"%d", &(element->p3));
fscanf(f2,"%d", &(element->er));
fscanf(f2,"%d", charge);
}

// This function calculates the local stiffness matrix
void ss(struct node *n1,struct node *n2, struct node *n3, int *err,
float *MeMat, int *g ,float *be)
{
int k,j;
float a,r[3],q[3];
//initialize local elements to zero
for(k=0;k<3;k++) {
for(j=0;j<3;j++) {
*(MeMat+3*k+j)=0;
}
*(be+k)=0;
}
for(k=0;k<3;k++) {
q[0]=(n2->y)-(n3->y);
q[1]=(n3->y)-(n1->y);
q[2]=(n1->y)-(n2->y);
r[0]=(n3->x)-(n2->x);
r[1]=(n1->x)-(n3->x);
r[2]=(n2->x)-(n1->x);
}
a=(q[0]*r[1]-q[1]*r[0])/2;

for(j=0;j<3;j++)
for(k=j;k<3;k++)
{
*(MeMat+3*k+j) += ((*err)/(4*a))*q[j]*q[k];
if (j!=k)
*(MeMat+3*j+k)+=((*err)/(4*a))*q[j]*q[k];
}

for(j=0;j<3;j++)

for(k=j;k<3;k++)
{
*(MeMat+3*k+j) +=((*err)/(4*a))*r[j]*r[k];
if (j!=k)
*(MeMat+3*j+k)+=((*err)/(4*a))*r[j]*r[k];
}
for(k=0;k<3;k++)
*(be+k)=((*g)*a)/3;
}
// This function assembles the elements of local stiffness matrix into
global matrix
void assembly(int *n1, int *n2,int *n3, float *local, float ** global,
float *be, float *b)
{
//Assembling the global matrix
global[*n1][*n1]+= * (local);
global[*n2][*n2]+= * (local+4);
global[*n3][*n3]+= * (local+8);
global[*n1][*n2]+= * (local+1);
global[*n2][*n1]+= * (local+1);
global[*n1][*n3]+= * (local+2);
global[*n3][*n1]+= * (local+2);
global[*n2][*n3]+= * (local+5);
global[*n3][*n2]+= * (local+5);
//Assembling load vector
b[*n1]+= *be;
b[*n2]+= *(be+1);
b[*n3]+= *(be+2);
}
 
P

pete

Babak said:
Hi Everyone,

I've written a standard
C code for a simple finite element analysis
in MSVC++ . When I save the file as a cpp file, it compiles and runs
perfectly, but when I save it as a c file,
there are lots of errors and
warnings in compiling stage. I am really confused about this problem
because I'm not even familiar with C++
and my code only includes simple
C functions. Can anybody please tell me what's my mistake?
Here is my entire code (Sorry it's a little lengthy!).

That's much better than being vague.

Most likely your c code is being compiled according to C89 rules
with some C99 features as extensions, like // comments.

Consolidate all of you object declarations in main
at the begining. C89 doesn't allow declarations
after statements within a compound statement {within a block}.
And don't initialise arrays of float, with {NULL},
use {0} instead.

int main(void)
{
FILE *fp;
FILE *ft;
FILE *fer;
FILE *ftest;
int i;
int j;
int NUMNODE=0;//number of nodes
int NUMELE=0;//number of elemnts
char *str;
struct node *nd;
struct element *ele;
int *g;
float **K;
float *b;
float Me[3][3]={0};
float be [3] [1]={0};
int n1;
int n2;
int n3;
 
F

Frederick Gotham

Babak posted:

str=(char *)malloc(sizeof(char)*80);


Just so you know, sizeof(char) is always 1. You could have written:

str = malloc(80);


The cast is redundant.

int n1=(((ele+i)->p1)-1);
int n2=(((ele+i)->p2)-1);
int n3=(((ele+i)->p3)-1);


You might be pleased to know that C has another way of writing that:


int n1 = ele.p1 - 1;
int n2 = ele.p2 - 1;
int n3 = ele.p3 - 1;


float param=(((nd+i)->y) * ((nd+i)->y) + (((nd+i)->x)-10) *
(((nd+i)->x)-10));


Again here:


float param = nd.y * nd.y * (nd.x - 10) * (nd.x - 10);

global[*n1][*n1]+= * (local);
global[*n2][*n2]+= * (local+4);
global[*n3][*n3]+= * (local+8);
global[*n1][*n2]+= * (local+1);
global[*n2][*n1]+= * (local+1);
global[*n1][*n3]+= * (local+2);
global[*n3][*n1]+= * (local+2);
global[*n2][*n3]+= * (local+5);
global[*n3][*n2]+= * (local+5);
//Assembling load vector
b[*n1]+= *be;
b[*n2]+= *(be+1);
b[*n3]+= *(be+2);

Again here:

global[*n1][*n1] += *local;
global[*n2][*n2] += local[4];
global[*n3][*n3] += local[8];
 
R

Richard Tobin

Babak said:
I've written a standard C code for a simple finite element analysis
in MSVC++ . When I save the file as a cpp file, it compiles and runs
perfectly, but when I save it as a c file, there are lots of errors and
warnings in compiling stage. I am really confused about this problem
because I'm not even familiar with C++ and my code only includes simple
C functions. Can anybody please tell me what's my mistake?

You use two features which are allowed in C++ and C99 but not C90:
slash-slash comments and declarations mixed with code. Perhaps
your compiler does not accept these new features. Change your
comments to /* this style */ and move your declarations to the
start of the function or block.
float Me[3][3]={NULL};
float be [3] [1]={NULL};

This is also wrong; you should use 0 rather than NULL. NULL is
for pointers. (It may work on some systems depending on how NULL
is defined, but it's wrong anyway.)

-- Richard
 
B

Babak

Thank you!

Moving all the declarations to the begining of main, changing NULL
to {0) and revising the format of comments solve the problem with MSVC.
I'm not still able to run my code with gcc. When I type

gcc -0 pre2 pre2.c -lm

in cygwin , the .exe file is created. But when I run it, the program
does not terminate, although it doesn't declare any errors!

Frederick said:
Babak posted:

str=(char *)malloc(sizeof(char)*80);


Just so you know, sizeof(char) is always 1. You could have written:

str = malloc(80);


The cast is redundant.

int n1=(((ele+i)->p1)-1);
int n2=(((ele+i)->p2)-1);
int n3=(((ele+i)->p3)-1);


You might be pleased to know that C has another way of writing that:


int n1 = ele.p1 - 1;
int n2 = ele.p2 - 1;
int n3 = ele.p3 - 1;


float param=(((nd+i)->y) * ((nd+i)->y) + (((nd+i)->x)-10) *
(((nd+i)->x)-10));


Again here:


float param = nd.y * nd.y * (nd.x - 10) * (nd.x - 10);

global[*n1][*n1]+= * (local);
global[*n2][*n2]+= * (local+4);
global[*n3][*n3]+= * (local+8);
global[*n1][*n2]+= * (local+1);
global[*n2][*n1]+= * (local+1);
global[*n1][*n3]+= * (local+2);
global[*n3][*n1]+= * (local+2);
global[*n2][*n3]+= * (local+5);
global[*n3][*n2]+= * (local+5);
//Assembling load vector
b[*n1]+= *be;
b[*n2]+= *(be+1);
b[*n3]+= *(be+2);

Again here:

global[*n1][*n1] += *local;
global[*n2][*n2] += local[4];
global[*n3][*n3] += local[8];
 
P

pete

Babak said:
Thank you!

Moving all the declarations to the begining of main, changing NULL
to {0) and revising the format of comments
solve the problem with MSVC.
I'm not still able to run my code with gcc. When I type

gcc -0 pre2 pre2.c -lm

in cygwin , the .exe file is created. But when I run it, the program
does not terminate, although it doesn't declare any errors!

Your code is long,
I don't have
"femesh2_p.txt" or "femesh2_t.txt" or "femesh2_er.txt",
and there are many obvious portability problems with the code,
so I don't anticipate debugging it quickly.
 
B

Babak

Can you pls at least give me some general ideas about these obvious
portability problems.
 
P

pete

Babak said:
Can you pls at least give me some general ideas about these obvious
portability problems.

It's not really as bad as I said.
exit(1);
is the only obvious portability problem.

It's mostly just the length of the code
and the nonavailabilty of the text files
and that I don't know exactly what the code is supposed to do.
 
C

Chris Torek

Here is my entire code (Sorry it's a little lengthy!).

Better "too much" than "too little" (at least usually :) ).

Others already provided some comments; here are some more.
fp=fopen("femesh2_p.txt", "r");
ftest=fopen("nodeindex_2.txt", "w");
checkfile (fp);
checkfile (ftest);
[where "checkfile" terminates the program if its argument is NULL]

It would probably be nicer to say *which* file(s) cannot be opened.
Also, while it is not "truly portable", printing a "reason" for the
failure to open the file tends to work and tends to be useful. For
instance:

fp = fopen("femesh2_p.txt", "r");
if (fp == NULL) {
fprintf(stderr, "myprog: unable to open %s for reading: %s\n",
"femesh2_p.txt", strerror(errno));
exit(EXIT_FAILURE);
}
ftest = fopen("nodeindex_2.txt", "w");
if (ftest == NULL) {
fprintf(stderr, "myprog: unable to open %s for writing: %s\n",
"nodeindex_2.txt", strerror(errno));
exit(EXIT_FAILURE);
}
while (!feof(fp)) {

This loop is (virtually) always wrong. See the comp.lang.c FAQ,
question 12.2 said:
fcloseall();

This is not a standard function. Presumably you mean to fclose()
fp and/or ftest here (note, I am just guessing).
while (!feof(ft)) {

Another instance of an (almost-)always-incorrect loop for reading
files. (Rule for beginners: never use feof(). Rule for later:
test feof() once, after the loop ends, if you want to distinguish
between "input ended because of normal ordinary EOF" from "input
ended because of bad CD-ROM or similar media problem".)

(Probably some more of the code could stand to be factored into
functions, but in a quick scan, I did not spot any other major
errors here.)
void read_node_data (FILE * input, struct node *nod)
{
fscanf (input,"%f", &(nod->x));
fscanf (input,"%f", &(nod->y));
}

The fscanf() function can fail; it may be worth checking the return
value here. You can also do this scan in one shot:

if (fscanf(input, "%f%f", &nod->x, &nod->y) != 2)
... do something about that ...

The possible reasons for failure here range from "error reading the
data off the input file" to "input file is working fine but contains
the Encyclopedia Britannica, instead of a sequence of floating point
numbers". All fscanf() tells you is whether it read and converted
(i.e., assigned) everything it was told to read (here, two "%f"s).

(For that matter, printf() and fprintf() can fail, although testing
every single call tends to be painful at best. One call to ferror(fp)
at the end of all, or each group of, writing, to check for failures
like disk-full, tends to be good enough.)
 
N

Neil

Richard said:
You use two features which are allowed in C++ and C99 but not C90:
slash-slash comments and declarations mixed with code. Perhaps
your compiler does not accept these new features. Change your
comments to /* this style */ and move your declarations to the

You Know I have seen this for around 15 years. The C standard may have
just picked it up, But I have not had a compiler reject a // comment
since the early 90's
MSVC 6.0 does support them (so did MSVC 1.5)
It is NOT the problem here. // or /* */ has become a style issue. or
the standard would have added it a decade ago.


start of the function or block.
float Me[3][3]={NULL};
float be [3] [1]={NULL};

This is also wrong; you should use 0 rather than NULL. NULL is
for pointers. (It may work on some systems depending on how NULL
is defined, but it's wrong anyway.)

-- Richard
 
R

Richard Heathfield

Neil said:
Richard Tobin wrote:


You Know I have seen this for around 15 years. The C standard may have
just picked it up, But I have not had a compiler reject a // comment
since the early 90's
MSVC 6.0 does support them (so did MSVC 1.5)

Odd, that. I get a diagnostic message from MSVC in code that uses //, just
as I do from gcc. Perhaps you need to crank up your diagnostics level.
 
M

Martin Ambuhl

Neil said:
You Know I have seen this for around 15 years. The C standard may have
just picked it up, But I have not had a compiler reject a // comment
since the early 90's

Your code as posted has illegal code -- even in C99 and C++ -- because
of your // comments. This is because it gets broken up into reasonable
length lines along the propagation chain. This leaves stranded parts of
your comments as "code" since those parts are no longer on a line
beginning with "//". It is an error to post code with // comments even
in a C++ newsgroup, since they leave uncompilable crap in their wake.

Your limited experience does not define C. Declarations intermeshed
with code is almost always poor programming style; comments which break
your program if the line is split is just stupid.
MSVC 6.0 does support them (so did MSVC 1.5)

MS does not define the C language. If you want to use a MS proprietary
language, they have a whole stable of them they would love you to be
locked into. C ain't one of them.
It is NOT the problem here. // or /* */ has become a style issue. or
the standard would have added it a decade ago.

That comment reflects only on your own ignorance. Code that becomes
broken when you post it is your problem; if having broken code is your
"style" preference, so be it.
 
I

Ian Collins

Martin said:
Your code as posted has illegal code -- even in C99 and C++ -- because
of your // comments. This is because it gets broken up into reasonable
length lines along the propagation chain. This leaves stranded parts of
your comments as "code" since those parts are no longer on a line
beginning with "//". It is an error to post code with // comments even
in a C++ newsgroup, since they leave uncompilable crap in their wake.
Looks like your slagging off the wrong poster.
 
K

Kenneth Brody

Frederick said:
Babak posted: [...]
global[*n1][*n1]+= * (local);
global[*n2][*n2]+= * (local+4);
global[*n3][*n3]+= * (local+8);
[...]

Again here:

global[*n1][*n1] += *local;
global[*n2][*n2] += local[4];
global[*n3][*n3] += local[8];
[...]

<mode type="nit-pick">

If you're going to rewrite these lines to use "local[4]", "local[8]",
and so on, why use "*local" rather than "local[0]"?

</mode>

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
D

Default User

Babak said:
Thank you!

Please don't top-post. Your replies belong following or interspersed
with properly trimmed quotes. See the other 99% of the posts in this
group.




Brian
 
M

Martin Ambuhl

Looks like your slagging off the wrong poster.

No, I responded to Neil's bogus points. It is true that Neil was not
the OP of the code, (a certain "Babak", that was). Since Neil
completely associated himself with the errors in that code and asserted
its "correctness" because his Microsoft compiler let him get away with
it, I did not check to see that we were dealing with two idiots rather
than just one. No apology is offered; Neil made it clear that Babak's
errors were also his and he defended them on the basis of his limited
experience.
 
M

Martin Ambuhl

Richard said:
More stupid than quoted strings?

I'm not wure what you mean. I think you mean longish quoted strings,
which also may be broken in the propagation chain. That is a problem,
which I try to handle with shorter strings:
char foo[] = "Here is one short line. "
"And here's its continuation.\n";
rather than
char bar[] = "Here is one short line. And here's its continuation.\n";

That last line may (or may not) show up at your newsreader as broken.
 
B

Babak

Martin said:
Richard said:
More stupid than quoted strings?

I'm not wure what you mean. I think you mean longish quoted strings,
which also may be broken in the propagation chain. That is a problem,
which I try to handle with shorter strings:
char foo[] = "Here is one short line. "
"And here's its continuation.\n";
rather than
char bar[] = "Here is one short line. And here's its continuation.\n";

That last line may (or may not) show up at your newsreader as broken.

Dear all,

I finally solved the problem with gcc. I used some declared
variables without initialization in my code which seems to make
problems with gcc (but not MSVC).
I'm very thankful for all your useful comments. Although a guy
named me an IDIOT, I think it is worth to learn new things even from a
harsh teacher!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top