473,414 Members | 1,711 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

gcc compiler

An
Hello,

I'm new to C and now I encountered the following problem.
When I compile the program hulp.c (the code is below) with the command
gcc -O -o hulp hulp.c,
running the program with input 1 2 3 4 1 2 3 4 1 2 3 4 1 2
gives output
12341234123412
00041234123412.
I don't understand how it is possible that the value of
macht[0],macht[1]and macht[2] don't remain 1 2 3.

It gets even more mysterious to me, since when I compile things using
gcc -o hulp hulp.c
running the program with the same input as above now gives the
expected output:
12341234123412
12341234123412.

How is this possible? What is the influence of the -O in the compiler
command? In the manual I read this has to do with optimization, but
what does it do here?

If I replace the type 'char' of 'inleeslg' to 'int', with the same
input as above BOTH compilers give the expected output:
12341234123412
12341234123412.
How can this be explained?

I really hope someone can help me out...

Here below one can find the code.
The first line of the file "facortest" is 2 1 1 2 3 4 5 6 7 8 9 10 11
0 .

Thank you in advance,

An
************************************************** *******
#include <stdio.h>

main()
{FILE *fp;
short i;
char inleeslg;
char macht[14];
long pbas;
char e;

fp=fopen("Factortest","r");
if ((fp=fopen("Factortest","r"))==NULL) printf("Kan datafile niet
openen \n");
else{
printf("Type 14 small numbers:\n");
for(i=0;i<14;i++)
{scanf("%d",&macht[i]);
}
/*Printing the input */
for(i=0;i<14;i++)
{printf("%d",macht[i]);
}
printf("\n");

fscanf(fp,"%d %d %d",&pbas,&e,&inleeslg);

/*Printing the input again */
for(i=0;i<14;i++)
{printf("%d",macht[i]);
}
printf("\n");
}
fclose(fp);
}
************************************************** ****************
Nov 14 '05 #1
11 1569

On Fri, 9 Jul 2004, An wrote:

I'm new to C and now I encountered the following problem.
When I compile the program hulp.c (the code is below) with the command
gcc -O -o hulp hulp.c,
running the program with input 1 2 3 4 1 2 3 4 1 2 3 4 1 2
gives output
12341234123412
00041234123412.
I don't understand how it is possible that the value of
macht[0],macht[1]and macht[2] don't remain 1 2 3.
You are overwriting them with zeroes, that's why. See below.

<snip> How is this possible? What is the influence of the -O in the compiler
command? In the manual I read this has to do with optimization, but
what does it do here?
It optimizes. Since your code was wrong to begin with, *any*
optimization is correct. So it makes some optimizations that change
the behavior of your program from wrong to wrong --- not a problem!
Write correct code, and suddenly the optimizer has a lot less leeway. :)

#include <stdio.h>

main()
int main(void) is preferred, and will work in C99 (the most recent
standardization).
{FILE *fp;
short i;
char inleeslg;
char macht[14];
long pbas;
char e;

fp=fopen("Factortest","r");
if ((fp=fopen("Factortest","r"))==NULL) printf("Kan datafile niet
openen \n");
Double whoops! First, you open the "Factortest" file *twice* here;
that's unwise, although I don't think it's a bug, strictly speaking.
The second problem is that your string literal overruns its line. Strings
in C can't span lines. Use a narrower margin for C code if necessary.

if (fp == NULL) printf("Kan datafile niet openen!\n");

else{
printf("Type 14 small numbers:\n");
for(i=0;i<14;i++)
{scanf("%d",&macht[i]);
Here is a bug. 'macht' is an array of char, not int. "%d" is the
format specifier for int. You mean something like

{
int tmp;
scanf("%d", &tmp);
macht[i] = tmp; /* with optional error-checking */
}
/*Printing the input */
for(i=0;i<14;i++)
{printf("%d",macht[i]);
}
printf("\n");

fscanf(fp,"%d %d %d",&pbas,&e,&inleeslg);
Here is another bug. 'pbas' is a long int. 'e' and 'inleeslg' are
chars. None of them are ints, which is what fscanf("%d") is expecting.
The correct format specifier for 'long int' is "%ld"; the two chars
can be read in using the temporary-variable solution I gave you above.
/*Printing the input again */
for(i=0;i<14;i++)
{printf("%d",macht[i]);
Note that this is *not* a bug, since while 'macht[i]' is a char,
it is passed as an int to 'printf'. However, learning when it is
safe to rely on the integer promotions is a tricky business.
}
printf("\n");
}
fclose(fp);
And last but not least,

return 0;
}

Nov 14 '05 #2
An <an*********@student.kuleuven.ac.be> wrote:
I'm new to C and now I encountered the following problem.
When I compile the program hulp.c (the code is below) with the command
gcc -O -o hulp hulp.c,
running the program with input 1 2 3 4 1 2 3 4 1 2 3 4 1 2
gives output
12341234123412
00041234123412.
I don't understand how it is possible that the value of
macht[0],macht[1]and macht[2] don't remain 1 2 3. It gets even more mysterious to me, since when I compile things using
gcc -o hulp hulp.c
running the program with the same input as above now gives the
expected output:
12341234123412
12341234123412. How is this possible? What is the influence of the -O in the compiler
command? In the manual I read this has to do with optimization, but
what does it do here? char inleeslg;
char macht[14];
long pbas;
char e;
but later you have
fscanf(fp,"%d %d %d",&pbas,&e,&inleeslg);
You are promising the fscanf() function that all 'pbas', 'e and 'inlesslg'
are integers but they aren't. But fscanf() doesn't know that and, under
certain circumstances, it probably writes over the memory of some other
variable. It's spelled out in the "manual", but under a different heading
than you probably were looking for. You invoke so-called "undefined
behaviour" and then all bets are off. Your program can seem to work, it
can run but give wrong results, it can just crash or even reformat your
harddisk (luckily, that doesn't happen too often nowadays anymore;-). By
playing around wit the optimization options the resulting executables
will be slightly different and you see two of the above mentioned conse-
quences: in one case the program seems to work, in the other it also runs
but gives you some strange output.
If I replace the type 'char' of 'inleeslg' to 'int', with the same
input as above BOTH compilers give the expected output:
12341234123412
12341234123412.
How can this be explained?
Once you also have made 'pbas' and 'e' ints (or corrected the format
string you pass to fscanf()) your program does not invoke undefined
behaviour anymore and it will run perfectly well and give correct
results forever and a day.
#include <stdio.h> main()
Make that

int main()

or

int main( void )

otherwise you're going to get into trouble once you start using a
C99 compliant compiler.
printf("Type 14 small numbers:\n");
for(i=0;i<14;i++)
{scanf("%d",&macht[i]);


Using scanf() to read in user input is basically impossible to get
right (just have the user make a typing error and the program will
blow up). Better look up e.g. fgets(), read in the whole line and
then disassemble it into the pieces you're looking for.

BTW, white space has become rather cheep so you are allowed to
use lots more of it for the indentation of your code, people
having to read it will be grateful...

Regards, Jens
--
\ Jens Thoms Toerring ___ Je***********@physik.fu-berlin.de
\__________________________ http://www.toerring.de
Nov 14 '05 #3
In 'comp.lang.c', an*********@student.kuleuven.ac.be (An) wrote:
When I compile the program hulp.c (the code is below) with the command
gcc -O -o hulp hulp.c,
running the program with input 1 2 3 4 1 2 3 4 1 2 3 4 1 2
gives output
12341234123412
00041234123412.
I don't understand how it is possible that the value of
macht[0],macht[1]and macht[2] don't remain 1 2 3.

It gets even more mysterious to me, since when I compile things using
gcc -o hulp hulp.c
running the program with the same input as above now gives the
expected output:
12341234123412
12341234123412.
Sounds like there is an Undefined Behaviour (UB) in your code.
How is this possible? What is the influence of the -O in the compiler
command? In the manual I read this has to do with optimization, but
what does it do here?

If I replace the type 'char' of 'inleeslg' to 'int', with the same
input as above BOTH compilers give the expected output:
12341234123412
12341234123412.
How can this be explained?
Typical UB. Anything can happen.
I really hope someone can help me out...

Here below one can find the code.
The first line of the file "facortest" is 2 1 1 2 3 4 5 6 7 8 9 10 11
0 .

************************************************** *******
#include <stdio.h>

main()
{FILE *fp;
short i;
char inleeslg;
char macht[14];
long pbas;
char e;

fp=fopen("Factortest","r");
if ((fp=fopen("Factortest","r"))==NULL) printf("Kan datafile niet
openen \n");
Stop! UB. You can't open a file twice. The rest of the code is doomed.
else{
printf("Type 14 small numbers:\n");
for(i=0;i<14;i++)
{scanf("%d",&macht[i]);
UB : "%d" expects the address of an int. You provided the address of a char.
}
/*Printing the input */
for(i=0;i<14;i++)
{printf("%d",macht[i]);
}
printf("\n");

fscanf(fp,"%d %d %d",&pbas,&e,&inleeslg);
UB : "%d" expects the address of an int. You provided the address of a char,
an int and a long.
/*Printing the input again */
for(i=0;i<14;i++)
{printf("%d",macht[i]);
}
printf("\n");
}
fclose(fp);
}
************************************************** ****************


--
-ed- get my email here: http://marreduspam.com/ad672570
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=c99
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
Nov 14 '05 #4
Emmanuel Delahaye <em**********@noos.fr> wrote:
an*********@student.kuleuven.ac.be (An) wrote:

fp=fopen("Factortest","r");
if ((fp=fopen("Factortest","r"))==NULL) printf("Kan datafile niet
openen \n");


Stop! UB. You can't open a file twice. The rest of the code is doomed.


How is that UB? Most operating systems allow files to be open multiple
times for reading; I'd consider it a compiler defect if the first
fopen succeeded here but the second failed.
Anyhow, AFAIK the behaviour of fopen is implemetation-defined.
Nov 14 '05 #5
On 10 Jul 2004 07:23:25 -0700, in comp.lang.c , ol*****@inspire.net.nz (Old
Wolf) wrote:
Emmanuel Delahaye <em**********@noos.fr> wrote:
an*********@student.kuleuven.ac.be (An) wrote:
>
> fp=fopen("Factortest","r");
> if ((fp=fopen("Factortest","r"))==NULL) printf("Kan datafile niet
> openen \n");
Stop! UB. You can't open a file twice. The rest of the code is doomed.


How is that UB?


The standard says nothing about being able to associate two FILE stream
pointers with one file. Hence its UB.
Most operating systems allow files to be open multiple
times for reading;
That may be true.
AFAIK the behaviour of fopen is implemetation-defined.


For it to be IB, the Standard has to say so.

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #6
Mark McIntyre <ma**********@spamcop.net> wrote:
ol*****@inspire.net.nz (Old Wolf) wrote:
Emmanuel Delahaye <em**********@noos.fr> wrote:
an*********@student.kuleuven.ac.be (An) wrote:
>
> fp=fopen("Factortest","r");
> if ((fp=fopen("Factortest","r"))==NULL) printf("Kan datafile niet
> openen \n");

Stop! UB. You can't open a file twice. The rest of the code is doomed.


How is that UB?


The standard says nothing about being able to associate two FILE stream
pointers with one file. Hence its UB.


Your argument is invalid: in the absence of a clause
specifically relating to opening two streams on one file, the assumption
must be that it is not undefined.

An analogy: it doesn't say you can simultaneously open a file called
"snarf" and a file called "foob" , so would it be UB if I tried that?

As it happens, we do have 7.19.2#8:
Whether the same file can be simultaneously open multiple
times is also implementation-defined.
AFAIK the behaviour of fopen is implemetation-defined.


For it to be IB, the Standard has to say so.


Dan Pop said so and, as a faithful minion, I didn't doubt :)
Nov 14 '05 #7
On 11 Jul 2004 14:43:13 -0700, in comp.lang.c , ol*****@inspire.net.nz (Old
Wolf) wrote:
Mark McIntyre <ma**********@spamcop.net> wrote:

The standard says nothing about being able to associate two FILE stream
pointers with one file. Hence its UB.
Your argument is invalid: in the absence of a clause
specifically relating to opening two streams on one file, the assumption
must be that it is not undefined.


Consider the meaning of the word "undefined".
An analogy: it doesn't say you can simultaneously open a file called
"snarf" and a file called "foob" , so would it be UB if I tried that?
See above
As it happens, we do have 7.19.2#8:


Perhaps you meant 7.19.3#8. I do agree however that the last sentence of
this clause makes it IB.
>AFAIK the behaviour of fopen is implemetation-defined.


For it to be IB, the Standard has to say so.


Dan Pop said so and, as a faithful minion, I didn't doubt :)


Dan says lots of things. Not all of which are ISO C either .

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #8
An
Thanks a lot for all comments (from everyone)! I made some
adjustments acording to your comments, and everything works fine now
:-). And, what's more important: I understand what I did wrong, so I
can avoid it from now on! The reason I tried to read the small
numbers in a "char", was to save memory. I have to learn about
'promotions'...

Thanks again,

An


"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote in message news:<Pi**********************************@unix45. andrew.cmu.edu>...
On Fri, 9 Jul 2004, An wrote:

I'm new to C and now I encountered the following problem.
When I compile the program hulp.c (the code is below) with the command
gcc -O -o hulp hulp.c,
running the program with input 1 2 3 4 1 2 3 4 1 2 3 4 1 2
gives output
12341234123412
00041234123412.
I don't understand how it is possible that the value of
macht[0],macht[1]and macht[2] don't remain 1 2 3.


You are overwriting them with zeroes, that's why. See below.

<snip>
How is this possible? What is the influence of the -O in the compiler
command? In the manual I read this has to do with optimization, but
what does it do here?


It optimizes. Since your code was wrong to begin with, *any*
optimization is correct. So it makes some optimizations that change
the behavior of your program from wrong to wrong --- not a problem!
Write correct code, and suddenly the optimizer has a lot less leeway. :)

#include <stdio.h>

main()


int main(void) is preferred, and will work in C99 (the most recent
standardization).
{FILE *fp;
short i;
char inleeslg;
char macht[14];
long pbas;
char e;

fp=fopen("Factortest","r");
if ((fp=fopen("Factortest","r"))==NULL) printf("Kan datafile niet
openen \n");


Double whoops! First, you open the "Factortest" file *twice* here;
that's unwise, although I don't think it's a bug, strictly speaking.
The second problem is that your string literal overruns its line. Strings
in C can't span lines. Use a narrower margin for C code if necessary.

if (fp == NULL) printf("Kan datafile niet openen!\n");

else{
printf("Type 14 small numbers:\n");
for(i=0;i<14;i++)
{scanf("%d",&macht[i]);


Here is a bug. 'macht' is an array of char, not int. "%d" is the
format specifier for int. You mean something like

{
int tmp;
scanf("%d", &tmp);
macht[i] = tmp; /* with optional error-checking */
}
/*Printing the input */
for(i=0;i<14;i++)
{printf("%d",macht[i]);
}
printf("\n");

fscanf(fp,"%d %d %d",&pbas,&e,&inleeslg);


Here is another bug. 'pbas' is a long int. 'e' and 'inleeslg' are
chars. None of them are ints, which is what fscanf("%d") is expecting.
The correct format specifier for 'long int' is "%ld"; the two chars
can be read in using the temporary-variable solution I gave you above.
/*Printing the input again */
for(i=0;i<14;i++)
{printf("%d",macht[i]);


Note that this is *not* a bug, since while 'macht[i]' is a char,
it is passed as an int to 'printf'. However, learning when it is
safe to rely on the integer promotions is a tricky business.
}

printf("\n");
}
fclose(fp);


And last but not least,

return 0;
}

Nov 14 '05 #9
On Sat, 10 Jul 2004 16:18:31 +0100,
Mark McIntyre <ma**********@spamcop.net> wrote:

On 10 Jul 2004 07:23:25 -0700, in comp.lang.c , ol*****@inspire.net.nz (Old
Wolf) wrote:
Emmanuel Delahaye <em**********@noos.fr> wrote:
an*********@student.kuleuven.ac.be (An) wrote:
>
> fp=fopen("Factortest","r");
> if ((fp=fopen("Factortest","r"))==NULL) printf("Kan datafile niet
> openen \n");

Stop! UB. You can't open a file twice. The rest of the code is doomed.


How is that UB?


The standard says nothing about being able to associate two FILE stream
pointers with one file. Hence its UB.


It is resource leak, nevertheless; parhaps harmless in this case. The
FILE* returnd by the first call to fopen is lost so that FILE* could never
be closed before the end of the program.

Villy

Nov 14 '05 #10

On Mon, 12 Jul 2004, Villy Kruse wrote:
an*********@student.kuleuven.ac.be (An) wrote:
>
> fp=fopen("Factortest","r");
> if ((fp=fopen("Factortest","r"))==NULL) printf("Kan datafile niet
> openen \n");
[...] It is resource leak, nevertheless; parhaps harmless in this case. The
FILE* returnd by the first call to fopen is lost so that FILE* could never
be closed before the end of the program.


The implementation is required to close all open file handles before
program termination (at least, program termination via 'exit' or
equivalent ('return' from 'main', falling off 'main')). Not a great
idea to rely on this behavior IMO, since it's usually not much harder
and much clearer to explicitly close your files, but not a true
"resource leak" in the way that, say, forgetting to free a malloc'ed
block is.

-Arthur
Nov 14 '05 #11
On Mon, 12 Jul 2004 09:35:55 -0400 (EDT),
Arthur J. O'Dwyer <aj*@nospam.andrew.cmu.edu> wrote:


On Mon, 12 Jul 2004, Villy Kruse wrote:
>>> an*********@student.kuleuven.ac.be (An) wrote:
>>> >
>>> > fp=fopen("Factortest","r");
>>> > if ((fp=fopen("Factortest","r"))==NULL) printf("Kan datafile niet
>>> > openen \n");

[...]
It is resource leak, nevertheless; parhaps harmless in this case. The
FILE* returnd by the first call to fopen is lost so that FILE* could never
be closed before the end of the program.


The implementation is required to close all open file handles before
program termination (at least, program termination via 'exit' or
equivalent ('return' from 'main', falling off 'main')). Not a great
idea to rely on this behavior IMO, since it's usually not much harder
and much clearer to explicitly close your files, but not a true
"resource leak" in the way that, say, forgetting to free a malloc'ed
block is.


A leak is a leak anytime a pointer or a handle to some resource is lost.

Let's say the program is running for months at a time, and the program
fragment is called once an hour on average, the program would in this way
accumulate a lot of opened files which could never be closed until the
program is terminated. Opened file handles are a limited resource in most
environments, and allowing them to leak can lead to long term problems.

A multitasking OS has to care care of lost malloc()ed memory anyway,
just in case the program terminates abnormally. Were that not the case
we would have to restart the OS whenever some program aborts in order
to reclaim its resources.
Villy
Nov 14 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Jeff Epler | last post by:
Hello. Recently, Generator Comprehensions were mentioned again on python-list. I have written an implementation for the compiler module. To try it out, however, you must be able to rebuild...
13
by: Bryan Parkoff | last post by:
You may notice that switch (...) is much faster than function that can gain a big improved performance because it only use JMP instruction however function is required to use CALL, PUSH, and POP...
10
by: Bjorn | last post by:
I'm using interfaces in C++ by declaring classes with only pure virtual methods. If then someone wants to implement the interface they needs to inherit from the class. If the implementing class...
7
by: Tao Wang | last post by:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi, I saw cuj's conformance roundup, but the result is quite old. I think many people like me want to know newer c++ standard conformance test...
14
by: joshc | last post by:
I'm writing some C to be used in an embedded environment and the code needs to be optimized. I have a question about optimizing compilers in general. I'm using GCC for the workstation and Diab...
16
by: pj | last post by:
(Was originally, probably wrongly, posted to the vc subgroup.) (This doesn't appear to be a c# problem, but a problem with a bug in the Visual Studio c# compiler, but, any help will be welcome...)...
0
by: rollasoc | last post by:
Hi, I seem to be getting a compiler error Internal Compiler Error (0xc0000005 at address 535DB439): likely culprit is 'BIND'. An internal error has occurred in the compiler. To work around...
3
by: Mark Rockman | last post by:
------ Build started: Project: USDAver2, Configuration: Debug .NET ------ Preparing resources... Updating references... Performing main compilation... error CS0583: Internal Compiler Error...
6
by: toton | last post by:
Hi, Anyone have a link to comparative study of different C++ compilers and how much they conform to C++ language standard? Most of the big platforms I know have GCC which well supports C++...
41
by: Miroslaw Makowiecki | last post by:
Where can I download Comeau compiler as a trial version? Thanks in advice.
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

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.