EmbeddedRelated.com
Forums
Memfault Beyond the Launch

problem using FILE pointer

Started by abc February 5, 2009
George Neuner wrote:
> CBFalconer <cbfalconer@yahoo.com> wrote: >> JeffR wrote: >>> cbfalconer wrote: >>>> abc wrote: >>>> >>... snip ... >>>> >>>>> FILE *fp; >>>>> >>>>> fp=fopen("C:\Documents and Settings\btp\Desktop\pertest\ecg.txt","r"); >>>> ^___ a backslash is an escape char. Use / or \\. >>>>> >>>>> while(fp!=EOF){ >>> ^.... while( !feof(fp) ) >> >> A bad suggestion. feof(fp) only signals that an EOF has been >> detected. Before that the following fread (or getc etc.) statement >> can read invalid data. All file reading calls signal when they >> encounter EOF. > > Well, technically the functions don't "signal" - else you could use a > signal handler to catch I/O errors. But they do all indicate errors > through their return values. > > [At least if the compiler is C90 or later. If you're working with an > older compiler, you can't rely on getc/putc to return anything > meaningful if an error occurs - particularly if you inline macro > versions. Not that you should be using those brain-dead functions > anyway ... ]
Again, misinformation. getc and putc return EOF (a negative integer) on error or EOF. They are often the most efficient way to use the input system. The thing to watch out for with them is the fact that they can evaluate the FILE* parameter more than once. They are unique among the file handling routines in doing this, but it enables eliminating allocation of input buffers, without the disadvantages of not buffering. This behaviour only occurs if you let getc etc. be macros. -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section.
George Neuner wrote:
> CBFalconer <cbfalconer@yahoo.com> wrote: >> JeffR wrote: >>> cbfalconer wrote: >>>> abc wrote: >>>> >>... snip ... >>>> >>>>> FILE *fp; >>>>> >>>>> fp=fopen("C:\Documents and Settings\btp\Desktop\pertest\ecg.txt","r"); >>>> ^___ a backslash is an escape char. Use / or \\. >>>>> >>>>> while(fp!=EOF){ >>> ^.... while( !feof(fp) ) >> >> A bad suggestion. feof(fp) only signals that an EOF has been >> detected. Before that the following fread (or getc etc.) statement >> can read invalid data. All file reading calls signal when they >> encounter EOF. > > Well, technically the functions don't "signal" - else you could use a > signal handler to catch I/O errors. But they do all indicate errors > through their return values. > > [At least if the compiler is C90 or later. If you're working with an > older compiler, you can't rely on getc/putc to return anything > meaningful if an error occurs - particularly if you inline macro > versions. Not that you should be using those brain-dead functions > anyway ... ]
Again, misinformation. getc and putc return EOF (a negative integer) on error or EOF. They are often the most efficient way to use the input system. The thing to watch out for with them is the fact that they can evaluate the FILE* parameter more than once. They are unique among the file handling routines in doing this, but it enables eliminating allocation of input buffers, without the disadvantages of not buffering. This behaviour only occurs if you let getc etc. be macros. -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section.
Rocky wrote:
> CBFalconer <cbfalco...@yahoo.com> wrote: >> abc wrote: >> >>> void main (void) >> ^^^^_____________main returns an int - say so. void is illegal > > With many compilers for limited resource processors it is quite > common to support the option of a void main() especially when > 'returning' from main is meaningless in these cases as it was > never actually called. (Again, to save stack space.)
You are taking chances if you ever have to port the code. You are not saving stack space, you are only saving the code space for a "return 0;" in main. At least with most implementations. -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section.
Rocky wrote:
> CBFalconer <cbfalco...@yahoo.com> wrote: >> abc wrote: >> >>> void main (void) >> ^^^^_____________main returns an int - say so. void is illegal > > With many compilers for limited resource processors it is quite > common to support the option of a void main() especially when > 'returning' from main is meaningless in these cases as it was > never actually called. (Again, to save stack space.)
You are taking chances if you ever have to port the code. You are not saving stack space, you are only saving the code space for a "return 0;" in main. At least with most implementations. -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section.
On Mon, 09 Feb 2009 17:20:24 -0500, CBFalconer <cbfalconer@yahoo.com>
wrote:

>George Neuner wrote: >> CBFalconer <cbfalconer@yahoo.com> wrote: >>> JeffR wrote: >>>> cbfalconer wrote: >>>>> abc wrote: >>>>> >>>... snip ... >>>>> >>>>>> FILE *fp; >>>>>> >>>>>> fp=fopen("C:\Documents and Settings\btp\Desktop\pertest\ecg.txt","r"); >>>>> ^___ a backslash is an escape char. Use / or \\. >>>>>> >>>>>> while(fp!=EOF){ >>>> ^.... while( !feof(fp) ) >>> >>> A bad suggestion. feof(fp) only signals that an EOF has been >>> detected. Before that the following fread (or getc etc.) statement >>> can read invalid data. All file reading calls signal when they >>> encounter EOF. >> >> Well, technically the functions don't "signal" - else you could use a >> signal handler to catch I/O errors. But they do all indicate errors >> through their return values. >> >> [At least if the compiler is C90 or later. If you're working with an >> older compiler, you can't rely on getc/putc to return anything >> meaningful if an error occurs - particularly if you inline macro >> versions. Not that you should be using those brain-dead functions >> anyway ... ] > >Again, misinformation. getc and putc return EOF (a negative >integer) on error or EOF.
Only for modern compilers. Sorry, but what I said is correct. The C90 (ANSI) library standard defined the error behavior for fgetc and fputc and specified that getc and putc be identical in behavior to their respective f_ functions. K&R defined getc/fgetc to return EOF only on end-of-file. If an error occurred, getc/fgetc could return garbage. K&R defined putc/fputc to return the value it wrote. You had to check errno (or call ferror) after the I/O call to find if an error actually occurred. In the middle 80's, leading compilers added return of EOF to indicate an error and it was eventually written into the 1990 ANSI standard. I know you were around for pre-ANSI (don't know if you go back to K&R). Maybe you've blocked it all out or maybe you had a compiler that was cutting edge, but I assure you I used compilers well into the middle 90's that behaved exactly as I described.
>The thing to watch out for with them is the fact that they can evaluate >the FILE* parameter more than once. They are unique among the file >handling routines in doing this, but it enables eliminating allocation >of input buffers, without the disadvantages of not buffering. This >behaviour only occurs if you let getc etc. be macros.
There were other issues with the macro versions as well. Because the return value from putc was the same as its input, some optimizing compilers would completely elide the value return code and instead simply copy the input value. George
On 2009-02-09, CBFalconer <cbfalconer@yahoo.com> wrote:
> Rocky wrote: >> CBFalconer <cbfalco...@yahoo.com> wrote: >>> abc wrote: >>> >>>> void main (void) >>> ^^^^_____________main returns an int - say so. void is illegal >> >> With many compilers for limited resource processors it is >> quite common to support the option of a void main() especially >> when 'returning' from main is meaningless in these cases as it >> was never actually called. (Again, to save stack space.)
How does it save stack space? I've used dozens of C compilers and none of them returned int values on the stack. IOW, changing the return type from "int" to "void" wouldn't change stack usage.
> You are taking chances if you ever have to port the code. You > are not saving stack space, you are only saving the code space > for a "return 0;" in main.
Usually not even that.
> At least with most implementations.
I've never seen a compiler that will generate code for a "return 0;" if it's unreachable (as it generally is in an embedded system). Any compiler that's worth using will generate the exact same code for these two cases: int main(void) { while (1) { // do a bunch of stuff. } return 0; } void main(void) { while (1) { // do a bunch of stuff. } } So you might as well comply with standards and do the former. -- Grant
On Feb 10, 6:40=A0am, Grant Edwards <gra...@visi.com> wrote:
> On 2009-02-09, CBFalconer <cbfalco...@yahoo.com> wrote: > > > Rocky wrote: > >> CBFalconer <cbfalco...@yahoo.com> wrote: > >>> abc wrote: > > >>>> void main (void) > >>> =A0^^^^_____________main returns an int - say so. =A0void is illegal > > >> With many compilers for limited resource processors it is > >> quite common to support the option of a void main() especially > >> when 'returning' from main is meaningless in these cases as it > >> was never actually called. (Again, to save stack space.) > > How does it save stack space? =A0I've used dozens of C compilers > and none of them returned int values on the stack. =A0IOW, > changing the return type from "int" to "void" wouldn't change > stack usage. > > > You are taking chances if you ever have to port the code. =A0You > > are not saving stack space, you are only saving the code space > > for a "return 0;" in main. > > Usually not even that. > > > At least with most implementations. > > I've never seen a compiler that will generate code for a > "return 0;" if it's unreachable (as it generally is in an > embedded system). > > Any compiler that's worth using will generate the exact same > code for these two cases: >
<SNIP CODE>
> So you might as well comply with standards and do the former.
Thanks Chuck & Grant for your input. I changed one of my projects to int main(void) and as you suggest the compiler generates the same code as it did for the void main(void) case.
Grant Edwards wrote:
> On 2009-02-09, CBFalconer <cbfalconer@yahoo.com> wrote: >> Rocky wrote: >>> CBFalconer <cbfalco...@yahoo.com> wrote: >>>> abc wrote: >>>> >>>>> void main (void) >>>> ^^^^_____________main returns an int - say so. void is illegal >>> With many compilers for limited resource processors it is >>> quite common to support the option of a void main() especially >>> when 'returning' from main is meaningless in these cases as it >>> was never actually called. (Again, to save stack space.) > > How does it save stack space? I've used dozens of C compilers > and none of them returned int values on the stack. IOW, > changing the return type from "int" to "void" wouldn't change > stack usage. >
The way to save stack space for main is by changing the C startup code so that you "jump" directly to main, rather than "calling" it. Of course, that's digging deeper than most people want to do, and can lead to problems if you get your C startup wrong (and it's even more fun if you are using C++). It's worth it if you are working on a really small system, or you need to do very early custom initialisation, or if your compiler/library's C startup code is so brain-dead you want to write your own (I've seen 32-bit toolchains that use byte-wide operations for initialising data and clearing .bss).
>> You are taking chances if you ever have to port the code. You >> are not saving stack space, you are only saving the code space >> for a "return 0;" in main. > > Usually not even that. >
While the "return 0" costs nothing, I wouldn't worry too much about portability. For library code, it makes sense to be portable. For your application itself, unless you are running on top of a general purpose OS then having to change "void main(void)" to "int main(void)" is not going to be noticeable in the porting effort. Personally, I sometimes use "int main(void)" to follow the standard, and sometimes "void main(void)" since that's what I actually *mean* - it's *my* program, not the standard's program, and if I am not going to return a value from the function main(), then main() should be declared with return type "void". I also often use "int __attribute__((noreturn)) main(void)" - that's non-portable too, but tells the compiler (and the reader) that main() won't return (and the return type is then totally ignored).
Please do not triple post, we read your post the first time, this
could be regarded as spam

On Feb 9, 10:17=A0pm, CBFalconer <cbfalco...@yahoo.com> wrote:

> Again, misinformation. =A0getc and putc return EOF (a negative > integer) on error or EOF. =A0They are often the most efficient way to > use the input system. =A0The thing to watch out for with them is the > fact that they can evaluate the FILE* parameter more than once. > They are unique among the file handling routines in doing this, but > it enables eliminating allocation of input buffers, without the > disadvantages of not buffering. =A0This behaviour only occurs if you > let getc etc. be macros. > > -- > =A0[mail]: Chuck F (cbfalconer at maineline dot net) > =A0[page]: <http://cbfalconer.home.att.net> > =A0 =A0 =A0 =A0 =A0 =A0 Try the download section.
Please do not triple post, we read your post the first time, this could be regarded as spam
On Tue, 10 Feb 2009 03:09:21 -0800 (PST),
bigbrownbeastiebigbrownface@googlemail.com wrote:

>Please do not triple post, we read your post the first time, this >could be regarded as spam > >On Feb 9, 10:17&#4294967295;pm, CBFalconer <cbfalco...@yahoo.com> wrote: > >> Again, misinformation. &#4294967295;getc and putc return EOF (a negative >> integer) on error or EOF. &#4294967295;They are often the most efficient way to >> use the input system. &#4294967295;The thing to watch out for with them is the >> fact that they can evaluate the FILE* parameter more than once. >> They are unique among the file handling routines in doing this, but >> it enables eliminating allocation of input buffers, without the >> disadvantages of not buffering. &#4294967295;This behaviour only occurs if you >> let getc etc. be macros. >> >> -- >> &#4294967295;[mail]: Chuck F (cbfalconer at maineline dot net) >> &#4294967295;[page]: <http://cbfalconer.home.att.net> >> &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; Try the download section. > >Please do not triple post, we read your post the first time, this >could be regarded as spam
He probably didn't. For a couple hours yesterday my news service was timing out accepting posts. I found later that a number of things I sent were posted several times due to retries. George

Memfault Beyond the Launch