471,319 Members | 1,612 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,319 software developers and data experts.

How to fix compiler warning

I have a macro that I use across the board for freeing ram. I'd like to
clean up my code so I don't get these warnings.

#define sfree(x) _internal_sfree((void **)&x)
#define _internal_sfree(x) ({ if(x && *x) { free(*x); *x=NULL; } })

void main() {
char *x = (char *) malloc(10);
int *y = (int *) malloc(10);

sfree(x);
sfree(y);
}

results in:

warning: dereferencing type-punned pointer will break strict-aliasing
rules

Aug 24 '07 #1
28 2091
Dave Stafford wrote:
I have a macro that I use across the board for freeing ram. I'd like to
clean up my code so I don't get these warnings.

#define sfree(x) _internal_sfree((void **)&x)
#define _internal_sfree(x) ({ if(x && *x) { free(*x); *x=NULL; } })
Remove the extraneous parenthesis around the expression.
void main() {
If you didn't get a warning for this, crank up the warning level!

--
Ian Collins.
Aug 24 '07 #2
Ian Collins wrote:
Dave Stafford wrote:
>I have a macro that I use across the board for freeing ram. I'd like to
clean up my code so I don't get these warnings.

#define sfree(x) _internal_sfree((void **)&x)
#define _internal_sfree(x) ({ if(x && *x) { free(*x); *x=NULL; } })
Remove the extraneous parenthesis around the expression.
Which still leaves the question why cast to void** and why test for NULL?

How about:

#define sfree(x) _internal_sfree(&x)
#define _internal_sfree(x) { free(*x); *x=NULL; }

--
Ian Collins.
Aug 24 '07 #3
Dave Stafford <in*****@in.validwrites:
I have a macro that I use across the board for freeing ram. I'd like to
clean up my code so I don't get these warnings.

#define sfree(x) _internal_sfree((void **)&x)
#define _internal_sfree(x) ({ if(x && *x) { free(*x); *x=NULL; } })

void main() {
char *x = (char *) malloc(10);
int *y = (int *) malloc(10);

sfree(x);
sfree(y);
}

results in:

warning: dereferencing type-punned pointer will break strict-aliasing
rules
Your macro depends on a gcc-specific extension (see "Statement Exprs"
in the gcc manual).

You take care to avoid passing a null pointer to free(), but
free(NULL) is guaranteed to do nothing.

Take a look at the following version of your program.
================================
#include <stdlib.h>

#define SFREE(p) (free(p), (p) = NULL)

int main(void) {
char *x = malloc(10);
int *y = malloc(10 * sizeof *y);

SFREE(x);
SFREE(y);
return 0;
}
================================

Every change I made fixes a bug in your code:

main() returns int, not void. And since it returns int, you should
return an int.

I renamed the macro from "sfree" to "SFREE"; by convention, most
macros should have all-caps names.

In a macro definition, references to arguments should be enclosed in
parentheses to avoid operator precedence problems.

Casting the result of malloc() is useless, and can hide bugs.

You didn't have a '#include <stdlib.h>'. This is required if you're
going to call malloc(). The casts probably silenced your compiler's
warning about this, but didn't fix the bug (it's like snipping the
wire to a warning light on your car's dashboard).

Allocating 10 bytes for an int* doesn't make much sense if, for
example, sizeof(int) == 4. I changed it to allocate 10 ints.

Recommended reading: the comp.lang.c FAQ, <http://www.c-faq.com/>.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 24 '07 #4
Ian Collins wrote:
Ian Collins wrote:
>Dave Stafford wrote:
>>I have a macro that I use across the board for freeing ram. I'd like to
clean up my code so I don't get these warnings.

#define sfree(x) _internal_sfree((void **)&x)
#define _internal_sfree(x) ({ if(x && *x) { free(*x); *x=NULL; } })
Remove the extraneous parenthesis around the expression.
Which still leaves the question why cast to void** and why test for NULL?

How about:

#define sfree(x) _internal_sfree(&x)
#define _internal_sfree(x) { free(*x); *x=NULL; }
Surely you should check that x!=NULL before calling *any* function on *x?

--
Philip Potter pgp <atdoc.ic.ac.uk
Aug 24 '07 #5
Philip Potter wrote:
Ian Collins wrote:
>Ian Collins wrote:
>>Dave Stafford wrote:
I have a macro that I use across the board for freeing ram. I'd
like to
clean up my code so I don't get these warnings.

#define sfree(x) _internal_sfree((void **)&x)
#define _internal_sfree(x) ({ if(x && *x) { free(*x); *x=NULL; } })

Remove the extraneous parenthesis around the expression.
Which still leaves the question why cast to void** and why test for NULL?

How about:

#define sfree(x) _internal_sfree(&x)
#define _internal_sfree(x) { free(*x); *x=NULL; }

Surely you should check that x!=NULL before calling *any* function on *x?
Good point! The noise got in the way...

--
Ian Collins.
Aug 24 '07 #6
Dave Stafford wrote:
I have a macro that I use across the board for freeing ram. I'd like to
clean up my code so I don't get these warnings.
What about those diagnostics you _should_ have gotten, but either didn't
get or forgot to tell us about?

You seem to have already taken the first step toward getting rid of the
diagnostics: you have set your diagnostic level too low. Lower it again
and maybe it will compile Fortran as C without complaint.
>
#define sfree(x) _internal_sfree((void **)&x)
#define _internal_sfree(x) ({ if(x && *x) { free(*x); *x=NULL; } })

void main() {
char *x = (char *) malloc(10);
int *y = (int *) malloc(10);

sfree(x);
sfree(y);
}

results in:

warning: dereferencing type-punned pointer will break strict-aliasing
rules
Aug 24 '07 #7
Philip Potter <pg*@see.sig.invalidwrites:
Ian Collins wrote:
>Ian Collins wrote:
>>Dave Stafford wrote:
I have a macro that I use across the board for freeing ram. I'd like to
clean up my code so I don't get these warnings.

#define sfree(x) _internal_sfree((void **)&x)
#define _internal_sfree(x) ({ if(x && *x) { free(*x); *x=NULL; } })

Remove the extraneous parenthesis around the expression.
Which still leaves the question why cast to void** and why test for NULL?

How about:

#define sfree(x) _internal_sfree(&x)
#define _internal_sfree(x) { free(*x); *x=NULL; }

Surely you should check that x!=NULL before calling *any* function
on *x?
That is not really a problem -- the x in _internal_sfree is always of
the form &... [Obviously this is only true if it is not invoked
directly, but there is no practical way to avoid problems if internal
helper macros are invoked by user code.]

Since the x is of the form &... and * and & "cancel each other out"
(talking very loosely) you end up not needing the other macro. With
the required extra parentheses, a comma expression rather than a
block, and a better name you get Keith's version:

#define SFREE(p) (free(p), (p) = NULL)

--
Ben.
Aug 24 '07 #8
Ben Bacarisse wrote:
Philip Potter <pg*@see.sig.invalidwrites:
>Ian Collins wrote:
>>Which still leaves the question why cast to void** and why test for NULL?

How about:

#define sfree(x) _internal_sfree(&x)
#define _internal_sfree(x) { free(*x); *x=NULL; }
Surely you should check that x!=NULL before calling *any* function
on *x?

That is not really a problem -- the x in _internal_sfree is always of
the form &... [Obviously this is only true if it is not invoked
directly, but there is no practical way to avoid problems if internal
helper macros are invoked by user code.]
Yes of course, I should have seen that before!

--
Philip Potter pgp <atdoc.ic.ac.uk
Aug 25 '07 #9
Philip Potter wrote:
Ben Bacarisse wrote:
>Philip Potter <pg*@see.sig.invalidwrites:
>>Ian Collins wrote:
Which still leaves the question why cast to void** and why test for
NULL?

How about:

#define sfree(x) _internal_sfree(&x)
#define _internal_sfree(x) { free(*x); *x=NULL; }
Surely you should check that x!=NULL before calling *any* function
on *x?

That is not really a problem -- the x in _internal_sfree is always of
the form &... [Obviously this is only true if it is not invoked
directly, but there is no practical way to avoid problems if internal
helper macros are invoked by user code.]

Yes of course, I should have seen that before!
See what happens when "function like" macros have lower case names :)

--
Ian Collins.
Aug 25 '07 #10
Ian Collins wrote:
Philip Potter wrote:
>Ben Bacarisse wrote:
>>Philip Potter <pg*@see.sig.invalidwrites:

Ian Collins wrote:
Which still leaves the question why cast to void** and why test for
NULL?
>
How about:
>
#define sfree(x) _internal_sfree(&x)
#define _internal_sfree(x) { free(*x); *x=NULL; }
Surely you should check that x!=NULL before calling *any* function
on *x?
That is not really a problem -- the x in _internal_sfree is always of
the form &... [Obviously this is only true if it is not invoked
directly, but there is no practical way to avoid problems if internal
helper macros are invoked by user code.]
Yes of course, I should have seen that before!
See what happens when "function like" macros have lower case names :)
How would it be any different if they were real functions?

--
Philip Potter pgp <atdoc.ic.ac.uk
Aug 25 '07 #11
Philip Potter <pg*@see.sig.invalidwrites:
Ian Collins wrote:
>Philip Potter wrote:
>>Ben Bacarisse wrote:
Philip Potter <pg*@see.sig.invalidwrites:

Ian Collins wrote:
>Which still leaves the question why cast to void** and why test for
>NULL?
>>
>How about:
>>
>#define sfree(x) _internal_sfree(&x)
>#define _internal_sfree(x) { free(*x); *x=NULL; }
Surely you should check that x!=NULL before calling *any* function
on *x?
That is not really a problem -- the x in _internal_sfree is always of
the form &... [Obviously this is only true if it is not invoked
directly, but there is no practical way to avoid problems if internal
helper macros are invoked by user code.]
Yes of course, I should have seen that before!
See what happens when "function like" macros have lower case names :)
How would it be any different if they were real functions?
The sfree() macro takes the address of its argument. If a function
did that, it would get the address of the parameter, a local object,
not the address of the object you pass to it.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 25 '07 #12
Ian Collins said:
Dave Stafford wrote:
>void main() {

If you didn't get a warning for this, crank up the warning level!
Whilst it's wrong (except on some freestanding implementations), it
isn't a syntax error or a constraint violation. Implementations need
not diagnose it (although some choose to do so).

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 25 '07 #13
Richard Heathfield wrote:
>
Ian Collins said:
Dave Stafford wrote:
void main() {
If you didn't get a warning for this, crank up the warning level!

Whilst it's wrong (except on some freestanding implementations), it
isn't a syntax error or a constraint violation. Implementations need
not diagnose it (although some choose to do so).
I don't see void main() as being as more or less correct
on freestanding implementations which define void main(),
than it is on hosted implementations which define void main().

--
pete
Aug 25 '07 #14
pete wrote:
Richard Heathfield wrote:
>Ian Collins said:
>>Dave Stafford wrote:

void main() {
If you didn't get a warning for this, crank up the warning level!
Whilst it's wrong (except on some freestanding implementations), it
isn't a syntax error or a constraint violation. Implementations need
not diagnose it (although some choose to do so).

I don't see void main() as being as more or less correct
on freestanding implementations which define void main(),
than it is on hosted implementations which define void main().
Section 5.1.2.2.1 of the standard does.

--
Ian Collins.
Aug 25 '07 #15
[comp.lang.c] Richard Heathfield <rj*@see.sig.invalidwrote:
Ian Collins said:
>If you didn't get a warning for this, crank up the warning level!
Whilst it's wrong (except on some freestanding implementations), it
isn't a syntax error or a constraint violation. Implementations need
not diagnose it (although some choose to do so).
I would think that an implementation worth its salt would provide a
warning level at which it did issue a diagnostic for void main(). Are
there any major implementations which cannot be coerced into doing so?

--
C. Benson Manica | I appreciate all corrections, polite or otherwise.
cbmanica(at)gmail.com |
----------------------| I do not currently read any posts posted through
sdf.lonestar.org | Google groups, due to rampant unchecked spam.
Aug 25 '07 #16
Christopher Benson-Manica said:
[comp.lang.c] Richard Heathfield <rj*@see.sig.invalidwrote:
>Ian Collins said:
>>If you didn't get a warning for this, crank up the warning level!
>Whilst it's wrong (except on some freestanding implementations), it
isn't a syntax error or a constraint violation. Implementations need
not diagnose it (although some choose to do so).

I would think that an implementation worth its salt would provide a
warning level at which it did issue a diagnostic for void main(). Are
there any major implementations which cannot be coerced into doing so?
Borland can, and gcc can. Last time I checked, which was VS6, Microsoft
couldn't.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 25 '07 #17
Fr************@googlemail.com said:
On Aug 25, 12:45 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>[...] C90 implementations must provide int main(int, char
**) and correct C90 programs must use int main(int char **) - not to
do so renders the behaviour of the program undefined.

I believe you are mistaken - in both C90 and C99, main can also take
no parameters. (It must still return an int of course.)
Whoops! Yes, of course it can instead take no parameters. Would you
believe me if I told you I knew that really? :-)

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 25 '07 #18
Ian Collins <ia******@hotmail.comwrites:
pete wrote:
[...]
>I don't see void main() as being as more or less correct
on freestanding implementations which define void main(),
than it is on hosted implementations which define void main().
Section 5.1.2.2.1 of the standard does.
It says that main shall be defined as 'int main(void)', or as
'int main(int argc, char *argv[])', "or in some other
implementation-defined manner".

So 'void main(void)' is "correct" on an implementation (either hosted
for freestanding) that supports it.

By contrast, 'int main(void)' is correct on any hosted implementation
(and may or may not be correct on a given freestanding
implementation).

I was going to say which one of you I agree with, but the disagreement
is over words, not over what those words refer to, so I won't bother.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 25 '07 #19
Christopher Benson-Manica wrote:
>
I would think that an implementation worth its salt would provide a
warning level at which it did issue a diagnostic for void main(). Are
there any major implementations which cannot be coerced into doing so?
I added a warning for
void main(void)
{
}

since lcc-win32 got into an obscure bug...

C99 mandates that main should return zero even if the programmer
doesn't explicitly write a return statement.

If you declare main as a void function however,
the compiler would try to make a void function return zero
as result!!!

A user warned me about this: the compiler crashed when it
saw

void main(void)
{}

I fixed it by ignoring the void statement. And added a
warning with a higher warning level.
Aug 25 '07 #20
jacob navia wrote, On 25/08/07 21:16:
Christopher Benson-Manica wrote:
>>
I would think that an implementation worth its salt would provide a
warning level at which it did issue a diagnostic for void main(). Are
there any major implementations which cannot be coerced into doing so?

I added a warning for
void main(void)
{
}
Good :-)
since lcc-win32 got into an obscure bug...

C99 mandates that main should return zero even if the programmer
doesn't explicitly write a return statement.

If you declare main as a void function however,
the compiler would try to make a void function return zero
as result!!!

A user warned me about this: the compiler crashed when it
saw

void main(void)
{}
You could have claimed it was not a bug because it did not affect
conformance to the C standard. You are explicitly allowed to fail to
compile a program that unconditionally invokes undefined behaviour, and
crashing counts.
I fixed it by ignoring the void statement. And added a
warning with a higher warning level.
Shucks. Still, even an obsolete compiler that crashes on void main() is
another reason not to use it :-)
--
Flash Gordon
Aug 28 '07 #21
On Sat, 25 Aug 2007 00:38:27 +0200 (CEST), Dave Stafford
<in*****@in.validwrote:
>I have a macro that I use across the board for freeing ram. I'd like to
clean up my code so I don't get these warnings.

#define sfree(x) _internal_sfree((void **)&x)
>#define _internal_sfree(x) ({ if(x && *x) { free(*x); *x=NULL; } })
There is no guarantee that casting &y to void** and then dereferencing
it will produce the void* containing the original value of y that you
want. Consider the case below where y is a int* and let sizeof
(void*) be 8 while all other pointers are 4.

There is even no guarantee that the value &x is properly aligned for a
void** value.
>
void main() {
char *x = (char *) malloc(10);
int *y = (int *) malloc(10);

sfree(x);
sfree(y);
}

results in:

warning: dereferencing type-punned pointer will break strict-aliasing
rules

Remove del for email
Aug 29 '07 #22
In article <fa**********@chessie.cirr.com>, Christopher Benson-Manica
<at***@otaku.freeshell.orgwrites
>[comp.lang.c] Richard Heathfield <rj*@see.sig.invalidwrote:
>Ian Collins said:
>>If you didn't get a warning for this, crank up the warning level!
>Whilst it's wrong (except on some freestanding implementations), it
isn't a syntax error or a constraint violation. Implementations need
not diagnose it (although some choose to do so).

I would think that an implementation worth its salt would provide a
warning level at which it did issue a diagnostic for void main(). Are
there any major implementations which cannot be coerced into doing so?
Yes, quite a few.

Most embedded cross compilers do not and should not.
In fact it is more useful if they give a warning to
int main()
as there is nothing to return to.

However I agree that in the hosted world a warning should be given.

These days I suspect the majority of C use is in the embedded world.
--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills Staffs England /\/\/\/\/
/\/\/ ch***@phaedsys.org www.phaedsys.org \/\/\
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

Aug 29 '07 #23
Barry Schwarz wrote:
On Sat, 25 Aug 2007 00:38:27 +0200 (CEST), Dave Stafford
<in*****@in.validwrote:
>I have a macro that I use across the board for freeing ram. I'd like to
clean up my code so I don't get these warnings.

#define sfree(x) _internal_sfree((void **)&x)
>#define _internal_sfree(x) ({ if(x && *x) { free(*x); *x=NULL; } })

There is no guarantee that casting &y to void** and then dereferencing
it will produce the void* containing the original value of y that you
want. Consider the case below where y is a int* and let sizeof
(void*) be 8 while all other pointers are 4.
Such an implementation would not be conforming AFAIK. sizeof(void *) ==
sizeof(char *).
There is even no guarantee that the value &x is properly aligned for a
void** value.
Values do not have alignment. This is why the following code works even though
shorts may have alignments that longs may not:

#include <stdio.h>
int main(void) {
short value = 10;
long lval = (long) value;
printf("%d\n",lval); /* Or should it be %ld? */
return 0;
}

Phil

--
Philip Potter pgp <atdoc.ic.ac.uk
Aug 29 '07 #24
Chris Hills wrote:
In article <fa**********@chessie.cirr.com>, Christopher Benson-Manica
<at***@otaku.freeshell.orgwrites
>[comp.lang.c] Richard Heathfield <rj*@see.sig.invalidwrote:
>>Ian Collins said:
>>>If you didn't get a warning for this, crank up the warning level!
>>Whilst it's wrong (except on some freestanding implementations), it
isn't a syntax error or a constraint violation. Implementations need
not diagnose it (although some choose to do so).

I would think that an implementation worth its salt would provide a
warning level at which it did issue a diagnostic for void main(). Are
there any major implementations which cannot be coerced into doing so?

Yes, quite a few.

Most embedded cross compilers do not and should not.
In fact it is more useful if they give a warning to
int main()
as there is nothing to return to.

However I agree that in the hosted world a warning should be given.

These days I suspect the majority of C use is in the embedded world.
That depends on how you define "the majority", I guess. I accept that your
statement may be correct for usage of C to get work done. But for learners of C,
I think the majority would be using hosted implementations on ordinary PCs.

Besides, I'm working on an embedded platform at the moment and the
implementation is hosted, not freestanding. (You just have to be careful not to
use any of the standard library calls (of which printf() is one) which may swell
your binary beyond 64Kb...)

Phil

--
Philip Potter pgp <atdoc.ic.ac.uk
Aug 29 '07 #25
On Wed, 29 Aug 2007 09:49:06 +0100, Philip Potter
<pg*@see.sig.invalidwrote:
>Barry Schwarz wrote:
>On Sat, 25 Aug 2007 00:38:27 +0200 (CEST), Dave Stafford
<in*****@in.validwrote:
>>I have a macro that I use across the board for freeing ram. I'd like to
clean up my code so I don't get these warnings.

#define sfree(x) _internal_sfree((void **)&x)
>>#define _internal_sfree(x) ({ if(x && *x) { free(*x); *x=NULL; } })

There is no guarantee that casting &y to void** and then dereferencing
it will produce the void* containing the original value of y that you
want. Consider the case below where y is a int* and let sizeof
(void*) be 8 while all other pointers are 4.

Such an implementation would not be conforming AFAIK. sizeof(void *) ==
sizeof(char *).
True. Let sizeof(void*) and sizeof(char*) be 8 while others are 4 and
the point remains valid.
>
>There is even no guarantee that the value &x is properly aligned for a
void** value.

Values do not have alignment. This is why the following code works even though
shorts may have alignments that longs may not:
Values assigned to pointers must satisfy alignment issues. &x is an
expression with type pointer to something. From 6.3.2.3-7:

"A pointer to an object or incomplete type may be converted to a
pointer to a different object or incomplete type. If the resulting
pointer is not correctly aligned for the pointed-to type, the behavior
is undefined."
>
#include <stdio.h>
int main(void) {
short value = 10;
long lval = (long) value;
All you have done here is cast an integer value to another integer
value of greater rank. This has nothing to do with alignment.

If you had said
long lval = *(long*)&value;
you would be addressing the issue at hand and in fact invoking
undefined behavior on all systems where sizeof(long)>sizeof(short).
The UB is the result not only of possible alignment issues but also of
accessing bytes beyond the end of value.
printf("%d\n",lval); /* Or should it be %ld? */
Yes.
return 0;
}

Remove del for email
Aug 31 '07 #26
In article <+U**************@phaedsys.demon.co.uk>
Chris Hills <ch***@phaedsys.demon.co.ukwrote:
>Most embedded cross compilers do not [warn about "void main"]
That may well be the case, although I cannot speak for "most" or even
"many".
>and should not.
Here, I disagree: "should" or "should not" is too strong, and I think
I disagree even more strongly with this:
>In fact it is more useful if they give a warning to
int main()
as there is nothing to return to.
Often enough, there *is* something to return to: the assembly code
that calls the startup routine. This may well just reboot, if that
suffices for an error recovery method.

Since I, in embedded environments, tend to name my "C startup
routine" start() (not main()), it does not affect me one way or
another what any given compiler thinks of the symbol "main". I
recommend this practice to all embedded-systems writers: do not
use main() at all, unless it will have return type "int" and the
two Standard C arguments.
>However I agree that in the hosted world a warning should be given.

These days I suspect the majority of C use is in the embedded world.
Perhaps. Of course, on vxWorks 6.x, RTPs are entered at main()
with the two Standard C arguments (plus, admittedly, several more
that one can use or ignore as desired -- specifically "char **envp",
a la Unix-like systems, and "void *aux", which is ... difficult to
describe) and the return value from main() is made available to
the task that collects the RTP's exit status.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Sep 2 '07 #27
In article <fb********@news1.newsguy.com>, Chris Torek
<no****@torek.netwrites
>In article <+U**************@phaedsys.demon.co.uk>
Chris Hills <ch***@phaedsys.demon.co.ukwrote:
>>Most embedded cross compilers do not [warn about "void main"]

That may well be the case, although I cannot speak for "most" or even
"many".
>>and should not.
Here, I disagree: "should" or "should not" is too strong, and I think
I disagree even more strongly with this:
Then we shall have to disagree.

>>In fact it is more useful if they give a warning to
int main()
as there is nothing to return to.
Often enough, there *is* something to return to: the assembly code
that calls the startup routine. This may well just reboot, if that
suffices for an error recovery method.
All the asm start up code I have seen is a linear piece of code whose
final instruction is something like "jmp _main" There is no return
point.

More to the point return statement in main will have nothing to return
to. It will be completely undefined (unless there is an OS)

Despite what the embedded OS vendors will have you believe the use of an
OR or RTOS in embedded systems is still quite uncommon.

So where is this "return" supposed to go? Having a return that does
something indeterminate is dangerous in many embedded systems.
Therefore there should be no return.

If it gets that far wrong you need a re-boot or of course an infinite
lop and let the watchdog take over.

Doing a return from many is just dangerous as the program exits into the
ether....
>Since I, in embedded environments, tend to name my "C startup
routine" start() (not main()), it does not affect me one way or
another what any given compiler thinks of the symbol "main". I
recommend this practice to all embedded-systems writers: do not
use main() at all, unless it will have return type "int" and the
two Standard C arguments.
Fair enough. However many (most?) of the embedded debug tools look for
"main" as a start point so often you get no choice.

--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills Staffs England /\/\/\/\/
/\/\/ ch***@phaedsys.org www.phaedsys.org \/\/\
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

Sep 2 '07 #28
Chris Hills wrote:
>
.... snip ...
>
All the asm start up code I have seen is a linear piece of code
whose final instruction is something like "jmp _main" There is
no return point.
Sounds as if you have been stuck with poor systems. Everything I
have built, or designed, called main (or the appropriate
equivalent), and either rebooted or halted if there was no
controlling shell to return to. Before any halt they would emit an
alerting message if the hardware permitted.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Sep 2 '07 #29

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

10 posts views Thread by Sony Antony | last post: by
7 posts views Thread by Matthew Del Buono | last post: by
1 post views Thread by Hafeez | last post: by
29 posts views Thread by junky_fellow | last post: by
8 posts views Thread by Charles Sullivan | last post: by
11 posts views Thread by Charles Sullivan | last post: by
11 posts views Thread by zeppe | last post: by
3 posts views Thread by gil | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.