470,849 Members | 1,275 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,849 developers. It's quick & easy.

how to organize my main file ?

By main file, I mean the one which contains the main routine. Can some
one please provide suggestions as to how I can improve the
organization of main file ? I have just though about a rough skeleton.

In my ray tracing project, I have to carry out following task (in
sequence)

1. Read the mesh from an ascii file and store it in the mesh data
structure.
2. Create a ray list and store it in a ray list.
3. Create the binary space partitioning tree for fast mesh traversal.
4. Trace all the rays and calculate the scattered and incident
electric fields.

I'm thinking of writing a function for every task.

#include "main.h"

static mesh *m; /* pointer to the mesh */
static bsptree *tree; /* pointer to the bsp tree */
static ray *raylist; /* pointer to the ray list */

/* function prototypes */

int read_mesh(char *);
int init_plane_wave(void);
int create_bsp_tree(void);
int calc_e_fields (void);
/* Provide the name of the ascii file(from which mesh is to be read)
as a command line argument eg. main sphere.dat */

int main(int argc char *argv[])
{
if(argc < 2)
{
fprintf(stderr, "Insufficient argumens\n");
return -1;
}

if(argc 2)
{
fprintf(stderr, "Too many arguments\n");
return -1;
}

if(read_mesh(argv[1])
return -1;
if(init_plane_wave())
return -1;
if(create_bsp_tree())
return -1;
if(calc_e_fields())
return -1;

return 0;
}

/* I decided to make the above data structures as static global
because they are needed throughout the program */

int read_mesh(char *filename)
{
FILE *fp;

fp = fopen(filename, "r");
if(fp == NULL)
{
fprintf(stderr, "Error while opening the file %s\n", filename);
return -1;
}
m = malloc(sizeof *m);
if(m == NULL)
{
fprintf(stderr, "Couldn't allocate memory for the mesh\n");
return -1;
}
/* parse_dat_file returns -1 if error occured while parsing file */
if(parse_dat_file(fp, &m))
return -1;
}

/* This function will initiailize the plane as in read the
specification related to a plane wave like frequency, electric field
at reference point, direction of the plane wave etc. It will allocate
memory for the ray list. After this it will call init_rays which
initializes a set of parallel rays. A plane wave is being simulated by
a dense grid of parallel rays */

int init_plane_wave(void)
{
...
...
}

/* This function will read the maximum allowable depth for the tree ,
allocate memory for it*/

int create_bsp_tree(void)
{

}

/* This function will call the raytrace function and after that it
will perform some calculations to find out the scattered and incident
electric fields */

int calc_e_fields (void)
{

}

Jun 27 '08 #1
29 1804
I have another question: Is it ok to write a function to destroy all
the objects(Its not just a simple 'free' call btw, there are lists
within objects which must be destroyed first)
Jun 27 '08 #2
In article <66**********************************@y22g2000prd. googlegroups.com>,
pereges <Br*****@gmail.comwrote:
>I have another question: Is it ok to write a function to destroy all
the objects(Its not just a simple 'free' call btw, there are lists
within objects which must be destroyed first)
Sure, why not? As long as the objects are dynamically allocated, that is.
--
"MAMA: Oh--So now it's life. Money is life. Once upon a time freedom
used to be life--now it's money. I guess the world really do change.
WALTER: No--it was always money, Mama. We just didn't know about it."
-- Lorraine Hansberry
Jun 27 '08 #3
pereges said:
By main file, I mean the one which contains the main routine. Can some
one please provide suggestions as to how I can improve the
organization of main file ? I have just though about a rough skeleton.

In my ray tracing project, I have to carry out following task (in
sequence)

1. Read the mesh from an ascii file and store it in the mesh data
structure.
2. Create a ray list and store it in a ray list.
3. Create the binary space partitioning tree for fast mesh traversal.
4. Trace all the rays and calculate the scattered and incident
electric fields.

I'm thinking of writing a function for every task.
It seems to me that tasks 1-3 might reasonably be called initialisation.
Task 4 appears to be the bit that does the useful processing.

A function for every task is always a good idea, but why not abstract your
first three tasks into a function called initialise() or something like
that. It might look something like this:

#include "whatever.h"

int initialise(const char *infile)
{
int rc = read_mesh(infile); /* change read_mesh() to take const char *
*/
if(0 == rc)
{
rc = init_plane_wave();
}
if(0 == rc)
{
rc = create_bsp_tree();
}
return rc;
}

and then main would look something like this:

#include <stdio.h>
#include <stdlib.h>
#include "whatever.h"

int main(int argc, char **argv)
{
int result = EXIT_FAILURE;

if(argc != 2)
{
printf("%s arguments\n", argc < 2 ? "Insufficient" : "Too many");
}
else
{
if(0 == initialise(argv[1]))
{
if(0 == calc_e_fields())
{
result = EXIT_SUCCESS;
}
}
}
return result;
}

You might want to put main() and initialise() in one source file (your
"main file" as you call it), the initialisation routines (read_mesh and
the other two) in, say, initialise.c, and the calcs in calcs.c - this will
help to keep each source file down to a manageable size and make things
easier for you to find.

Note that a -1 return value from main isn't guaranteed to be meaningful,
whereas EXIT_FAILURE is.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #4
On Jun 17, 9:13 pm, Richard Heathfield <r...@see.sig.invalidwrote:
It seems to me that tasks 1-3 might reasonably be called initialisation.
Task 4 appears to be the bit that does the useful processing.

A function for every task is always a good idea, but why not abstract your
first three tasks into a function called initialise() or something like
that. It might look something like this:

#include "whatever.h"

int initialise(const char *infile)
{
int rc = read_mesh(infile); /* change read_mesh() to take const char *
*/
if(0 == rc)
{
rc = init_plane_wave();
}
if(0 == rc)
{
rc = create_bsp_tree();
}
return rc;

}

and then main would look something like this:

#include <stdio.h>
#include <stdlib.h>
#include "whatever.h"

int main(int argc, char **argv)
{
int result = EXIT_FAILURE;

if(argc != 2)
{
printf("%s arguments\n", argc < 2 ? "Insufficient" : "Too many");
}
else
{
if(0 == initialise(argv[1]))
{
if(0 == calc_e_fields())
{
result = EXIT_SUCCESS;
}
}
}
return result;

}

You might want to put main() and initialise() in one source file (your
"main file" as you call it), the initialisation routines (read_mesh and
the other two) in, say, initialise.c, and the calcs in calcs.c - this will
help to keep each source file down to a manageable size and make things
easier for you to find.
Thanks, I think this is a very good idea but I think the calcs.c file
will not span more than 30-40 lines. But I think it is better this way
because later on if there is a requirement to calculate some other
things(eg. surface currents, magnetic fields , whatever etc), then all
that code can go into this file.
Note that a -1 return value from main isn't guaranteed to be meaningful,
whereas EXIT_FAILURE is.
Why ?
I have seen that everytime a C program fails, the process returns some
non zero value(Pelles C compiler reports this). So what is wrong in
returning -1 ? Is this only applicable to main function or others as
well ? I usually use

#define SUCCESS 0
#define FAILURE -1

as return values for functions other than main.
Jun 27 '08 #5
pereges wrote:
On Jun 17, 9:13 pm, Richard Heathfield <r...@see.sig.invalidwrote:
<snip>
>Note that a -1 return value from main isn't guaranteed to be
meaningful, whereas EXIT_FAILURE is.

Why ?
Because the C standard says so.
I have seen that everytime a C program fails, the process returns some
non zero value(Pelles C compiler reports this).
Perhaps, but what a C program returns to the host system after it has
finished (or to be more precise, what value your system indicates that
the program has returned) is not specified by the standard, and
therefore your observations may not be valid for one or more systems.

What the standard does specify is what value you can portably use as an
argument to the exit function or as an expression with the return
keyword. These are 0 or EXIT_SUCCESS to indicate that the program has
terminated normally or EXIT_FAILURE to indicate that the program has
terminated abnormally. Note that the value that the host system may
report to you as the termination status code of your program need not
match the value that you supplied to exit or return. The C runtime code
can perform translations on this value to ensure compatibility with the
protocols of the host environment.

IOW, there could exit a system where -1 indicates successful
termination. This would render your code broken. On the other hand if
you use EXIT_FAILURE in the place of -1 your program would work
correctly on all systems which are fully conforming to the C standard.
So what is wrong in
returning -1 ? Is this only applicable to main function or others as
well ?
Yes.
I usually use

#define SUCCESS 0
#define FAILURE -1

as return values for functions other than main.
In C zero is taken as boolean false and any other value is taken as
boolean true. Your macros above conflict against this, but in this
respect, so does a lot of C code including portions of the standard
library. Also the convention for functions is that a return of zero
indicates successful completion and a non-zero return indicates
unsuccessful completion.

I would much rather use C99's bool type rather than these macros, as
they are much abused and will merely confuse anyone reading your code.

Jun 27 '08 #6
"pereges" <Br*****@gmail.comwrote in message
news:66**********************************@j33g2000 pri.googlegroups.com...
On Jun 17, 9:13 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>Note that a -1 return value from main isn't guaranteed to be meaningful,
whereas EXIT_FAILURE is.

Why ?
I have seen that everytime a C program fails, the process returns some
non zero value(Pelles C compiler reports this). So what is wrong in
returning -1 ?
It's not really 'wrong', it's simply not standard (thus
not portable). The only return values for main() which
are guaranteed to be portable (to a standard-conforming
implementation) are zero (0), or one of the macros
'EXIT_SUCCESS' or 'EXIT_FAILURE'. These macros are
defined in standard header <stdlib.h>. Their actual
values can and do vary among implementations, so you
could get different behavior with a different implementation
and/or platform.

If you're using a compiler which conforms to the most
recent (1999) C standard, you can omit the return
statement entirely, whereupon the program will behave
as if a 'return 0' were written. While perfectly valid,
many folks still frown upon doing this, and would rather
see an explicit return statement to make things perfectly
clear.
Is this only applicable to main function or others as
well ?
The above requirements I cited for a portable return value
apply to the 'main()' function, and I believe also the
'exit()' function. You can do whatever you like with your
own functions (subject, of course, to language rules).

>I usually use

#define SUCCESS 0
#define FAILURE -1
Don't Do That. You've redefined standard macros. I'm
not sure what the standard says about the behavior here,
it could be undefined. Use the 'framework' provided by
the implementation, e.g. standard constructs such as
'EXIT_FAILURE'. If you try to circumvent or change their
intended behavior, imo you've just introduced potential
problems for no good reason.

-Mike
Jun 27 '08 #7
In article <6-******************************@earthlink.com>,
Mike Wahler <mk******@mkwahler.netwrote:
>"pereges" <Br*****@gmail.comwrote in message
news:66**********************************@j33g200 0pri.googlegroups.com...
>On Jun 17, 9:13 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>>Note that a -1 return value from main isn't guaranteed to be meaningful,
whereas EXIT_FAILURE is.

Why ?
I have seen that everytime a C program fails, the process returns some
non zero value(Pelles C compiler reports this). So what is wrong in
returning -1 ?

It's not really 'wrong', it's simply not standard (thus
not portable). The only return values for main() which
In this newsgroup, "wrong" and "not standard" are synonymous.
See also "morally bankrupt".

Jun 27 '08 #8
So, EXIT_FAILURE and EXIT_SUCCESS can be used in any function other
than main. Mostly I have seen that they are not used outside main.
Jun 27 '08 #9
pereges wrote:
I have another question: Is it ok to write a function to destroy all
the objects(Its not just a simple 'free' call btw, there are lists
within objects which must be destroyed first)
I assume you will be calling such a function either just before program
termination or after a major task has been completed. As long as it
does not free memory still in use, or try to free nonexistent memory,
it should be functionally okay. Whether such a strategy will suit your
application depends on many other factors.

Jun 27 '08 #10
On Jun 17, 11:12 pm, santosh <santosh....@gmail.comwrote:
I assume you will be calling such a function either just before program
termination or after a major task has been completed.
just before the termination. The last function to be called.
As long as it
does not free memory still in use, or try to free nonexistent memory,
it should be functionally okay. Whether such a strategy will suit your
application depends on many other factors.
like for eg. ? mine is a pretty straight forward numerical computation/
simulation program. I was also wondering what is the point in freeing
the dynamic memory just before the program terminates because the
objects will be destroyed once the program terminates anyways.

Jun 27 '08 #11
pereges wrote:
So, EXIT_FAILURE and EXIT_SUCCESS can be used in any function other
than main.
You can do so, as long as you are internally self consistent, but this
is rare. It is more common to return either zero or one. Which of these
is used to signal success and which one failure really depends on local
convention. All that matters is consistency.

For example you could have a function return the int value 1 for success
and zero for failure. Then you might test a function like this:

if (!do_foo()) {
/* handle error */
}

The code for the reverse situation might be like:

if (do_foo()) {
/* handle error */
}

Note that this method allows for multiple error codes, which is usually
convenient.

It's common (and more robust) to define an enumeration for default
success and failure and typedef the enum. You can also use #define
macros as you did above.

You might also want to use C99's bool type.

For functions returning pointer values, usually a return of NULL
indicates failure.
Mostly I have seen that they are not used outside main.
No. It's customary for most non-trivial applications to have their own
error handling conventions. It's more work up-front, but pays off as
the complexity of the program grows.

Jun 27 '08 #12

"pereges" <Br*****@gmail.comwrote in message
news:3d**********************************@z24g2000 prf.googlegroups.com...
So, EXIT_FAILURE and EXIT_SUCCESS can be used in any function other
than main.
That's not what I said, but they could be. They are
intended to be used to communicate a program's completion
status (i.e. success or failure) to the host system, thus
typically used only with 'main()' or 'exit()'. I've never
seen them used for anything else, but that doesn't mean
someone never did. :-)

Mostly I have seen that they are not used outside main.
True.

-Mike
Jun 27 '08 #13

"pereges" <Br*****@gmail.comwrote in message
news:5c**********************************@c19g2000 prf.googlegroups.com...
On Jun 17, 11:12 pm, santosh <santosh....@gmail.comwrote:
>I assume you will be calling such a function either just before program
termination or after a major task has been completed.

just before the termination. The last function to be called.
>As long as it
does not free memory still in use, or try to free nonexistent memory,
it should be functionally okay. Whether such a strategy will suit your
application depends on many other factors.

like for eg. ? mine is a pretty straight forward numerical computation/
simulation program. I was also wondering what is the point in freeing
the dynamic memory just before the program terminates because the
objects will be destroyed once the program terminates anyways.
Most modern operating systems will indeed reclaim allocated memory
upon termination of an application, but the language does not
guarantee this (it cannot, since C can be implemented on a platform
with no OS ('free-standing implementation'). IMO the best practice
is to do as my mother used to tell me, "put things back the way you
found them." IOW if you allocate a resource, free it when you're done.

-Mike

Jun 27 '08 #14
pereges wrote:

[ ... ]
I was also wondering what is the point in freeing
the dynamic memory just before the program terminates because the
objects will be destroyed once the program terminates anyways.
It will reduce the number of false positives that memory checkers like
Valgrind will report. It's also better form, even though it may not be
necessary under modern operating systems.

Jun 27 '08 #15

"pereges" <Br*****@gmail.comwrote in message
news:66**********************************@y22g2000 prd.googlegroups.com...
>I have another question: Is it ok to write a function to destroy all
the objects(Its not just a simple 'free' call btw, there are lists
within objects which must be destroyed first)
Inital task:
1. Read the mesh from an ascii file and store it in the mesh data
structure.
2. Create a ray list and store it in a ray list.
3. Create the binary space partitioning tree for fast mesh traversal.
4. Trace all the rays and calculate the scattered and incident
electric fields.

Do it like this

int main(int argc, char **argv)
{
MESH *mesh;
RAYLIST *raylist;
BSP *bsp;
IMAGE *img;

/* turn the ascii input file into a mesh */
mesh = createmesh(argv[1]) ;
if(!mesh)
{
fprintf(stderr, "Cannot create mesh\n");
exit(EXIT_FAILURE);
}
/* create everything else we need */
raylist = creatraylist(mesh);
bsp = createbsp(mesh, raylist);
img = createimage(1024, 1024);

/* do the work here */
raytrace(img, raylist, bsp);

saveimage(img, "image.bmp");
/* destroy everything */
killimage(img);
killbsp(bsp);
killraylist(raylist);
killmesh(mesh);

return 0;
}

Your main function creates all the objects you need, prints out an error
message if any of them fail, calls a high level function to do the work,
then destroys all the objects and returns. Other modules actually manage the
objects. Clearly the mesh and image objects are highly reusable. Only you as
program designer know exactly what goes in the "raylist" and binary
separating tree, and how these objects are passed to the renderer. However
the scope for design is reduced to these three highly specific modules.

In a real program you also need to print out a usage message, and probably
parse some options. This adds only a bit of complexity to main().

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
Jun 27 '08 #16
pereges skrev:
By main file, I mean the one which contains the main routine. Can some
one please provide suggestions as to how I can improve the
organization of main file ? I have just though about a rough skeleton.

In my ray tracing project, I have to carry out following task (in
sequence)

1. Read the mesh from an ascii file and store it in the mesh data
structure.
2. Create a ray list and store it in a ray list.
3. Create the binary space partitioning tree for fast mesh traversal.
4. Trace all the rays and calculate the scattered and incident
electric fields.

I'm thinking of writing a function for every task.
I assume, you have no need for sophisticated error handling, then there
is no need to propagate error codes all over the place, just log error
and die.

So, this would be my initial main:

#include <stdio.h>
#include "ray_track.h"

int main(int argc, char *argv[])
{
struct ray_track rt;

ray_open( &rt, argc, argv);
ray_fload_mesh( &rt, fname_mesh);
ray_create_raylist (&rt);
ray_create_bsp_three(&rt);
ray_calc_scattering (&rt);
ray_close(&rt);

return EXIT_SUCCESS;
}
The header file would look something like:
#ifndef RAY_TRACK_H
#define RAY_TRACK_H

struct ray_track
{
const char *fname_mesh;

struct mesh *mesh;
struct ray *raylist;
struct bsp_three *bsp_three;

/*! logging & error handlers */
void (*trace) (const char *msg);
void (*err_warn ) (int err, int line, const char *msg);
void (*err_fatal) (int err, int line, const char *msg);
};

/*! Ray track function prototypes */
void ray_open (struct ray_track *, int argc, char **argv);
void ray_create_mesh (struct ray_track *, const char *fname_mesh);
void ray_create_raylist (struct ray_track *);
void ray_create_bsp_three (struct ray_track *);
void ray_calc_scattering (struct ray_track *);
void ray_close (struct ray_track *);

#endif /* !RAY_TRACK_H*/
--
Tor <bw****@wvtqvm.vw | tr i-za-h a-z>
Jun 27 '08 #17
Mike Wahler said:
"pereges" <Br*****@gmail.comwrote in message
news:66**********************************@j33g2000 pri.googlegroups.com...
<snip>
>
>>I usually use

#define SUCCESS 0
#define FAILURE -1

Don't Do That. You've redefined standard macros.
Neither SUCCESS nor FAILURE is a standard macro.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #18
On Jun 18, 1:45 am, Tor Rustad <tor_rus...@hotmail.comwrote:
I assume, you have no need for sophisticated error handling, then there
is no need to propagate error codes all over the place, just log error
and die.
I do need a good error handling mechanism. Right now, I just check for
error condition and use fprintf to report the messages to stderr. It
tends to get a little verbose sometimes.
So, this would be my initial main:

#include <stdio.h>
#include "ray_track.h"

int main(int argc, char *argv[])
{
struct ray_track rt;

ray_open( &rt, argc, argv);
ray_fload_mesh( &rt, fname_mesh);
ray_create_raylist (&rt);
ray_create_bsp_three(&rt);
ray_calc_scattering (&rt);
ray_close(&rt);

return EXIT_SUCCESS;

}

The header file would look something like:

#ifndef RAY_TRACK_H
#define RAY_TRACK_H

struct ray_track
{
const char *fname_mesh;

struct mesh *mesh;
struct ray *raylist;
struct bsp_three *bsp_three;

/*! logging & error handlers */
void (*trace) (const char *msg);
void (*err_warn ) (int err, int line, const char *msg);
void (*err_fatal) (int err, int line, const char *msg);

};

/*! Ray track function prototypes */
void ray_open (struct ray_track *, int argc, char **argv);
void ray_create_mesh (struct ray_track *, const char *fname_mesh);
void ray_create_raylist (struct ray_track *);
void ray_create_bsp_three (struct ray_track *);
void ray_calc_scattering (struct ray_track *);
void ray_close (struct ray_track *);

#endif /* !RAY_TRACK_H*/
Can you please given an example of these three functions ? what are
they used for ? :

void (*trace) (const char *msg);
void (*err_warn ) (int err, int line, const char *msg);
void (*err_fatal) (int err, int line, const char *msg);

How to differentiate between a fatal error and a warning ?
Jun 27 '08 #19

"Richard Heathfield" <rj*@see.sig.invalidwrote in message
news:7N******************************@bt.com...
Mike Wahler said:
>"pereges" <Br*****@gmail.comwrote in message
news:66**********************************@j33g200 0pri.googlegroups.com...
<snip>
>>
>>>I usually use

#define SUCCESS 0
#define FAILURE -1

Don't Do That. You've redefined standard macros.

Neither SUCCESS nor FAILURE is a standard macro.
Oops. Now I'm seeing things. :-)

-Mike
Jun 27 '08 #20
On Jun 18, 9:25 am, pereges <Brol...@gmail.comwrote:
>
Can you please given an example of these three functions ? what are
they used for ? :

void (*trace) (const char *msg);
void (*err_warn ) (int err, int line, const char *msg);
void (*err_fatal) (int err, int line, const char *msg);

How to differentiate between a fatal error and a warning ?
Where did you get these functions? These functions are not there in
the Standard C Library.
<off-topic>
Richard Stevens have used similar functions in his Unix Network
Programming Books. May be you got these functions from there. When you
issue a warning, a diagnostic is sent to stderr or logged and the
process continues. In case of fatal errors, you display/log an error
message and the process terminates.
</off-topic>

Jun 27 '08 #21
rahul said:
On Jun 18, 9:25 am, pereges <Brol...@gmail.comwrote:
>>
Can you please given an example of these three functions ? what are
they used for ? :

void (*trace) (const char *msg);
void (*err_warn ) (int err, int line, const char *msg);
void (*err_fatal) (int err, int line, const char *msg);

How to differentiate between a fatal error and a warning ?
Where did you get these functions?
Nowhere. They're not functions. They're function pointers.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #22
pereges wrote:

<snip>
Can you please given an example of these three functions ? what are
they used for ? :

void (*trace) (const char *msg);
I guess that this is used to print a backtrace, preceded by the
customised message.
void (*err_warn ) (int err, int line, const char *msg);
This is to print a warning - the line where it occured, and the text
pointed by 'msg', with perhaps other information. You might call it
like this:

err_warn(errno, __LINE__, "Custom message.");
void (*err_fatal) (int err, int line, const char *msg);
Same as above except that it should terminate the program (or call a
function that does so) after printing the diagnostics.
How to differentiate between a fatal error and a warning ?
That's context specific. Generally failure to obtain critical resources
like files and memory are fatal, while things like network packet loss,
or failure of a non-essential component could just be regarded as
insufficient to terminate the program. In general any exception after
which you can still proceed with all or most of the functionality of
the program intact can be just a "warning" while a fatal error is one
that forces you to stop.

Jun 27 '08 #23
santosh said:
pereges wrote:

<snip>
>Can you please given an example of these three functions ? what are
they used for ? :

void (*trace) (const char *msg);

I guess that this is used to print a backtrace, preceded by the
customised message.
You're sure it isn't used to point at a function, then?

(Ditto, twice, for the other two.)

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #24
On Tue, 17 Jun 2008 16:33:24 UTC, pereges <Br*****@gmail.comwrote:
Note that a -1 return value from main isn't guaranteed to be
meaningful,
whereas EXIT_FAILURE is.

Why ?
That is because the standard requests it.
I have seen that everytime a C program fails, the process returns some
non zero value(Pelles C compiler reports this). So what is wrong in
returning -1 ? Is this only applicable to main function or others as
well ? I usually use

#define SUCCESS 0
#define FAILURE -1

as return values for functions other than main.
main() is the interface between the system that is calling your
program. So the standard tries to give you and any system that is able
to run programs written in C rules for the interface, that is
1. how to give parameters to the program at startup
2. values allowed to return to the system

There are systems on the maret who may fail miserably when main() or
exit() returns other values than 0 or EXIT_FAIlTURE.

I know of some systems that gets confused when main() or exit() tries
to return an int outside the range 0-255, even as they accept any
value inside that value, extending the C standard with system
dependant wider range. But the system will go into undefinded behavior
by receiving a value outside 0-255 in from main()/exit().

On other hand it is complete on you to define each and any value a
function you've ritten can return. So the function can return 42 for
success and 0 for failture or a pointer to a a data type its prototype
defines or something else you means it is the ideal value.

So there are only specified values for the external interface:

The name is main. It returns int with only 2 allowed values and owns 2
different groups of parameters where
group 1 defines zero parameters (VOID)
group 2 defines exactly 2 parameters in defined sequence
first parameter: int argc - the number of parameters given
second parameter: char **argv - an array of pointers to
strings
wheras argv[0] is either NULL or the name of the progrsm
and argv[argc] is always NULL
The names of the parameter are commonly used but not really
defined.
--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2R Deutsch ist da!
Jun 27 '08 #25
Tor Rustad wrote:
>
.... snip ...
>
So, this would be my initial main:

#include <stdio.h>
#include "ray_track.h"

int main(int argc, char *argv[])
{
struct ray_track rt;

ray_open( &rt, argc, argv);
ray_fload_mesh( &rt, fname_mesh);
ray_create_raylist (&rt);
ray_create_bsp_three(&rt);
ray_calc_scattering (&rt);
ray_close(&rt);

return EXIT_SUCCESS;
}
I hope not. You have not included stdlib.h, for EXIT_SUCCESS.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
** Posted from http://www.teranews.com **
Jun 27 '08 #26
Herbert Rosenau wrote:

<snip>
main() is the interface between the system that is calling your
program. So the standard tries to give you and any system that is able
to run programs written in C rules for the interface, that is
1. how to give parameters to the program at startup
2. values allowed to return to the system
[ ... ]
The name is main. It returns int with only 2 allowed values [ ... ]
Actually three viz. 0, EXIT_SUCCESS and EXIT_FAILURE.

<snip>

Jun 27 '08 #27
CBFalconer wrote:

[...]
I hope not. You have not included stdlib.h, for EXIT_SUCCESS.
Yeah, it's a good idea to compile the initial skeleton!

That exercise was left for the student... ;)

--
Tor <bw****@wvtqvm.vw | tr i-za-h a-z>
Jun 27 '08 #28
I'm thinking of declare m, tree, raylist as extern variables in
common.h. Now, I have heard a lot of arguments against extern but what
if its done *properly* ?Well these data structures are frequently
needed in many functions, and continously passing them everywhere is
extermely painful even when they are hardly used in a function. It has
made my code extermely obfuscated, difficult to read, too many
arguments in a function and probably even slower in cases where
recursive functions are used. Let's say mesh *m is passed to a
recursive function. Then in that case, for all the calls a seperate
copy of m will be maintained even if m was utilized in probably 1
statement. Apart from this during the error handling, it is quite easy
to call the killall function from any where in the program where the
error occured and free the data structures allocated upto that point.
No need to pass any parameters.

eg :

void killall()
{
if(m != NULL)
killlmesh();
if(tree != NULL)
killtree();
if(raylist != NULL)
killraylist();
}

Jun 27 '08 #29
On Jun 18, 7:18 pm, "Herbert Rosenau" <os2...@pc-rosenau.dewrote:
On Tue, 17 Jun 2008 16:33:24 UTC, pereges <Brol...@gmail.comwrote:
Note that a -1 return value from main isn't guaranteed to be
meaningful,
whereas EXIT_FAILURE is.
Why ?

That is because the standard requests it.
I have seen that everytime a C program fails, the process returns some
non zero value(Pelles C compiler reports this). So what is wrong in
returning -1 ? Is this only applicable to main function or others as
well ? I usually use
#define SUCCESS 0
#define FAILURE -1
as return values for functions other than main.

main() is the interface between the system that is calling your
program. So the standard tries to give you and any system that is able
to run programs written in C rules for the interface, that is
1. how to give parameters to the program at startup
2. values allowed to return to the system

There are systems on the maret who may fail miserably when main() or
exit() returns other values than 0 or EXIT_FAIlTURE.
And EXIT_SUCCESS. Actually I don't think they will fail miserably. I
believe the standard says that simply it's not guaranteed that a
meaningful value will be returned to the caller.
Jun 28 '08 #30

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

10 posts views Thread by Bruce W...1 | last post: by
2 posts views Thread by key9 | last post: by
4 posts views Thread by Daniel N | last post: by
2 posts views Thread by key9 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.