I am first an accountant and decided to take on programming a few
years ago...
I have been first studying simple algorithms...
Now I have decided to first learn C (i'll give it 600 effective hours -
so btw 1 and 3 years) before going to c++ or perl, or python, java or
php or ruby on rails or vba, i'll see at that time what answers most
my needs either as a professionnal accountant or as a personal project
i'd like to take on... Is there anything specific I could do with a
good knowledge of C only ?
So I have been having a hard time with the basics of pointers (20
hours). I really want to feel ok with this before getting any further.
I haven't looked at functions yet.
Here is a programm I know by heart - from a book - but in this code it
doesn't work althought it is very similar to other versions I have
been "coding" over and over more than 30 times ... and 10 % of the
time, there is a bug very similar to the one below I can solve by
looking carefully at the code or cannot solve if I have looked
carefully at the code. That's why I'd like to learn how to debug.
So far or so early with learning C, I'd like to use this opportunity
to learn how to debug and know about the tools that can help.
I have mainly been programming under Windows Xp DJGPP Dolorie... and I
have found a command : simify (link : http://www.delorie.com/djgpp/v2faq/faq9_3.html
) to help debug.
===O===
FIRST, here is the culprit : (this prg inserts a symbol every 3 digits
if the number includes 4 or more digits)
===O===
#include <stdio.h> /* printf, putchar, gets, puts */
#include <conio.h> /* getche */
#include <stdlib.h> /* atoi */
#include <ctype.h> /* isdigit */
#include <string.h> /* strcpy, strlen */
#define BOOL int
/**********/
main()
{
char buffer[128] ;
char clearbuf[128] ;
char output[172] ;
char * pb = buffer, * pc = clearbuf, * po = output ;
int symbol ;
int i, k ;
int cnt ;
BOOL ok ;
/**********/
printf("\033[2J");
printf("\nCe prog separe...\n");
/**********/
do
{
printf("\nSeparateur :");
symbol = getche() ;
if ( symbol < 32 )
printf("Pas de caractere de control comme separateur !");
if ( isdigit(symbol) )
printf("Pas de chiffre comme separateur !" ) ;
} while ( symbol < 32 || isdigit(symbol) ) ;
/**********/
do
{
ok = 1 ;
printf("\nEntrez un nombre entier positif ");
gets(buffer) ;
cnt = 0 ;
while ( *(buffer + cnt) && ok )
{
if ( !isdigit(*(buffer + cnt) ) )
{
printf("Pas d'entier positif!") ;
ok = 0 ;
}
cnt++;
}
} while ( !ok ) ;
/**********/
if ( cnt > 1 && atoi(buffer) )
{
while ( *pb == '0' )
pb++ ;
while ( *pc++ = *pb++ )
;
strcpy(buffer, clearbuf);
}
/**********/
if ( (cnt = strlen(buffer)) > 3)
{
for ( i = cnt - 1, k = 0, pb = buffer ; i >= 0 ; i--, k++ )
{
po[k] = pb[i] ;
if ( ( (cnt - i) % 3 ) == 0 && i != 0 )
po[++k] = symbol ;
}
po[k] = '\0' ;
for ( i = k - 1 ; i >= 0 ; i-- )
putchar(*(output + i));
}
else
puts(buffer) ;
}
===O===
Running this doesn't work after entering a symbol
NOW the simify cmd says (in an dmp output text file) :
===O===
Entrez un separateur : ;
Entrer un nbr (pas plus de 50 chiffres svp) 434334
Exiting due to signal SIGSEGV
General Protection Fault at eip=00001f9e
eax=00092ca5 ebx=0000029d ecx=0000000d edx=00000001 esi=00000054
edi=00012d74
ebp=00092d48 esp=00092b60 program=C:\DJGPP\ACT43B\PTRS36.EXE
cs: sel=01a7 base=029d0000 limit=0009ffff
ds: sel=01af base=029d0000 limit=0009ffff
es: sel=01af base=029d0000 limit=0009ffff
fs: sel=017f base=0000f860 limit=0000ffff
gs: sel=01bf base=00000000 limit=0010ffff
ss: sel=01af base=029d0000 limit=0009ffff
App stack: [00092d74..00012d74] Exceptn stack: [00012cd4..00010d94]
Call frame traceback EIPs:
0x00001f9e _main+243
0x00003a38 ___crt1_startup+176
C:\DJGPP\act43b>symify ptrs36.exe
C:\DJGPP\act43b>symify -o ptrs36.exe
Invalid option -o - type `symify' for help
C:\DJGPP\act43b>symify -o pbb1.dmp ptrs36.exe
====O====
I don't know if I can use what simify says to find any bug.
=========
Am I using simify right ?
Is my bug tracable ?
What(free) tool in my windows Xp context can I use to debug ?
=========
Thanks in advance ,
Pascal
> Here is a programm I know by heart - from a book - but in this code it
> doesn't work althought it is very similar to other versions I have
> main()
> symbol = getche() ;
> gets(buffer) ;
The book you got this from must be ancient, but at first try the code seems
to work (on my OS).
What's the actual problem?
And the register dump stuff is a waste of time at this level.
--
Bart
> And the register dump stuff is a waste of time at this level.
Ok perhaps not such a waste as the error is mentioned there:
<bpasc...@googlemail.com> wrote in message
news:cf6b7eb3-88e7-4c92...@j12g2000vbl.googlegroups.com...
> Entrez un separateur : ;
> Entrer un nbr (pas plus de 50 chiffres svp) 434334
> Exiting due to signal SIGSEGV
I'll have a closer look.
--
Bart
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define BOOL int
/***********************************/
main()
{
char buffer[128] ;
char output[172] ;
char clearbuf[128] ;
char * pb = buffer, * pc = clearbuf, * po = output ;
int cnt, symbol ;
int i, k ;
BOOL ok ;
/***********************************/
printf("\033[2J");
printf("\nCe prg permet d'inserer...\n");
/***********************************/
do
{
printf("\nSeparateur :");
symbol = getche() ;
if ( symbol < 32 )
printf("Pas de caractere de control comme
separateur !");
if ( isdigit(symbol) )
printf("Pas de chiffre comme
separateur !" ) ;
} while ( symbol < 32 || isdigit
(symbol) ) ;
/***********************************/
do
{
ok = 1 ;
printf("\nEntrer un nbr (pas plus de 50 chiffres svp)
") ;
gets(buffer) ;
cnt = 0 ;
while ( *(buffer + cnt) && ok )
{
if ( !(isdigit(buffer + cnt)) )
{
printf(" \nCe n'est pas un entier
positif !") ;
ok = 0 ;
}
cnt++ ;
}
} while ( !ok ) ;
/***********************************/
if ( cnt > 1 && atoi(buffer) )
{
while ( *pb == '0' )
pb++ ;
while ( *pc++ == *pb++ )
;
strcpy(buffer, clearbuf) ;
}
/***********************************/
if ( (cnt = strlen(buffer)) > 3)
{
for ( i = cnt - 1, k = 0, pb = buffer ; i >=
0 ; i--, k++ )
{
po[k] = pb[i] ;
if ( ((cnt - i ) % 3) == '0' && i !=
I'm confused now, which one was supposed to be working, the first one you
posted? With the error dump?
I would stick with that one since that one worked for me and the others
(which have a couple of blatant errors) don't.
No idea how you would use your simify program to pinpoint the error.
If you get segfault errors on your machine, in this simple program I would
just insert exit(0) at specific points to see near line it occurs at (I'd
also hardcode the values of symbol and buffer to avoid having to reenter
these).
Start just after gets(), and if it's OK then just move the exit(0) a bit
further down (gets() is not a good idea to use but you can worry about
replacing it later).
--
Bart
<conio.h> is part of your Windows library, not of C. Therefore, your
code is not only outside the scope of this group, but more importantly,
many regulars here will be unable to compile your code. (I for one have
no <conio.h> header.)
> #include <stdlib.h> /* atoi */
> #include <ctype.h> /* isdigit */
> #include <string.h> /* strcpy, strlen */
>
> #define BOOL int
>
> /**********/
>
> main()
This should be
int main(void)
Which is clearer and works with the latest standardized version of C.
> {
> char buffer[128] ;
> char clearbuf[128] ;
> char output[172] ;
>
> char * pb = buffer, * pc = clearbuf, * po = output ;
>
> int symbol ;
> int i, k ;
> int cnt ;
>
> BOOL ok ;
>
> /**********/
>
> printf("\033[2J");
> printf("\nCe prog separe...\n");
>
You can use puts() instead of printf(), which saves a fair bit of
overhead and automatically adds the \n to the end of every line.
> /**********/
>
> do
> {
> printf("\nSeparateur :");
> symbol = getche() ;
What does this function do? If you need to get a single character, use
getc() or fgetc().
>
> if ( symbol < 32 )
> printf("Pas de caractere de control comme separateur !");
> if ( isdigit(symbol) )
> printf("Pas de chiffre comme separateur !" ) ;
> } while ( symbol < 32 || isdigit(symbol) ) ;
>
> /**********/
>
Please use proper indentation when posting on Usenet.
> do
> {
> ok = 1 ;
> printf("\nEntrez un nombre entier positif ");
> gets(buffer) ;
Stop right here. NEVER ever EVER use gets(). It is impossible to use
safely, since it does no buffer size checking and therefore is inviting
users to overrun your buffer and run over who-knows-what memory.
Use fgets() instead, which will accept sizeof buffer as an additional
argument, and will check the size of the input.
>
> cnt = 0 ;
>
> while ( *(buffer + cnt) && ok )
> {
> if ( !isdigit(*(buffer + cnt) ) )
> {
> printf("Pas d'entier positif!") ;
> ok = 0 ;
> }
> cnt++;
> }
> } while ( !ok ) ;
>
> /**********/
>
> if ( cnt > 1 && atoi(buffer) )
atoi() is also not recommended since it doesn't fail well if you pass it
invalid input. Use strtol() or strtoul() instead.
> {
> while ( *pb == '0' )
> pb++ ;
>
> while ( *pc++ = *pb++ )
> ;
>
> strcpy(buffer, clearbuf);
> }
>
> /**********/
>
> if ( (cnt = strlen(buffer)) > 3)
> {
> for ( i = cnt - 1, k = 0, pb = buffer ; i >= 0 ; i--, k++ )
Your spacing is abysmal. Please correct it.
> {
> po[k] = pb[i] ;
>
> if ( ( (cnt - i) % 3 ) == 0 && i != 0 )
> po[++k] = symbol ;
> }
> po[k] = '\0' ;
>
> for ( i = k - 1 ; i >= 0 ; i-- )
> putchar(*(output + i));
> }
> else
> puts(buffer) ;
> }
>
If you fix all of the above problems, it might fix whatever the issue
with your code is. But as it stands, I can neither compile nor read the
posted code. So please correct these things, fix the formatting and
repost if you are still having issues.
--
Andrew Poelstra <http://testing.wpsoftware.net/finex>
[snip]
> if ( cnt > 1 && atoi(buffer) )
...
Many prefer strtol to atoi. atoi returns nothing and strtol can be error
checked. Very good you sure learn quickly. Your better than me and I've been
studying on and off for several years now. But I've never made a point of
pointers til now :)
Bill
Myself personally I would've put exit(EXIT_SUCCESS); for portability
rather than exit(0);
Bill
0 and EXIT_SUCCESS are both portable across all C implementations.
> I am first an accountant and decided to take on programming a few
> years ago...
> I have been first studying simple algorithms...
>
> Now I have decided to first learn C (i'll give it 600 effective hours -
> so btw 1 and 3 years) before going to c++ or perl, or python, java or
> php or ruby on rails or vba, i'll see at that time what answers most
> my needs either as a professionnal accountant or as a personal project
> i'd like to take on... Is there anything specific I could do with a
> good knowledge of C only ?
>
> So I have been having a hard time with the basics of pointers (20
> hours). I really want to feel ok with this before getting any further.
> I haven't looked at functions yet.
You've had some advice already but I'd like to add something very
general. "Putting off" functions is a bad idea. They are the key
tool for decomposing problem into simpler problems and for building
complex behaviour from simple behaviour. In short, they are a central
theme in programming and you end up making matters worse by using a
text that delays introducing them.
Learn to write simple functions and then learn how to combine simple
functions. The habit of writing lots of function should stay with you
throughout your programming life.
There are other signs that the book you are using is not a good one.
Have you has a look at "The C Programming Language, 2nd Edition" by
Kernighan and Ritchie?
A few other general tips...
If you find yourself writing "flag" variables (like "ok" in your
program) think again. Experienced programmers use then a lot less the
beginners for reasons I have never fully understood. If you still
want to use one, give it a helpful name than "ok".
In C, *(output + i) is the same as output[i]. You use both forms in
your program but the second is almost always clearer.
--
Ben.
Pointers are what plague beginning C programmers more than anything
else, so you're in good company.
-Beej
> 0 and EXIT_SUCCESS are both portable across all C implementations.
>
I see I didn't know that. But what about exit(1); and
exit(EXIT_FAILURE); ?
Bill
The first is non-portable; the second is portable;
The only three return values guaranteed to be portable across all C
implementations are 0, EXIT_SUCCESS and EXIT_FAILURE.
>
><bpasc...@googlemail.com> wrote in message
>news:cf6b7eb3-88e7-4c92...@j12g2000vbl.googlegroups.com...
>
>[snip]
>
>> if ( cnt > 1 && atoi(buffer) )
>
>...
>
>Many prefer strtol to atoi. atoi returns nothing and strtol can be error
atoi is defined to return an int if the value is in range.
>checked. Very good you sure learn quickly. Your better than me and I've been
>studying on and off for several years now. But I've never made a point of
>pointers til now :)
>
>Bill
>
--
Remove del for email
> What(free) tool in my windows Xp context can I use to debug ?
Under Windows there is a choice of much more up-to-date compilers to use,
for example gcc (as mingw), lcc-win32, and DMC (digital mars). And they
might have debug systems that are more usable (I wouldn't know).
Using DMC, your program crashed when entering the separator using getche().
Changing this to getch() (and printing symbol to the screen) seemed to fix
that. Maybe your djp-whatever compiler has the same problem.
--
Bart
That looks like a typo.
if ( ((cnt - i ) % 3) == 0 && i != 0 )
> > What(free) tool in my windows Xp context can I use to debug ?
>
> Under Windows there is a choice of much more up-to-date compilers to use,
> for example gcc (as mingw), lcc-win32, and DMC (digital mars).
also Microsoft's Visual C++ Express. It's free, and despite the name,
can be coerced into being a C compiler
> And they
> might have debug systems that are more usable (I wouldn't know).
VCC has a fine debugger (Idon't know what "simify" has)
> > I am first an accountant and decided to take on programming a few
> > years ago... I have been first studying simple algorithms...
>
> > Now I have decided to first learn C (i'll give it 600 effective hours -
> > so btw 1 and 3 years) before going to c++ or perl, or python, java or
> > php or ruby on rails or vba, i'll see at that time what answers most
> > my needs either as a professionnal accountant or as a personal project
> > i'd like to take on... Is there anything specific I could do with a
> > good knowledge of C only ?
>
> > So I have been having a hard time with the basics of pointers (20
> > hours). I really want to feel ok with this before getting any further.
> > I haven't looked at functions yet.
>
> You've had some advice already but I'd like to add something very
> general. "Putting off" functions is a bad idea. They are the key
> tool for decomposing problem into simpler problems and for building
> complex behaviour from simple behaviour. In short, they are a central
> theme in programming and you end up making matters worse by using a
> text that delays introducing them.
there are plenty of languages without pointers and, I'd argue, none
without functions. I don't classify it as a programming language if
it
doesn't have functions!
Functions are way of breaking problems down into sub-problems.
Of using ready built solutions (by you or someone else).
We use them in every day life. "drizzle the olive oil", "knit one",
"remove the cover plate", "goto the airport", "select print".
Functional decomposition is what makes life bearable.
> Learn to write simple functions and then learn how to combine simple
> functions. The habit of writing lots of function should stay with you
> throughout your programming life.
>
> There are other signs that the book you are using is not a good one.
> Have you has a look at "The C Programming Language, 2nd Edition" by
> Kernighan and Ritchie?
You *really* should.
> A few other general tips...
>
> If you find yourself writing "flag" variables (like "ok" in your
> program) think again. Experienced programmers use then a lot less the
> beginners for reasons I have never fully understood.
Its to do with Span of Control matching Scope of Control
if I remember my Constantine and Yourdon correctly.
:-)
> If you still
> want to use one, give it a helpful name than "ok".
>
> In C, *(output + i) is the same as output[i]. You use both forms in
> your program but the second is almost always clearer.
--
there may have been other things between sliced bread and Java
> there are plenty of languages without pointers and, I'd argue, none
> without functions.
Prolog (it has relations) and more generally rule-based languages.
(Rules are not functions.) Early BASICs. Assembler. Does COBOL have
functions?
> I don't classify it as a programming language if
> it doesn't have functions!
Well, maybe. (I don't classify it as a /proper/ programming language
unless it as /first-class/ functions.)
--
"This town is run by seven megalomaniac wizards!" /Archer's Goon/
Hewlett-Packard Limited registered office: Cain Road, Bracknell,
registered no: 690597 England Berks RG12 1HN
> nick_keigh...@hotmail.com wrote:
>
>> there are plenty of languages without pointers and, I'd argue, none
>> without functions.
>
> Prolog (it has relations) and more generally rule-based languages.
> (Rules are not functions.) Early BASICs. Assembler. Does COBOL have
> functions?
Yes.
COBOL provides the language facilities for a programmer to subdivide his
program into functional units, at three different levels (two "private"
levels, and one "public" level).
COBOL provides mechanisms to permit multiple "public" entrypoints ("PROGRAM
NAME"s and their associated "PROCEDURE DIVISION" code) within a single
compilation unit.
Within the code for a single "public" entrypoint, COBOL provides a named
division of code to group and identify high-level functional units
("SECTION"s), and within each of these divisions, COBOL provides a named
division of code to group and identify low-level functional units
("PARAGRAPH"s). Both SECTION and PARAGRAPH identifiers are "private", and
not exposed outside of the code for the "public" entrypoint"
With the advent of linkage-editors in the mid-1900's (circa 1950), COBOL
(and other high-level-languages) gained the ability to further subdivide
programming activities into functional components, by permitting access of
one public-named functional unit from a functional unit in a separate
compilation unit.
>> I don't classify it as a programming language if
>> it doesn't have functions!
>
> Well, maybe. (I don't classify it as a /proper/ programming language
> unless it as /first-class/ functions.)
I guess that there are many programming languages that don't satisfy your
definition for a /proper/ programming language, then. OTOH, many systems
(and /proper/ programming language compilers) have been built using those
languages. To each his own, I guess. To me, a /proper/ programmer should be
able to write a program without depending on the features of /any/ specific
language (or, conversely, should be able to express the program in /any/
language that s/he knows). Programming languages are (or should be)
secondary knowledge to /proper/ programmers; the /primary/ knowledge of
a /proper/ programmer is how to design and write a program that achieves
the programmers goal. But, then again, that's just my opinion. :-)
--
Lew Pitcher
Master Codewright & JOAT-in-training | Registered Linux User #112576
http://pitcher.digitalfreehold.ca/ | GPG public key available by request
Thanks for your interest and all these infos.
Some infos go beyond my present early beginner level but it makes
things look interesting for the futur if I can still have the chance
to keep studying C at this pace (I have started 2 and a half months
ago ).
I 'm not part of a computer university class nor part of a certificate
program where for the first case students have to learn many different
subjects and languages simultaneously and second case unlike java, C
online certificate are not that common unless embedded with C++ (I
understand by the name C++ is an extension of C and there are objects
in C++ and I don't see why each google C query leads to a C++ forum or
site or why C is most of the time link to C++ ?
I feel attracted in C because of the freedom in coding it gives,
unlike coding with objects where I think objects are less easy to deal
with when facing someting new and unexpected. Of course, on the other
hand, objects are more powerful. I am not sure why. It might be
because I have no idea of what objects bring as advantages over lines
of codes.
===O===
About the script ; the first script I have posted on Jun 10, 12:58 am
is working fine, the second one (posted on Jun 10, 1:14 am) is the one
not working. Sorry for this confusion.
===O===
Someone says at this point, it's not a priority to learn how to debug.
So I'll come back later when I'll have bigger program in size, I
understand it should make more sense then.
By the way, I'm not putting anything such as functions away, it's just
I am following book chapters.
In the 2 books I am learning from, functions come just after
pointers ... but in one book (the most difficult but more complete one
"from G. Willms - french Version published by PC Poche") pointers come
far after arrays but still before functions.
In the other book written by "Tony Zhang published in french by Campus
Press / Pearson education") Pointers precede Arrays and Functions.
So, in both books, functions come after arrays and pointers...
But before getting on functions which I believe is something huge, I'd
first look at preprocessor things.
===O===
Some people in this topic say the books I am studying from might be
old. Doest it make a difference at a starting level ? Is there a new C
standardized version that revolutions things ?
===O===
About portability :
I have started learning and coding simple programs on both Linux
Ubuntu and Windows Borland and Dolorie gcc.
The 2 books I am learning from say to use getchar() instead of getche
()
getchar() and
while ( getchar() != '\n' ) ;
to make scripts work on Linux.
As Andrew says puts replaces printf without the '\n'. Puts is only to
be use where no variable arguments such as %d, %s ... At this point,
those 2 books I am learning from tell about puts but don't make much
use of it.
I'll try this script with modifications on Ubuntu but I expect many
other issues.
At this point I'm not focusing on portability. Should portability be a
subject to focus on at this beginner level?
===O===
There are many stuff in the script initially posted where my
understanding is low.
Ex. : atoi(buffer) ;
Does it says to convert alphanumeric characters to integers?
It's the first time I see atoi.
In the book where the script is taken from, it says about atoi it
checks if the number only has zeros in it.
So, I understand atoi() returns a boolean value.
I'll try to use strtol instead, I have never seen it but i'll try to
remember about atoi and strtol or strtoul and the same for gets and
fgets.
===O===
The most difficult thing to understand there was
while ( *pc++ == *pb++ )
;
From my understanding, it says as a loop until an empty value is
return to copy the content/variable of * pb into * pc and right after
to increment pb and pc then, the loop restarts and says to copie pb
into pc ...
Is it the right understanding ?
Is it as correct as :
while (* pb) /* while * pb != 0 */
{
* pc = *pb ;
pb ++ ; pc++ ;
}
===O===
I first came here to learn how to debug but it seems there are people
who have answer to my C related question, google takes me most of the
time to C++ forum and websites.
Thanks,
Pascal
> On June 10, 2009 09:11, in comp.lang.c, Chris Dollin (chris....@hp.com)
> wrote:
>> Well, maybe. (I don't classify it as a /proper/ programming language
>> unless it as /first-class/ functions.)
>
> I guess that there are many programming languages that don't satisfy your
> definition for a /proper/ programming language, then.
Oh, yes. Many many. Many many many. It is to weep.
> OTOH, many systems (and /proper/ programming language compilers) have
> been built using those languages.
Of course. I didn't say those languages were useless. (Painful,
that I would say.)
> To each his own, I guess. To me, a /proper/ programmer should be
> able to write a program without depending on the features of /any/ specific
> language (or, conversely, should be able to express the program in /any/
> language that s/he knows). Programming languages are (or should be)
> secondary knowledge to /proper/ programmers; the /primary/ knowledge of
> a /proper/ programmer is how to design and write a program that achieves
> the programmers goal. But, then again, that's just my opinion. :-)
I don't believe that such design can be done without at least a
view as to which (kind of) language will be used; I don't believe
programming can be done without a programming language. Certainly
there is /some/ transferable knowledge.
About /proper programmers/ I make and made no claims in these two
messages.
--
"This town is run by seven megalomaniac wizards!" /Archer's Goon/
Hewlett-Packard Limited Cain Road, Bracknell, registered no:
registered office: Berks RG12 1HN 690597 England
<snip>
> By the way, I'm not putting anything such as functions away, it's just
> I am following book chapters.
>
> In the 2 books I am learning from, functions come just after
> pointers ... but in one book (the most difficult but more complete one
> "from G. Willms - french Version published by PC Poche") pointers come
> far after arrays but still before functions.
>
> In the other book written by "Tony Zhang published in french by Campus
> Press / Pearson education") Pointers precede Arrays and Functions.
>
> So, in both books, functions come after arrays and pointers...
>
> But before getting on functions which I believe is something huge, I'd
> first look at preprocessor things.
All I can say is that this is not a good sign for these books. Can
you get hold of anything else? I don't suggest learning in a
different order just to be awkward -- it really makes like simpler.
<snip>
> There are many stuff in the script initially posted where my
> understanding is low.
>
> Ex. : atoi(buffer) ;
> Does it says to convert alphanumeric characters to integers?
> It's the first time I see atoi.
>
> In the book where the script is taken from, it says about atoi it
> checks if the number only has zeros in it.
>
> So, I understand atoi() returns a boolean value.
In C, all integers can be used in a boolean context (an 'if', a
'while' and so on) but atoi returns the numerical value of the initial
portion of the string it is passed. Since in C 0 is taken to be false
and non-zero taken to be true, testing atoi(some_string) can tell you
if it contains digits other than zero at the start. It is not a good
way to do this test, but it is close enough.
<snip>
> The most difficult thing to understand there was
>
> while ( *pc++ == *pb++ )
> ;
>
> From my understanding, it says as a loop until an empty value is
> return to copy the content/variable of * pb into * pc and right after
> to increment pb and pc then, the loop restarts and says to copie pb
> into pc ...
>
> Is it the right understanding ?
No. == tests for equality. Nothing is copied. It may be that = was
intended as that will copy the characters from pb to pc.
> Is it as correct as :
>
> while (* pb) /* while * pb != 0 */
> {
> * pc = *pb ;
> pb ++ ; pc++ ;
> }
No. This loop is different to the one above and it is different from
what I think you might have meant! Even if the loop above had been
while (*pc++ = *pb++);
the second version remains different. Rather than tell you, step
through what they do when pb points to the 'a' in "abc".
--
Ben.
> nick_keigh...@hotmail.com wrote:
>
> > there are plenty of languages without pointers and, I'd argue, none
> > without functions.
>
> Prolog (it has relations) and more generally rule-based languages.
> (Rules are not functions.) Early BASICs.
Dartmouth BASIC had DEF FN. It's a very limited form of function, but it
is a function definition.
Richard
Was there a BASIC without GOSUB ?
Most CPU's have a call/return or jsr/ret or similar set of instructions.
Cobol has something similar too, I think.
Granted, these are procedures, not functions, but in the sense of this
discussion we were more talking about procedures anyway.
I think the Prolog 'rules' can also be classified as procedures ?
SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
I'd agree with this - for any program less than a few hundred lines,
it's probably easier to step through the code manually than to use a
debugger anyway.
> [snip]
>
> Some people in this topic say the books I am studying from might be
> old. Doest it make a difference at a starting level ? Is there a new C
> standardized version that revolutions things ?
>
Not since 1989. (There was another standardized version in 1999, but it
was neither revolutionary nor widely adopted.)
The issue with using an older book is that programming technique (and
teaching techniques) have evolved immensely over the years. For example,
back in the day micro-optimizations - loops counting down instead of up,
and such things - were useful. But now this is considered "premature
optimization" and the goal is always to make your code readable, rather
than fast.
This is true of all languages, not just C.
> [snip]
>
> The 2 books I am learning from say to use getchar() instead of getche
> ()
>
> getchar() and
> while ( getchar() != '\n' ) ;
>
> to make scripts work on Linux.
>
getchar() will work -everywhere- that C does, not just Linux, and
including Windows. Why the book would use getche() at all is beyond me.
> [snip]
>
> At this point I'm not focusing on portability. Should portability be a
> subject to focus on at this beginner level?
>
My opinion (and the one shared by most of this group) is that unless you
have a reason not to, you should focus on portability.
Certainly, anything taught in a beginner's C book should be done
portably. The reason for this is that you can learn to do everything the
portable way, and then later on when you need to do things that are non-
portable (say, using display hardware or networking or whatever), you'll
be able to write most of your program portably.
As for the non-portable bits, they can be hidden away in functions, and
then when you need to move your code, you only have to change the
functions, not the main logic.
> [snip]
>
> I first came here to learn how to debug but it seems there are people
> who have answer to my C related question, google takes me most of the
> time to C++ forum and websites.
>
That is true - unfortunately, like too many new programmers, Google does
not know the difference between C and C++. You can try searching C in
quotes like "C", and that should reduce hits for the word C++.
But bear in mind that much of the information on the Internet (for both
C and C++) is sloppy code, and often non-portable or simply wrong.
Except for those languages intentionally designed
to be obfuscatious. (eg, whitespace, intercal,
unlambda, perl)
> >> there are plenty of languages without pointers and, I'd argue, none
> >> without functions.
<snip>
> >> I don't classify it as a programming language if
> >> it doesn't have functions!
>
> > Well, maybe. (I don't classify it as a /proper/ programming language
> > unless it as /first-class/ functions.)
>
> I guess that there are many programming languages that don't satisfy your
> definition for a /proper/ programming language, then.
the majority I think! Including C!
<snip>
I don't know why you think "whitespace" is designed to be
obfuscatory. It is well-known that adding whitespace to a program
/improves/ readability. All that Brady and Morris have done is
explore the logical consequences of improving readability
/maximally/. People might struggle with hashes (pounds) and tildes
and ampersands, but spaces are easy.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Forged article? See
http://www.cpax.org.uk/prg/usenet/comp.lang.c/msgauth.php
"Usenet is a strange place" - dmr 29 July 1999
<snip>
> (I
> understand by the name C++ is an extension of C
that's what the name implies but there are enough additions and
changes
to C++ to make it, really, a different language. Although most well
written
C will compile and execute correctly with a C++ compiler in reality
idiomatic C++ doesn't look much like idiomatic C.
> and there are objects
> in C++ and I don't see why each google C query leads to a C++ forum or
> site or why C is most of the time link to C++ ?
bad luck. Some people confuse the two (maybe google does).
> I feel attracted in C because of the freedom in coding it gives,
> unlike coding with objects
I don't think OO programming is significantly "less free". Whatever
*that* means!
> where I think objects are less easy to deal
> with when facing someting new and unexpected.
they're actually pretty good with the new and unexpected things
but they add to the beginner's learning curve. Particularly
a language like C++ which is C with objects (and other stuff!)
added. Remember most C programs are also C++ programs
(or close to).
> Of course, on the other
> hand, objects are more powerful. I am not sure why.
their advantages may not be very obvious until you
start to deal with large programs. They allow you to break
a large program into small pieces (C provides techniques
to do this as well). This modularisation is what allows
complex systesm to be developed. Some of the most
complex artifacts on earth are computer programs.
> It might be
> because I have no idea of what objects bring as advantages over lines
> of codes.
even objects end up as lines of code somewhere!
> Someone says at this point, it's not a priority to learn how to debug.
it's a priority to learn how to write correct programs!
If you can't write 'em correctly from scratch (and few people can)
you're going to have to debug 'em some how!
Note "debug" does not necessarily mean "use a debugger".
[hi richard!]
Often
it means examine the output or output from intermediate stages
and reason about the program until you work out why the behaviour
of the program is different from that which you expect. A debugger
can help you do this but it isn't the only way.
- good quality logging
- test suites
- run time assertions
- prrofs of correctness (these are hard actually!)
> So I'll come back later when I'll have bigger program in size, I
> understand it should make more sense then.
if you can't write small correct programs you won't write big correct
programs.
> By the way, I'm not putting anything such as functions away, it's just
> I am following book chapters.
>
> In the 2 books I am learning from, functions come just after
> pointers ... but in one book (the most difficult but more complete one
> "from G. Willms - french Version published by PC Poche") pointers come
> far after arrays but still before functions.
>
> In the other book written by "Tony Zhang published in french by Campus
> Press / Pearson education") Pointers precede Arrays and Functions.
>
> So, in both books, functions come after arrays and pointers...
>
> But before getting on functions which I believe is something huge,
you may be pleasantly surprised. I'd say functions were absolutely
fundamental to programming. But that doesn't really make them hard.
For technical reasons C needs pointers to do certain things with
functions (pass modifiable arguments) that other languages do by
other means. C is very low level" Very close to the machine. This
is its blessing and its curse.
> I'd first look at preprocessor things.
the preprocessor is pretty ugly, but necessary
> Some people in this topic say the books I am studying from might be
> old. Doest it make a difference at a starting level ? Is there a new C
> standardized version that revolutions things ?
C divides up in to roughly three eras.
1. pre-1989 there was no formal standard but a defacto one
2. 1989 standard
3. 1999 standard
The 1989 standard will still run all the well written pre-standard
stuff. You don't seem to be writing to the pre-1989 "standard"
so ignore it. The 1999 standard was very slow to be adopted. It is
*still*
not widely implemented and many users who value C for its portability
use the 1989 standard. Your code looks ok for either 1989 of 1999.
They didn't discard anything important in the 1999 standard (pre-1989
code might have problems).
<snip>
> At this point I'm not focusing on portability. Should portability be a
> subject to focus on at this beginner level?
not really, but if you know a portable way to do something
why not do it? Running on Windows and Unix will tend to draw
your attention to really non-portable things.
> ===O===
>
> There are many stuff in the script initially posted where my
> understanding is low.
>
> Ex. : atoi(buffer) ;
> Does it says to convert alphanumeric characters to integers?
> It's the first time I see atoi.
yes. You need a good reference. Eg. K&R. But this isn't bad:-
http://www.dinkumware.com/manuals/default.aspx#Standard%20C%20Library
just typeing "atoi" into google has a good chance of answering your
question.
> In the book where the script is taken from, it says about atoi it
> checks if the number only has zeros in it.
this sounds wrong. Do you mean "...only has digits in it"?
> So, I understand atoi() returns a boolean value.
nope. Booleans are either true or false. atoi() returns an integer.
> I'll try to use strtol instead, I have never seen it but i'll try to
> remember about atoi and strtol or strtoul and the same for gets and
> fgets.
atoi() isn't as bad as gets(). atoi() only gives you the wrong
answer, gets() opens a gigantic security hole that allows all sorts
of exploits and virii.
> ===O===
>
> The most difficult thing to understand there was
>
> while ( *pc++ == *pb++ )
> ;
that is rather idiomatic
> From my understanding, it says as a loop until an empty value is
> return to copy the content/variable of * pb into * pc and right after
> to increment pb and pc then, the loop restarts and says to copie pb
> into pc ...
>
> Is it the right understanding ?
>
> Is it as correct as :
>
> while (* pb) /* while * pb != 0 */
> {
> * pc = *pb ;
> pb ++ ; pc++ ;
>
> }
yes. excellent!
> ===O===
>
> I first came here to learn how to debug but it seems there are people
> who have answer to my C related question, google takes me most of the
> time to C++ forum and websites.
>
> Thanks,
no problem
--
Nick Keighley
> Chris Dollin wrote:
> ) nick_keigh...@hotmail.com wrote:
> )
> )> there are plenty of languages without pointers and, I'd argue, none
> )> without functions.
> )
> ) Prolog (it has relations) and more generally rule-based languages.
> ) (Rules are not functions.) Early BASICs. Assembler. Does COBOL have
> ) functions?
>
> Was there a BASIC without GOSUB ?
Unlikely. Since GOSUB doesn't provide you with functions, it
doesn't matter. It doesn't even provide you with procedures,
IMAO.
> I think the Prolog 'rules' can also be classified as procedures ?
At the risk of being incorrect, I'd say.
--
"You're down as expendable. You don't get a weapon." /Dark Lord of Derkholm/
> <bpascal...@googlemail.com> wrote:
> > I'll try to use strtol instead, I have never seen it but i'll try to
> > remember about atoi and strtol or strtoul and the same for gets and
> > fgets.
>
> atoi() isn't as bad as gets().
Yes, but...
> atoi() only gives you the wrong answer,
...no. atoi() isn't as bad as gets() only because, making more effort
than you should need to, you _can_ stop atoi() from having undefined
behaviour using ISO C only. You cannot do that with gets(). However, if
you don't make that effort, and pass atoi() a string it cannot handle,
it will still have behaviour that is equally as undefined as gets().
In the mean time, Pascal has made the right choice: use strtol().
> gets() opens a gigantic security hole that allows all sorts
> of exploits and virii.
^^
*THWACK* There ain't no such word. If you don't speak Latin, don't
pretend to.
Richard
> Willem wrote:
>
>> Chris Dollin wrote:
>> ) nick_keigh...@hotmail.com wrote:
>> )
>> )> there are plenty of languages without pointers and, I'd argue, none
>> )> without functions.
>> )
>> ) Prolog (it has relations) and more generally rule-based languages.
>> ) (Rules are not functions.) Early BASICs. Assembler. Does COBOL have
>> ) functions?
>>
>> Was there a BASIC without GOSUB ?
>
> Unlikely. Since GOSUB doesn't provide you with functions, it
> doesn't matter. It doesn't even provide you with procedures,
> IMAO.
If not "procedure", what name would you give to a self-contained piece
of code intended to be called via GOSUB?
> Chris Dollin <chris....@hp.com> writes:
>
>> Willem wrote:
>>
<snip>
>>>
>>> Was there a BASIC without GOSUB ?
>>
>> Unlikely. Since GOSUB doesn't provide you with functions, it
>> doesn't matter. It doesn't even provide you with procedures,
>> IMAO.
>
> If not "procedure", what name would you give to a self-contained
> piece of code intended to be called via GOSUB?
SUBroutine
> Chris Dollin wrote:
> ) nick_keigh...@hotmail.com wrote:
> )
> )> there are plenty of languages without pointers and, I'd argue, none
> )> without functions.
> )
> ) Prolog (it has relations) and more generally rule-based languages.
> ) (Rules are not functions.) Early BASICs. Assembler. Does COBOL have
> ) functions?
>
> Was there a BASIC without GOSUB ?
Apparently, there is/was.
GOSUB is part of the original (Dartmouth) BASIC, but (so the Wikipedia
article says) FreeBASIC deprecated (and disabled) GOSUB in favour of
the "SUB" keyword.
[snip]
--
Lew Pitcher
Master Codewright & JOAT-in-training | Registered Linux User #112576
http://pitcher.digitalfreehold.ca/ | GPG public key available by request
---------- Slackware - Because I know what I'm doing. ------
> If not "procedure", what name would you give to a self-contained piece
> of code intended to be called via GOSUB?
In the versions of BASIC that I used, GOSUB subroutines were
hardly self-contained, because there was no notion of local
variables.
--
"The fact that there is a holy war doesn't mean that one of the sides
doesn't suck - usually both do..."
--Alexander Viro
"subroutine" sounds like it might have a place is computing terminology
....
--
"Avoid hyperbole at all costs, its the most destructive argument on
the planet" - Mark McIntyre in comp.lang.c
I'd call it a subroutine, but I think of both functions and procedures
as kinds of subroutines.
This is all meaningless without a definition of the word "procedure".
And since C doesn't use the word "procedure", ...
--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
I have made quite a gigantic step with some answers, thanks!
I will now try to focus on portablity even if it's boring to switch
between xp and linux ubuntu...
ONE THING I want to say is that I didn't "invent" any lines of this
script, I have copied and learned it by heart from a book written by
G.Willms, so credit and discredit should be addressed to him ... I
wouldn't say if there is anything right or not right for this little
script. To me, I find this book conveniant (that's a beginner point of
view). I'm sure there are a lot more books and if I want to go further
with C, I will look for a good reference (the price should match the
content).
By the way, my method to learn is 3/4th of the time to learn by heart,
like to write a script like this one over and over until i remember
all of it or the most important part.
1/4th of the time to read and practise through exercices. Then when i
practise, i recall what i have learned by heart and then of course I'm
not close to the official solution (i need more variable and i have
less controls of the user's input) but the program works.
I don't know if it'a good method but to be honest i find it easy to
implement in terms of concentration and stuff...
Pascal
Officially (Dartmouth again) it was called a subroutine, surprisingly
enough.
Richard
C is a low-level language, while it can be used for high-level app
programming, it's natural domain is in embedded and system
programming, or compiler writing. As an accountant you are better off
starting with a more high-level language, like Java. Before doing
that, learning a scripting language like Python, could be useful.
--
Tor <echo bwz...@wvtqvm.vw | tr i-za-h a-z>
Yes, but i have readen somewhere that C is useful when other languages
can't solve a specific matter and it is quite good to understand the
basics of C.
So far, I seek not to spend my entire life with C ( around 600 hours
or 1-2 years, if i don't have too many duties...)
Then I would learn C++ for 300 hours (I have readen C++ is more for
game programming but i belive you can do a lot more with C++).
Aftward, a quick look at perl and a deeper look at Python (maybe 2
years overall).
Then I'd see what's hot and what are my goals at this time ;
-web developpements (I have a good knowledge of html and an I have
been dealing with css for about 1 year and I had some insights of
php...
-database programming (this is close to an accountant's job).
I am doing things at a personal pace, for instance, one day I can
learn and write 10 scripts, and for a week i can just let it go
because of personal duties, fatigue... but i read at least everyday a
chapter or a programm about in C.
I can only say my skills in a any of these languages mentionned above
will remain basics for the next 10 years.
Then i hope to be able to talk seriously with real programmers, i
don't know, maybe getting to know how car systems work, gps, mobile
phones, online databases... computer is a very wide area, I just hope
not to get lost.
>> ... As an accountant you are better off
>> starting with a more high-level language, like Java. Before doing
>> that, learning a scripting language like Python, could be useful.
> Yes, but i have readen somewhere that C is useful when other languages
> can't solve a specific matter and it is quite good to understand the
> basics of C.
>
> So far, I seek not to spend my entire life with C ( around 600 hours
> or 1-2 years, if i don't have too many duties...)
The problem is you might get frustrated by not being able anything very
exciting in C without a lot of fiddly, error-prone code. Or without
importing third party libraries which is an area of expertise all by itself.
So the suggestion to use a 'softer' language first is good and will give a
useful perspective.
--
Bart
C, C++ and Perl?!
I must say, this is among the 3 worst languages a non-professional could
pick to start up with.
> -database programming (this is close to an accountant's job).
Well then, why not start up with SQL? Just, install MySQL and poke
around. Lost of stuff to learn, and add some PHP scripting to your web
pages using those SQL tables.
After that, look at Java.
I'm not fully convinced because you don't tell the reason why
choosing
C, C++, Perl to learn programing is a bad choice.
I have tried php and vba (for the last, i'm able to copy-paste excel
macros found in google and rearrange them to achieve something).
For php (i was learning basic simple algorithms at that time for a
year long (3 hours/a week) algos with very few maths (not my cup of
tea) but enough to understand a checkers application.
After a few php scripts and my first sips of { ' " $ I decided that
algo weren't enough and when i'd time i'd learn how to program with
true, bullet-proof computer language. And with C (unlike with vba) I
feel it is close to those algos I have learnt alone and for some
reasons, it wasn't a easy time...
So, please Tor, be more explicit about why C, C++, Perl are bad to
start with.
Don't forget I have studied (simple level) algos on my own.
Cheers,
Pascal
Actually I said quite a lot here:
"C is a low-level language, while it can be used for high-level app
programming, it's natural domain is in embedded and system
programming, or compiler writing."
C gives the programmer a lot of freedom and speed, this is great for
professionals, we usually know what we are doing and can spend a lot of
time on details, such as algorithms, protocols, HW details, database,
standards etc. These days, before digging into C, the students usually
learn the basics of programming in some high language first.
* C is weakly typed, easier if the language is strongly typed
* C has pointers, easier if the language has no pointers
* C has manual memory management, easier if the languages has automatic
memory management
* Not much diagnostics required from a C compiler. Invalid C programs
may be translated without a warning.
* no run-time checks for buffer overflow
C assume the programmer is right and don't stop him from doing the job,
a beginner is usually wrong and should be stopped.
C is like driving a Formula One race car, you are better off getting
your driver licence in a Volvo.
> C is like driving a Formula One race car, you are better off getting
> your driver licence in a Volvo.
I disagree. I got my license in a VW Golf, and drive a Volvo now. I
prefer my Volvo, but the Golf was definitely more forgiving on beginning
drivers. Also, Formula One cars aren't for advanced drivers, but for a
very, very few.
Pascal is a VW Golf; C is a Porsche; INTERCAL is a Formula One car.
Richard
I wouldn't actually agree that C is such a bad first language, but this is
the reason given. C++ is a bad first language - it is extremely complex and
many of the constructs are hard to understand for someone who has little
programming experience. I am an experienced programmer and I find Perl's
rules totally frustrating, because of things like the implicit variables and
the array/scalar contexts, also the odd way in which compound types are
constructed. I find I have to scratch around in the manual to perform
relatively simple operations like sorting an array.
Ok guys, opinions diversify. I will keep on learning the basics of C
and afterwards if i see i'm facing a wall, i'll go on with a more
accessible language. I don't want to specialize for the next 2-3 years
(given i can have ennough time to keep on learning...).
If i'd ever specialize, i hope to go more intensevly (maybe take 6
months off and attend a class) with whatever language i'm on. It could
be C++, VBA, Python, Java, Php, Ruby... Java is very popular for
university certificates and more.
Anyhow, I think a basic understanding of C will help.
Thanks
Between a WV Golf, Volvo, Porshe (i don't have a car, I live in Paris
and i ride the tube/subway so i can read a C book)
Pascal
INTERCAL was designed as a joke, a parody of the languages of 60 ties.
:) If you are looking for weird stuff, here is "Hello World" in Malbolge
('&%:9]!~}|z2Vxwv-,POqponl$Hjig%eB@@>}=<M:9wv6WsU2T|nm-,jcL(I&%$#"
`CB]V?Tx<uVtT`Rpo3NlF.Jh++FdbCBA@?]!~|4XzyTT43Qsqq(Lnmkj"Fhg${z@>
or what about the readability of brainf**k:
+[>>+++++[<++++++>-]<[>++++[>++++++++<-]<[->+>.<<]>[-<+>]+++++
[>+++++<-]>+++.-.<+++[>------<-]>.---------.<+++++[>++++++<-]>
.--.[-]++++++++++.[-]<<-]>+++++[<++++++>-]>>[-]<<<[>++++[>++++
++++<-]>>[<.>>+<-]>[-<+>]<+<<+++++[->++++++<]>.--.<++++[>-----
--<-]>.++++++++.<+++[>++++++<-]>.++++.[-]++++++++++.[-]<<-]<]
Obfuscated C comes short:
#define P(X)j=write(1,X,1)
#define C 39
int
M[5000]={2},*u=M,N[5000],R=22,a[4],l[]={0,-1,C-1,-1},m[]={1,-C,-1,C},*b=N,
*d=N,c,e,f,g,i,j,k,s;main(){for(M[i=C*R-1]=24;f|d>=b;){c=M[g=i];i=e;for(s=f=0;
s<4;s++)if((k=m[s]+g)>=0&&k<C*R&&l[s]!=k%C&&(!M[k]||!j&&c>=16!=M[k]>=16))a[f++
]=s;if(f){f=M[e=m[s=a[rand()/(1+2147483647/f)]]+g];j=j<f?f:j;f+=c&-16*!j;M[g]=
c|1<<s;M[*d++=e]=f|1<<(s+2)%4;}else e=d>b++?b[-1]:e;}P("
");for(s=C;--s;P("_")
)P(" ");for(;P("\n"),R--;P("|"))for(e=C;e--;P("_ "+(*u++/8)%2))P("|
"+(*u/4)%2
);}
> Anyhow, I think a basic understanding of C will help.
Sure will, and in my view K&R2 is one of the best programming books ever
written.
> Between a WV Golf, Volvo, Porshe (i don't have a car, I live in Paris
> and i ride the tube/subway so i can read a C book)
In Paris, taking the Metro is easy, safe and very goes very fast.
Programming languages are not quite like that, some are easier, some are
safer and some are famous for their speed.
Was in a massive traffic jam in Paris once, a big road crossing where no
cars could move, have felt like that when programming in C sometimes. :)
> nick_keigh...@hotmail.com wrote:
>
> > there are plenty of languages without pointers and, I'd argue, none
> > without functions.
>
> Prolog (it has relations) and more generally rule-based languages.
> (Rules are not functions.) Early BASICs. Assembler. Does COBOL have
> functions?
>
> > I don't classify it as a programming language if
> > it doesn't have functions!
>
> Well, maybe. (I don't classify it as a /proper/ programming language
> unless it as /first-class/ functions.)
In C, technically functions aren't first-class, but pointers to
functions are first-class. Some people might consider C functions
somewhat impoverished compared to functions in other languages, but
they are first-class (with the understanding that we're letting
pointers-to-functions stand in for functions).
> Nick Keighley <nick_keigh...@hotmail.com> wrote:
>
> > <bpascal...@googlemail.com> wrote:
>
> > > I'll try to use strtol instead, I have never seen it but i'll try to
> > > remember about atoi and strtol or strtoul and the same for gets and
> > > fgets.
> >
> > atoi() isn't as bad as gets().
>
> Yes, but...
>
> > atoi() only gives you the wrong answer,
>
> ...no. atoi() isn't as bad as gets() only because, making more effort
> than you should need to, you _can_ stop atoi() from having undefined
> behaviour using ISO C only. You cannot do that with gets(). However, if
> you don't make that effort, and pass atoi() a string it cannot handle,
> it will still have behaviour that is equally as undefined as gets().
What I think you mean is that the behavior /specification/ of atoi()
in such cases is equally undefined as the behavior specification of
gets() under analogous circumstances. It's likely that the /actual/
behavior of atoi() is much more well-defined than the behavior of
gets() in such cases.
I don't think that's what he meant. As far as the standard is
concerned, undefined behavior is undefined behavior. It's true that
atoi("99999999999999999999999999") is less likely to crash your
program or corrupt memory than gets(buf) while your cat is sitting on
the keyboard, but that's no excuse for being careless.
The point, I think, is that it's possible to use atoi() safely by
refraining from calling it with certain arguments. It's not possible
to use gets() safely, because its input is whatever appears on stdin,
and you typically have no control over that. The only defense (unless
you somehow have absolute control over what appears on stdin) is to
avoid calling gets() at all.
On the other hand, the effort required to use atoi() safely probably
exceeds the effort required to use strtol().
There's an ambiguity because the word "behavior" has a meaning
in two different contexts, the context of the Standard, and the
context of everyday life.
In the Standard, "behavior" is a description of what a program
/may/ do (ie, is allowed to do by the Standard).
In ordinary conversation, "behavior" is what a program
/actually does/.
The original comment was made (I believe) about "behavior" in the
first sense.
That statement could also be read taking "behavior" in the second
sense. In fact I think that mistake would be easy to make by
people who aren't used to the CLC argot. My comment was meant to
point out the ambiguity and clarify the distinction. Hopefully
I'll be more successful with that in this second posting than I
was in the first. :)
> The point, I think, is that it's possible to use atoi() safely by
> refraining from calling it with certain arguments. It's not possible
> to use gets() safely, because its input is whatever appears on stdin,
> and you typically have no control over that. The only defense (unless
> you somehow have absolute control over what appears on stdin) is to
> avoid calling gets() at all.
Perhaps, but practically speaking I wouldn't worry too much about
calling atoi() on malformed input, whereas I would never want to
call gets(). And I don't think that distinction is irrelevant,
even in comp.lang.c.
> On the other hand, the effort required to use atoi() safely probably
> exceeds the effort required to use strtol().
Technically speaking, or practically speaking? Technically
speaking, I agree with you. Practically speaking, in most cases
it's probably not worth worrying about; even if atoi() is used
wrongly, more often than not the cost of failure times the
probability of failure is still negligible.
> Keith Thompson <ks...@mib.org> writes:
>
>> Tim Rentsch <t...@alumnus.caltech.edu> writes:
>> > ral...@xs4all.nl (Richard Bos) writes:
>> >> Nick Keighley <nick_keigh...@hotmail.com> wrote:
>> >> > <bpascal...@googlemail.com> wrote:
<snip>
>> >> ...no. atoi() isn't as bad as gets() only because, making
>> >> more effort than you should need to, you _can_ stop atoi()
>> >> from having undefined behaviour using ISO C only. You cannot
>> >> do that with gets(). However, if you don't make that effort,
>> >> and pass atoi() a string it cannot handle, it will still have
>> >> behaviour that is equally as undefined as gets().
>> >
>> > What I think you mean is that the behavior /specification/ of
>> > atoi() in such cases is equally undefined as the behavior
>> > specification of gets() under analogous circumstances. It's
>> > likely that the /actual/ behavior of atoi() is much more
>> > well-defined than the behavior of gets() in such cases.
>>
>> I don't think that's what he meant. As far as the standard is
>> concerned, undefined behavior is undefined behavior. It's true
>> that atoi("99999999999999999999999999") is less likely to crash
>> your program or corrupt memory than gets(buf) while your cat is
>> sitting on the keyboard, but that's no excuse for being
>> careless.
>
> There's an ambiguity because the word "behavior" has a meaning
> in two different contexts, the context of the Standard, and the
> context of everyday life.
>
> In the Standard, "behavior" is a description of what a program
> /may/ do (ie, is allowed to do by the Standard).
In Section 3.4, the C99 Standard defines the word "behavior" as
"external appearance or action". From what I can tell, your
description here better describes /well-defined/ behavior, rather
than just "behavior", even as defined by the Standard.
It seems to me, in both senses of the word, "behavior" describes
what a program is able to do, not what it is permitted to do.
I apologize if I'm midunderstanding you or the Standard.
<snip>
--
Curtis
int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hell\
o, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}
~ Anonymous (1984 IOCCC winner)
Consider a statement like "if XYZ, the behavior is undefined."
This doesn't mean that what the program does is undefined; it
means what the program is allowed to do by the Standard is
undefined.
Now consider a statement like, "if I give my program an input
file of /dev/null, its bevahior is a little screwy." This
doesn't mean the program is allowed to be a little screwy, it
means what it actually does is a little screwy.
Another example: {unsigned u = 0; u = u+1; return u;} This
program fragment has "well-defined" behavior. But if we run the
program, and the memory for u gets hit by a cosmic ray, what the
program actually does may be different from what the Standard
requires it to do. Its behavior(1) is defined by the Standard,
but its behavior(2) is affected by cosmic rays (which are not
part of the Standard). The terms behavior(1) and behavior(2)
clearly can't mean the same thing.
Do you see the difference I'm trying to illuminate?
> I apologize if I'm midunderstanding you or the Standard.
No problem. These ideas are difficult to communicate.
"Behavior" is what a program actually does.
I agree that it's relevant, but I disagree with your conclusion.
I might use atoi() in a throwaway program that nobody else will ever
use, and that I won't use more than once or twice. (I might even use
gets() in the same circumstances.) For anything more serious than
that, I'd go to the extra effort to use strtol(). I would no more
assume that atoi("9999999999999999999") is harmless than I would
assume that INT_MAX + 1 is harmless. In both cases, a signed integer
overflow will probably give some arbitrary result, but on some
implementations it could crash the program.
Or I might use atoi() if the program logic guarantees that the
argument won't overflow, but even then I"d consider it to be too
fragile.
Programs inevitably have bugs, and programmers inevitably spend time
tracking down those bugs. There is considerable value in having one
less thing to worry about when the program's behavior goes awry.
I disagree. "Behavior" is what the program actually does.
And if a program doesn't behave in the way required by the standard,
the standard's statement about its behavior isn't incorrect, it's
merely inapplicable; just about everything the standard says applies
only to conforming implementations.
[snip]
> Tim Rentsch <t...@alumnus.caltech.edu> writes:
>> Curtis Dyer <dye...@gmail.com> writes:
>>> On 20 Jun 2009, Tim Rentsch <t...@alumnus.caltech.edu> wrote:
> [...]
>>> > In the Standard, "behavior" is a description of what a
>>> > program /may/ do (ie, is allowed to do by the Standard).
>
> I disagree. "Behavior" is what the program actually does.
>
> And if a program doesn't behave in the way required by the
> standard, the standard's statement about its behavior isn't
> incorrect, it's merely inapplicable; just about everything the
> standard says applies only to conforming implementations.
>
> [snip]
Thank you both (Tim and Keith). I'm not sure how I managed to get
confused over this. :-)
> Tim Rentsch <t...@alumnus.caltech.edu> writes:
> > Keith Thompson <ks...@mib.org> writes:
> [...]
> >> The point, I think, is that it's possible to use atoi() safely by
> >> refraining from calling it with certain arguments. It's not possible
> >> to use gets() safely, because its input is whatever appears on stdin,
> >> and you typically have no control over that. The only defense (unless
> >> you somehow have absolute control over what appears on stdin) is to
> >> avoid calling gets() at all.
> >
> > Perhaps, but practically speaking I wouldn't worry too much about
> > calling atoi() on malformed input, whereas I would never want to
> > call gets(). And I don't think that distinction is irrelevant,
> > even in comp.lang.c.
> [...]
>
> I agree that it's relevant, but I disagree with your conclusion.
>
> I might use atoi() in a throwaway program that nobody else will ever
> use, and that I won't use more than once or twice. (I might even use
> gets() in the same circumstances.) For anything more serious than
> that, I'd go to the extra effort to use strtol(). [snip]
I don't think our positions are that far apart here. We both
think it's better to use strtol() than atoi(); where I think we
differ is we put different priorities on doing that relative to
other attention-demanding tasks. I don't mean to disagree, only
to note the difference in priorities.
> On 22 Jun 2009, Keith Thompson <ks...@mib.org> wrote:
>
> > Tim Rentsch <t...@alumnus.caltech.edu> writes:
> >> Curtis Dyer <dye...@gmail.com> writes:
> >>> On 20 Jun 2009, Tim Rentsch <t...@alumnus.caltech.edu> wrote:
> > [...]
> >>> > In the Standard, "behavior" is a description of what a
> >>> > program /may/ do (ie, is allowed to do by the Standard).
> >
> > I disagree. "Behavior" is what the program actually does.
> >
> > And if a program doesn't behave in the way required by the
> > standard, the standard's statement about its behavior isn't
> > incorrect, it's merely inapplicable; just about everything the
> > standard says applies only to conforming implementations.
> >
> > [snip]
>
> Thank you both (Tim and Keith). I'm not sure how I managed to get
> confused over this. :-)
Happy to be of service. ;-)
> Tim Rentsch <t...@alumnus.caltech.edu> writes:
> > Curtis Dyer <dye...@gmail.com> writes:
> >> On 20 Jun 2009, Tim Rentsch <t...@alumnus.caltech.edu> wrote:
> [...]
> >> > In the Standard, "behavior" is a description of what a program
> >> > /may/ do (ie, is allowed to do by the Standard).
>
> I disagree. "Behavior" is what the program actually does.
>
> And if a program doesn't behave in the way required by the standard,
> the standard's statement about its behavior isn't incorrect, it's
> merely inapplicable; just about everything the standard says applies
> only to conforming implementations.
Let me try saying this a different way. When the Standard talks
about behavior, it is talking about how a program behaves (or
will behave) on the abstract machine. When people in general
talk about the behavior of a program (or especially a particular
program execution), "behavior" typically refers to how the
program will behave (or does behave) on a physical machine.
Behavior on the abstract machine could be undefined as far as
the Standard is concerned, but at the same time the behavior on
the physical machine could be well-defined by the implementation
(and in fact is in many cases).
It's important to distinguish between these two usages, because
they are talking about two different things. Related things,
perhaps, but still different things. Making a statement about
behavior in the first sense isn't the same as making that
statement about behavior in the second sense. And vice versa.
Not all the time. Also, the observable behaviour of the physical machine
has to be the same as the required observable behviour of the abstract
machine.
> When people in general
> talk about the behavior of a program (or especially a particular
> program execution), "behavior" typically refers to how the
> program will behave (or does behave) on a physical machine.
It depends. Sometimes people are talking about how the program is
required to behave, especially where the program will be run on multiple
different systems.
> Behavior on the abstract machine could be undefined as far as
> the Standard is concerned, but at the same time the behavior on
> the physical machine could be well-defined by the implementation
> (and in fact is in many cases).
Undefined behaviour in the C standard does not mean undefined on the
abstract machine, it means undefined by the C standard, which is not the
same thing.
> It's important to distinguish between these two usages, because
> they are talking about two different things. Related things,
> perhaps, but still different things. Making a statement about
> behavior in the first sense isn't the same as making that
> statement about behavior in the second sense. And vice versa.
I dom't think the difference is what you think it is. For example, the
behaviour might be defined by the Posix standard, and that certainly is
not a physical machine!
--
Flash Gordon
I don't think so; I think it's talking about the program's actual
behavior. The standard specifies a range of possible actual behaviors
that a program on a conforming implementation may exhibit. Even the
phrase "undefined behavior" implies that there *is* some behavior that
the standard doesn't define; this can only be the actual behavior on a
real system. Nasal demons are behavior.
> When people in general
> talk about the behavior of a program (or especially a particular
> program execution), "behavior" typically refers to how the
> program will behave (or does behave) on a physical machine.
> Behavior on the abstract machine could be undefined as far as
> the Standard is concerned, but at the same time the behavior on
> the physical machine could be well-defined by the implementation
> (and in fact is in many cases).
>
> It's important to distinguish between these two usages, because
> they are talking about two different things. Related things,
> perhaps, but still different things. Making a statement about
> behavior in the first sense isn't the same as making that
> statement about behavior in the second sense. And vice versa.
And in my opinion, the standard uses the word "behavior" in the second
sense, not the first.
I argued (possibly without enough thought!) that atoi()
was less undesirable than gets().
> > >> >> ...no. atoi() isn't as bad as gets() only because, making
> > >> >> more effort than you should need to, you _can_ stop atoi()
> > >> >> from having undefined behaviour using ISO C only. You cannot
> > >> >> do that with gets(). However, if you don't make that effort,
> > >> >> and pass atoi() a string it cannot handle, it will still have
> > >> >> behaviour that is equally as undefined as gets().
I suppose I was thinking that the "likely" undefined behaviour
was less draconian for atoi() than gets(). I never use gets() and
I rarely use atoi(). In future I will be using atoi() even less!
> > >> > What I think you mean is that the behavior /specification/ of
> > >> > atoi() in such cases is equally undefined as the behavior
> > >> > specification of gets() under analogous circumstances. It's
> > >> > likely that the /actual/ behavior of atoi() is much more
> > >> > well-defined than the behavior of gets() in such cases.
>
> > >> I don't think that's what he meant. As far as the standard is
> > >> concerned, undefined behavior is undefined behavior.
yes, but we tend to have a mental model of what we can
reasonably expect an implementation to do. Most atoi()s return
zero if you hand them rubbish (I was quite surprised to find this
wasn't what the standard said (I have code that relies on this...)).
I hadn't considered what overflow was likely to do. :-(
gets() on the other hand with the obvious implementation is just
going to stomp all over memory. And that can't possibly be good.
> > >> It's true
> > >> that atoi("99999999999999999999999999") is less likely to crash
> > >> your program or corrupt memory than gets(buf) while your cat is
> > >> sitting on the keyboard, but that's no excuse for being
> > >> careless.
>
> > > There's an ambiguity because the word "behavior" has a meaning
> > > in two different contexts, the context of the Standard, and the
> > > context of everyday life.
>
> > > In the Standard, "behavior" is a description of what a program
> > > /may/ do (ie, is allowed to do by the Standard).
I'm not sure I see the distinction between "Standard" behaviour and
"everyday" behaviour.
> > In Section 3.4, the C99 Standard defines the word "behavior" as
> > "external appearance or action".
ok
> > From what I can tell, your
> > description here better describes /well-defined/ behavior, rather
> > than just "behavior", even as defined by the Standard.
there's behaviour in what a program does and behaviour as in a range
of permitted actual behaviours some future execution of a program may
have. I suppose the standard is defining behaviour in the "future
imperfect" sense.
> > It seems to me, in both senses of the word, "behavior" describes
> > what a program is able to do, not what it is permitted to do.
I think the standard is constaining the possible behaviours of the
program.
> Consider a statement like "if XYZ, the behavior is undefined."
> This doesn't mean that what the program does is undefined;
I'd say that was exactly what it meant!
> it
> means what the program is allowed to do by the Standard is
> undefined.
sounds the same to me...
> Now consider a statement like, "if I give my program an input
> file of /dev/null, its bevahior is a little screwy." This
> doesn't mean the program is allowed to be a little screwy, it
> means what it actually does is a little screwy.
again it seems to me a distinction without a difference
> Another example: {unsigned u = 0; u = u+1; return u;} This
> program fragment has "well-defined" behavior. But if we run the
> program, and the memory for u gets hit by a cosmic ray, what the
> program actually does may be different from what the Standard
> requires it to do.
yes but the standard is reasoning about an abstract machine.
The abstract machine is immune to cosmic rays.
The standard is saying
"if, and only if, the implementation's actual external appearance or
action corresponds with the abstract machine's external appearance
or
action does this standard apply."
Possibly the actual machine's behviour has to be a subset
of the AM's set of behaviours.
> Its behavior(1) is defined by the Standard,
> but its behavior(2) is affected by cosmic rays (which are not
> part of the Standard). The terms behavior(1) and behavior(2)
> clearly can't mean the same thing.
>
> Do you see the difference I'm trying to illuminate?
>
> > I apologize if I'm midunderstanding you or the Standard.
>
> No problem. These ideas are difficult to communicate.
I'm beginning to see what you may mean. But if we start talking
about implmentations and real world hardware I think we might
be outside the standards domain of discourse.
--
Nick Keighley
"Programs must be written for people to read, and only
incidentally for machines to execute."
- Abelson & Sussman,
Structure and Interpretation of Computer Programs
> >>>>> In the Standard, "behavior" is a description of what a program
> >>>>> /may/ do (ie, is allowed to do by the Standard).
>
> >> I disagree. "Behavior" is what the program actually does.
ok, I'd nearly been pursuaded otherwise but now I'm back with you!
Behaviour is what a program does.
> >> And if a program doesn't behave in the way required by the standard,
> >> the standard's statement about its behavior isn't incorrect, it's
> >> merely inapplicable; just about everything the standard says applies
> >> only to conforming implementations.
>
> > Let me try saying this a different way. When the Standard talks
> > about behavior, it is talking about how a program behaves (or
> > will behave) on the abstract machine.
I agree
> Not all the time.
why not?
> Also, the observable behaviour of the physical machine
> has to be the same as the required observable behviour of the abstract
> machine.
yes
> > When people in general
> > talk about the behavior of a program (or especially a particular
> > program execution), "behavior" typically refers to how the
> > program will behave (or does behave) on a physical machine.
and that can lead to trouble (like believing atoi()'s UB is less
wicked than gets() UB...)
> It depends. Sometimes people are talking about how the program is
> required to behave, especially where the program will be run on multiple
> different systems.
and then you want to talk about AM behaviour
> > Behavior on the abstract machine could be undefined as far as
> > the Standard is concerned, but at the same time the behavior on
> > the physical machine could be well-defined by the implementation
> > (and in fact is in many cases).
yes. And sometimes we write programs where we rely on PM behaviour
> Undefined behaviour in the C standard does not mean undefined on the
> abstract machine,
I'd have said it does mean that!
> it means undefined by the C standard, which is not the
> same thing.
why not?
> > It's important to distinguish between these two usages, because
> > they are talking about two different things. Related things,
> > perhaps, but still different things. Making a statement about
> > behavior in the first sense isn't the same as making that
> > statement about behavior in the second sense. And vice versa.
>
> I dom't think the difference is what you think it is. For example, the
> behaviour might be defined by the Posix standard, and that certainly is
> not a physical machine!
Posix may be *an* abstract machine but it is not *the* abstract
machine. From the Standard's point of view Posix is just another
implementation machine.
--
Nick Keighley
You are in a clearing. You can see a spire in the distance.
You can also see a copy of "C Unleashed".
: INV
You have;
a DeathStation 900 laptop,
a voucher for a free pizza,
and a torch.
: TAKE BOOK
You can't. It's too heavy.
Bill Godfrey (clc)
> Tim Rentsch <t...@alumnus.caltech.edu> writes:
> > Keith Thompson <ks...@mib.org> writes:
> >> Tim Rentsch <t...@alumnus.caltech.edu> writes:
> >> > Curtis Dyer <dye...@gmail.com> writes:
> >> >> On 20 Jun 2009, Tim Rentsch <t...@alumnus.caltech.edu> wrote:
> >> [...]
> >> >> > In the Standard, "behavior" is a description of what a program
> >> >> > /may/ do (ie, is allowed to do by the Standard).
> >>
> >> I disagree. "Behavior" is what the program actually does.
> >>
> >> And if a program doesn't behave in the way required by the standard,
> >> the standard's statement about its behavior isn't incorrect, it's
> >> merely inapplicable; just about everything the standard says applies
> >> only to conforming implementations.
> >
> > Let me try saying this a different way. When the Standard talks
> > about behavior, it is talking about how a program behaves (or
> > will behave) on the abstract machine.
>
> I don't think so; I think it's talking about the program's actual
> behavior. The standard specifies a range of possible actual behaviors
> that a program on a conforming implementation may exhibit.
^^^
That's what I said! The standard uses the word behavior to talk
about what a program /may/ do. Not what it will do, but what it
may do.
> Even the
> phrase "undefined behavior" implies that there *is* some behavior that
> the standard doesn't define; this can only be the actual behavior on a
> real system. Nasal demons are behavior.
Furthermore, there is 5.1.2.3 p 1:
The semantic descriptions in this International Standard
describe the behavior of an abstract machine [...].
That's also what I said -- the Standard is talking about how
a program will behave on the abstract machine.
> > When people in general
> > talk about the behavior of a program (or especially a particular
> > program execution), "behavior" typically refers to how the
> > program will behave (or does behave) on a physical machine.
> > Behavior on the abstract machine could be undefined as far as
> > the Standard is concerned, but at the same time the behavior on
> > the physical machine could be well-defined by the implementation
> > (and in fact is in many cases).
> >
> > It's important to distinguish between these two usages, because
> > they are talking about two different things. Related things,
> > perhaps, but still different things. Making a statement about
> > behavior in the first sense isn't the same as making that
> > statement about behavior in the second sense. And vice versa.
>
> And in my opinion, the standard uses the word "behavior" in the second
> sense, not the first.
That view seems at odds with your earlier "may" statement,
and also with 5.1.2.3 p 1.
> Tim Rentsch wrote:
> > Keith Thompson <ks...@mib.org> writes:
> >
> >> Tim Rentsch <t...@alumnus.caltech.edu> writes:
> >>> Curtis Dyer <dye...@gmail.com> writes:
> >>>> On 20 Jun 2009, Tim Rentsch <t...@alumnus.caltech.edu> wrote:
> >> [...]
> >>>>> In the Standard, "behavior" is a description of what a program
> >>>>> /may/ do (ie, is allowed to do by the Standard).
> >> I disagree. "Behavior" is what the program actually does.
> >>
> >> And if a program doesn't behave in the way required by the standard,
> >> the standard's statement about its behavior isn't incorrect, it's
> >> merely inapplicable; just about everything the standard says applies
> >> only to conforming implementations.
> >
> > Let me try saying this a different way. When the Standard talks
> > about behavior, it is talking about how a program behaves (or
> > will behave) on the abstract machine.
>
> Not all the time.
Perhaps not in every single instance, but in most instances.
See also 5.1.2.3 p 1.
> Also, the observable behaviour of the physical machine
> has to be the same as the required observable behviour of the abstract
> machine.
That's nonsense, of course it doesn't. The Standard might
/specify/ that the behaviors must match, but that isn't
the same as saying they /do/ match when a program is
actually run. Statements in the Standard can't change
the laws of physics.
> > When people in general
> > talk about the behavior of a program (or especially a particular
> > program execution), "behavior" typically refers to how the
> > program will behave (or does behave) on a physical machine.
>
> It depends. Sometimes people are talking about how the program is
> required to behave, especially where the program will be run on multiple
> different systems.
Granted. I did say "typically", specifically to avoid
meaning "always".
> > Behavior on the abstract machine could be undefined as far as
> > the Standard is concerned, but at the same time the behavior on
> > the physical machine could be well-defined by the implementation
> > (and in fact is in many cases).
>
> Undefined behaviour in the C standard does not mean undefined on the
> abstract machine, it means undefined by the C standard, which is not the
> same thing.
How do you reconcile this statement with 5.1.2.3 p 1?
> > It's important to distinguish between these two usages, because
> > they are talking about two different things. Related things,
> > perhaps, but still different things. Making a statement about
> > behavior in the first sense isn't the same as making that
> > statement about behavior in the second sense. And vice versa.
>
> I dom't think the difference is what you think it is. For example, the
> behaviour might be defined by the Posix standard, and that certainly is
> not a physical machine!
First, you agree there's a difference, which is my main point.
Second, saying "the behavior" illustrates the problem -- the word
behavior means several different things, depending on the
(sometimes implied) context in which its used. The behavior /of
an actual program execution/ is defined by the object code in
question, the physical machine instruction set, and the laws of
physics (and the OS, the actual physical machine, etc). The
behavior /as specified by the ISO Standard/ can include undefined
behavior, unspecified behavior, etc -- but these won't make the
behavior of the actual program execution be any less defined.
The behavior /that is required to be Posix compliant/ is also not
(necessarily) the same as the behavior of the actual program
execution -- hopefully it is, but Posix (like ISO C) is a set of
specifications for how a program /may/ behave, not a guarantee
(or forecast, if you like) about how a program will /actually/
behave. Saying a compiler is ISO compliant or Posix compliant
may bring an /expectation/ of a particular behavior, but the
expectation might or might not match what happens when the
program is actually run.
What I think you mean is: "Stand aside, vile correctness peasant! Bother
me not with your erring on the side of caution. I shall cast all such to
the wind, for I am the Great Impervio, and I laugh in the face of
danger!" (Tell me, did I guess any more correctly than you?)
However, given the existence of strtol(), which is equivalent to atoi()
except where it is clearly superior, anyone who uses atoi() in new code
had better have a very good reason indeed if he doesn't want to be
called foolhardy.
Richard
> On 22 June, 17:01, Tim Rentsch <t...@alumnus.caltech.edu> wrote:
> > Curtis Dyer <dye...@gmail.com> writes:
> > > On 20 Jun 2009, Tim Rentsch <t...@alumnus.caltech.edu> wrote:
> > > > Keith Thompson <ks...@mib.org> writes:
> > > >> Tim Rentsch <t...@alumnus.caltech.edu> writes:
> > > >> > ralt...@xs4all.nl (Richard Bos) writes:
> > > >> >> Nick Keighley <nick_keighley_nos...@hotmail.com> wrote:
> > > >> >> > <bpascal...@googlemail.com> wrote:
[snip]
> > > > There's an ambiguity because the word "behavior" has a meaning
> > > > in two different contexts, the context of the Standard, and the
> > > > context of everyday life.
> >
> > > > In the Standard, "behavior" is a description of what a program
> > > > /may/ do (ie, is allowed to do by the Standard).
[snip]
> > > In Section 3.4, the C99 Standard defines the word "behavior" as
> > > "external appearance or action".
[snip]
> > > From what I can tell, your
> > > description here better describes /well-defined/ behavior, rather
> > > than just "behavior", even as defined by the Standard.
>
> there's behaviour in what a program does and behaviour as in a range
> of permitted actual behaviours some future execution of a program may
> have. I suppose the standard is defining behaviour in the "future
> imperfect" sense.
Right: actual behavior, and (specification of) permitted behavior(s),
and those are two different things.
> > > It seems to me, in both senses of the word, "behavior" describes
> > > what a program is able to do, not what it is permitted to do.
>
> I think the standard is constaining the possible behaviours of the
> program.
Yes, except the standard is constraining the possible /allowed/
behaviors; it is not constraining the set of behaviors that are
actually possible to occur.
> > Consider a statement like "if XYZ, the behavior is undefined."
> > This doesn't mean that what the program does is undefined;
>
> I'd say that was exactly what it meant!
>
> > it
> > means what the program is allowed to do by the Standard is
> > undefined.
>
> sounds the same to me...
>
> > Now consider a statement like, "if I give my program an input
> > file of /dev/null, its bevahior is a little screwy." This
> > doesn't mean the program is allowed to be a little screwy, it
> > means what it actually does is a little screwy.
>
> again it seems to me a distinction without a difference
>
> > Another example: {unsigned u = 0; u = u+1; return u;} This
> > program fragment has "well-defined" behavior. But if we run the
> > program, and the memory for u gets hit by a cosmic ray, what the
> > program actually does may be different from what the Standard
> > requires it to do.
>
> yes but the standard is reasoning about an abstract machine.
> The abstract machine is immune to cosmic rays.
Yes, the Standard is describes behavior as it occurs (or would
occur) on the abstract machine. That behavior is not guaranteed
to match the behavior that actually occurs when the program is
run on a particular physical computer. The distinction is
relevant precisely because they are not guaranteed to be same,
and indeed are often different.
> The standard is saying
> "if, and only if, the implementation's actual external appearance or
> action corresponds with the abstract machine's external appearance
> or action does this standard apply."
Not quite. As the Standard uses the term, an implementation is a
piece of software. Actually running a program requires, besides
an implementation, a "data-processing system", ie, a computer
(and OS, presumably). The distinction is evident in 1 p 2:
This International Standard does not specify [...] all minimal
requirements of a data-processing system that is capable of
supporting a conforming implementation.
> Possibly the actual machine's behviour has to be a subset
> of the AM's set of behaviours.
If the actual machine (and OS, etc) behaves as it's supposed to,
and the implementation is conforming, then the actual program
execution /will/ behave in a way that's consistent with the ISO C
specified behavior. But an implementation can be conforming
without making any absolute guarantees about what will happen
when a program is actually run -- which is lucky, because no
absolute guarantees are possible (well, at least not non-trivial
ones), so if they were required, no implementation could be
conforming.
> > Its behavior(1) is defined by the Standard,
> > but its behavior(2) is affected by cosmic rays (which are not
> > part of the Standard). The terms behavior(1) and behavior(2)
> > clearly can't mean the same thing.
> >
> > Do you see the difference I'm trying to illuminate?
> >
> > > I apologize if I'm midunderstanding you or the Standard.
> >
> > No problem. These ideas are difficult to communicate.
>
> I'm beginning to see what you may mean. But if we start talking
> about implmentations and real world hardware I think we might
> be outside the standards domain of discourse.
I'm okay with talking about both, and in fact I think both are
relevant (in some contexts) here in the newsgroup; I just want
it to be clear which notion is under discussion so one is not
mistaken for the other.
> Tim Rentsch <t...@alumnus.caltech.edu> wrote:
>
> > ral...@xs4all.nl (Richard Bos) writes:
> > > Nick Keighley <nick_keigh...@hotmail.com> wrote:
> > >
> > > > atoi() isn't as bad as gets().
> > >
> > > Yes, but...
> > >
> > > > atoi() only gives you the wrong answer,
> > >
> > > ...no. atoi() isn't as bad as gets() only because, making more effort
> > > than you should need to, you _can_ stop atoi() from having undefined
> > > behaviour using ISO C only. You cannot do that with gets(). However, if
> > > you don't make that effort, and pass atoi() a string it cannot handle,
> > > it will still have behaviour that is equally as undefined as gets().
> >
> > What I think you mean is that the behavior /specification/ of atoi()
> > in such cases is equally undefined as the behavior specification of
> > gets() under analogous circumstances. It's likely that the /actual/
> > behavior of atoi() is much more well-defined than the behavior of
> > gets() in such cases.
>
> What I think you mean is: "Stand aside, vile correctness peasant! Bother
> me not with your erring on the side of caution. I shall cast all such to
> the wind, for I am the Great Impervio, and I laugh in the face of
> danger!"
What I was trying to do (and what I intended to mean) is to point
out that "behavior" is used in two distinct senses, and that your
earlier comment is correct in one of those senses but not in the
other. I wasn't intending to make any comment one way or the
other on the advisability or inadvisability of using atoi() (as
compared to using strtol(), for example).
> (Tell me, did I guess any more correctly than you?)
I believe I understood the point you were making. Do you think
you understood the point I was making?
> However, given the existence of strtol(), which is equivalent to atoi()
> except where it is clearly superior, anyone who uses atoi() in new code
> had better have a very good reason indeed if he doesn't want to be
> called foolhardy.
Nolo contendere. However that question is orthogonal to the
point I was trying to make.
Well, it is defining behaviour in terms of what the abstract machine is
required (or sometimes permitted) to do, and that need not always be the
same as the physical machine ;-)
>>>> And if a program doesn't behave in the way required by the standard,
>>>> the standard's statement about its behavior isn't incorrect, it's
>>>> merely inapplicable; just about everything the standard says applies
>>>> only to conforming implementations.
>>> Let me try saying this a different way. When the Standard talks
>>> about behavior, it is talking about how a program behaves (or
>>> will behave) on the abstract machine.
>
> I agree
So do I now.
>> Not all the time.
>
> why not?
Lets start with volatile, which lays constraints on the relationship
between the actual implementation and the abstract machine, and then at
program termination all files have to be in the correct state, and
dynamics of interactive devices have to be as specified...
Actually, on looking more carefully I can't immediately see anything
else, and the paragraphs I'm refering to don't use the word "behavior"!
OK, so I'll accept that when the standard refers to behaviour it is
specifically the behaviour of the abstract machine.
>> Also, the observable behaviour of the physical machine
>> has to be the same as the required observable behviour of the abstract
>> machine.
>
> yes
Actually, on looking, only specific items of observable behaviour need
to match!
>>> When people in general
>>> talk about the behavior of a program (or especially a particular
>>> program execution), "behavior" typically refers to how the
>>> program will behave (or does behave) on a physical machine.
>
> and that can lead to trouble (like believing atoi()'s UB is less
> wicked than gets() UB...)
Yes.
Of course other Undefined Behaviour is not always as wicked as gets(),
since sometimes it si behaviour documented by something other than the
standard and something that is required.
>> It depends. Sometimes people are talking about how the program is
>> required to behave, especially where the program will be run on multiple
>> different systems.
>
> and then you want to talk about AM behaviour
Well, I tend to just talk about behaviour myself ;-)
>>> Behavior on the abstract machine could be undefined as far as
>>> the Standard is concerned, but at the same time the behavior on
>>> the physical machine could be well-defined by the implementation
>>> (and in fact is in many cases).
>
> yes. And sometimes we write programs where we rely on PM behaviour
Indeed.
>> Undefined behaviour in the C standard does not mean undefined on the
>> abstract machine,
>
> I'd have said it does mean that!
>
>> it means undefined by the C standard, which is not the
>> same thing.
>
> why not?
Because the standard explicitly allows other things to define it! So it
is behaviour which *might* be defined, or might not be, just not defined
by the C standard.
>>> It's important to distinguish between these two usages, because
>>> they are talking about two different things. Related things,
>>> perhaps, but still different things. Making a statement about
>>> behavior in the first sense isn't the same as making that
>>> statement about behavior in the second sense. And vice versa.
>> I dom't think the difference is what you think it is. For example, the
>> behaviour might be defined by the Posix standard, and that certainly is
>> not a physical machine!
>
> Posix may be *an* abstract machine but it is not *the* abstract
> machine. From the Standard's point of view Posix is just another
> implementation machine.
Allowing as undefined behaviour (where the standard is explicitly
defining behaviour of the abstract machine), "...behaving during
translation or program execution in a documented manner characteristic
of the environment..." seems to me to allow the Posix standard to define
behaviour of The Abstract Machine where the C standard leave it undefined.
--
Flash Gordon
See other post. I accept this.
>> Also, the observable behaviour of the physical machine
>> has to be the same as the required observable behviour of the abstract
>> machine.
>
> That's nonsense, of course it doesn't. The Standard might
> /specify/ that the behaviors must match, but that isn't
> the same as saying they /do/ match when a program is
> actually run. Statements in the Standard can't change
> the laws of physics.
None of the standard requirements, as far as I'm aware, ever require
violating the laws of physics. In any case, when an implementation does
not meet the requirements placed on it by the standard that means it
does not conform, and so what the standard says is irrelevant in any case.
>>> When people in general
>>> talk about the behavior of a program (or especially a particular
>>> program execution), "behavior" typically refers to how the
>>> program will behave (or does behave) on a physical machine.
>> It depends. Sometimes people are talking about how the program is
>> required to behave, especially where the program will be run on multiple
>> different systems.
>
> Granted. I did say "typically", specifically to avoid
> meaning "always".
Generally people don't even realise there is a standard :-(
>>> Behavior on the abstract machine could be undefined as far as
>>> the Standard is concerned, but at the same time the behavior on
>>> the physical machine could be well-defined by the implementation
>>> (and in fact is in many cases).
>> Undefined behaviour in the C standard does not mean undefined on the
>> abstract machine, it means undefined by the C standard, which is not the
>> same thing.
>
> How do you reconcile this statement with 5.1.2.3 p 1?
That is talking about behaviour it defines, not behaviour it doesn't
define! Undefined behaviour in the C standard is explicitly allowed to
be defined by something else, and that something else does not have to
be defining the physical machine! See 3.4.3 p2, specifically "..behaving
during translation or program execution in a documented manner
characteristic of the environment..."
>>> It's important to distinguish between these two usages, because
>>> they are talking about two different things. Related things,
>>> perhaps, but still different things. Making a statement about
>>> behavior in the first sense isn't the same as making that
>>> statement about behavior in the second sense. And vice versa.
>> I dom't think the difference is what you think it is. For example, the
>> behaviour might be defined by the Posix standard, and that certainly is
>> not a physical machine!
>
> First, you agree there's a difference, which is my main point.
>
> Second, saying "the behavior" illustrates the problem -- the word
> behavior means several different things, depending on the
> (sometimes implied) context in which its used.
Yes, and the C standard defines which meaning it is using, which is not
quite what I have first though, but there you go.
> The behavior /of
> an actual program execution/ is defined by the object code in
> question, the physical machine instruction set, and the laws of
> physics (and the OS, the actual physical machine, etc).
Yes.
> The
> behavior /as specified by the ISO Standard/ can include undefined
> behavior, unspecified behavior, etc -- but these won't make the
> behavior of the actual program execution be any less defined.
Yes and no. Some of that undefined behaviour might lead to an illegal
opcode sequence which the processor manufacturer has not bothered to
deal with and for which the actual choice of between two options might
depend on truly random (at the quantum level) factors, or possibly
slightly less random factors such as slight variations in voltage. I
have in the past come across opcodes where the manufacturer did not
define what would happen.
> The behavior /that is required to be Posix compliant/ is also not
> (necessarily) the same as the behavior of the actual program
> execution -- hopefully it is, but Posix (like ISO C) is a set of
> specifications for how a program /may/ behave, not a guarantee
> (or forecast, if you like) about how a program will /actually/
> behave. Saying a compiler is ISO compliant or Posix compliant
> may bring an /expectation/ of a particular behavior, but the
> expectation might or might not match what happens when the
> program is actually run.
Actually, the statement that some implementation conforms to standards
X, Y and Z *is* a guarantee that it will behave in the way specified by
those standards (given that all of the program is defined by one
standard or another). Of course, some times things don't live up to
their guarantees, but in that case it is not compliant.
--
Flash Gordon
> Tim Rentsch wrote:
> > Flash Gordon <sm...@spam.causeway.com> writes:
> >
> >> Tim Rentsch wrote:
[snip]
> >> Also, the observable behaviour of the physical machine
> >> has to be the same as the required observable behviour of the abstract
> >> machine.
> >
> > That's nonsense, of course it doesn't. The Standard might
> > /specify/ that the behaviors must match, but that isn't
> > the same as saying they /do/ match when a program is
> > actually run. Statements in the Standard can't change
> > the laws of physics.
>
> None of the standard requirements, as far as I'm aware, ever require
> violating the laws of physics.
Providing an absolute guarantee that an actual program execution be
consistent with the semantic description of ISO C cannot be done under
the laws of physics (at least not at we currently understand them).
If you agree that the Standard does not expect any such absolute
guarantee, then we are in agreement; if not, I'd be curious to hear
which passages in the Standard you think imply such an expectation.
> In any case, when an implementation does
> not meet the requirements placed on it by the standard that means it
> does not conform, and so what the standard says is irrelevant in any case.
An implementation (of ISO C) is a piece of software. What it means to
meet the Standard's requirements is to say that the implementation
would behave suitably /if/ run on an appropriate data-processing
system. The Standard specifically does not address what such a
data-processing system (ie, computer/OS) might be -- 1 p 2 says:
This International Standard does not specify [...] all minimal
requirements of a data-processing system that is capable of
supporting a conforming implementation.
So saying an implementation is conforming doesn't mean an actual
program execution will behave in accordance with the Standard.
>[snip]
> >>> Behavior on the abstract machine could be undefined as far as
> >>> the Standard is concerned, but at the same time the behavior on
> >>> the physical machine could be well-defined by the implementation
> >>> (and in fact is in many cases).
> >> Undefined behaviour in the C standard does not mean undefined on the
> >> abstract machine, it means undefined by the C standard, which is not the
> >> same thing.
> >
> > How do you reconcile this statement with 5.1.2.3 p 1?
>
> That is talking about behaviour it defines, not behaviour it doesn't
> define!
The referenced paragraph says:
The semantic descriptions in this International Standard
describe the behavior of an abstract machine in which issues of
optimization are irrelevant.
I don't see anything here that excludes this statement from applying
to statements about implementation-defined behavior, locale-specific
behavior, unspecified behavior, or undefined behavior. What makes
you say it applies to some aspects of semantic descriptions but
not others?
> Undefined behaviour in the C standard is explicitly allowed to
> be defined by something else, and that something else does not have to
> be defining the physical machine! See 3.4.3 p2, specifically "..behaving
> during translation or program execution in a documented manner
> characteristic of the environment..."
Yes, that's the point of what I was saying -- when the Standard
says "undefined behavior", it means "behavior" in the sense of
what the Standard requires; it does not mean that some other
agency can't define (or place requirements on) some other sense
of the word behavior.
>[snip]
> > The behavior /of
> > an actual program execution/ is defined by the object code in
> > question, the physical machine instruction set, and the laws of
> > physics (and the OS, the actual physical machine, etc).
>
> Yes.
>
> > The
> > behavior /as specified by the ISO Standard/ can include undefined
> > behavior, unspecified behavior, etc -- but these won't make the
> > behavior of the actual program execution be any less defined.
>
> Yes and no. Some of that undefined behaviour might lead to an illegal
> opcode sequence which the processor manufacturer has not bothered to
> deal with and for which the actual choice of between two options might
> depend on truly random (at the quantum level) factors, or possibly
> slightly less random factors such as slight variations in voltage. I
> have in the past come across opcodes where the manufacturer did not
> define what would happen.
Behavior on the physical machine is still defined, by the instruction
set architecture, by how the architecture is implemented, by how the
implementation is realized in the manufactured components in the
particular machine in question, and ultimately by the laws of physics.
The definition may not be deterministic or especially useful, but the
behavior is still defined. For example, a program execution cannot
cause energy to be created.
> > The behavior /that is required to be Posix compliant/ is also not
> > (necessarily) the same as the behavior of the actual program
> > execution -- hopefully it is, but Posix (like ISO C) is a set of
> > specifications for how a program /may/ behave, not a guarantee
> > (or forecast, if you like) about how a program will /actually/
> > behave. Saying a compiler is ISO compliant or Posix compliant
> > may bring an /expectation/ of a particular behavior, but the
> > expectation might or might not match what happens when the
> > program is actually run.
>
> Actually, the statement that some implementation conforms to standards
> X, Y and Z *is* a guarantee that it will behave in the way specified by
> those standards (given that all of the program is defined by one
> standard or another). Of course, some times things don't live up to
> their guarantees, but in that case it is not compliant.
Perhaps there are other such standards, but ISO C is not one
of them. An implementation can be conforming without providing
any guarantee of what will happen during an actual program run.
See the comments above.
I'd be curious to hear which laws of physics must necessarily be
violated by a conforming C program.
>> In any case, when an implementation does
>> not meet the requirements placed on it by the standard that means it
>> does not conform, and so what the standard says is irrelevant in any case.
>
> An implementation (of ISO C) is a piece of software. What it means to
> meet the Standard's requirements is to say that the implementation
> would behave suitably /if/ run on an appropriate data-processing
> system. The Standard specifically does not address what such a
> data-processing system (ie, computer/OS) might be -- 1 p 2 says:
>
> This International Standard does not specify [...] all minimal
> requirements of a data-processing system that is capable of
> supporting a conforming implementation.
>
> So saying an implementation is conforming doesn't mean an actual
> program execution will behave in accordance with the Standard.
Yes it does. If an actual program execution does not behave in
accordance with the Standard, then the implementation (on that
particular system) is non-conforming. (And if, as you seem to imply,
full conformance is physically impossible, then there are no
conforming implementations in the real world.)
In practice, of course, issues like "This strictly conforming program
doesn't execute properly if the power is turned off" aren't blamed on
the implementation.
If I have a copy of an implementation that would be conforming on some
particular system, but I don't have that system (or an emulation of
it), then I don't really have a conforming implementation.
[snip]
>> Actually, the statement that some implementation conforms to standards
>> X, Y and Z *is* a guarantee that it will behave in the way specified by
>> those standards (given that all of the program is defined by one
>> standard or another). Of course, some times things don't live up to
>> their guarantees, but in that case it is not compliant.
>
> Perhaps there are other such standards, but ISO C is not one
> of them. An implementation can be conforming without providing
> any guarantee of what will happen during an actual program run.
> See the comments above.
The way I think of it is that the standard doesn't make guarantees; it
only imposes restrictions. The only penalty for violating one if its
restrictions is that the implementation or the program is
non-conforming.
> >> >> Also, the observable behaviour of the physical machine
> >> >> has to be the same as the required observable behviour of the abstract
> >> >> machine.
>
> >> > That's nonsense, of course it doesn't. The Standard might
> >> > /specify/ that the behaviors must match, but that isn't
> >> > the same as saying they /do/ match when a program is
> >> > actually run. Statements in the Standard can't change
> >> > the laws of physics.
>
> >> None of the standard requirements, as far as I'm aware, ever require
> >> violating the laws of physics.
>
> > Providing an absolute guarantee that an actual program execution be
> > consistent with the semantic description of ISO C cannot be done under
> > the laws of physics (at least not at we currently understand them).
> > If you agree that the Standard does not expect any such absolute
> > guarantee, then we are in agreement; if not, I'd be curious to hear
> > which passages in the Standard you think imply such an expectation.
>
> I'd be curious to hear which laws of physics must necessarily be
> violated by a conforming C program.
[I've *gotta* give this a shot]
Isn't the very concept of a deterministic computation fly in the face
of modern quantum mechanics?
<snip>
No. From the principles of quantum mechanics, you can derive the fact
that determinism is a VERY accurate approximation to reality at the
macroscopic level. It requires very special experimental set-ups to
detect the indeterminate nature of the underlying fundamental reality.
It's so difficult to detect that there are still people working on
coming up with a way to explain those experimental results
deterministically. Therefore, computers which support C's deterministic
computation model are not in conflict with the laws of physics.
On the flip side of this argument, the smaller and faster that computer
components get, the harder it is to get them to behave reliably, because
of quantum uncertainty.
ah well, I didn't think I'd get that to fly but I felt
I had to try
Oh, that isn't quite what I said. I said no absolute guarantees
can be made that actual program execution matches expectations
(or requirements, if you will). To give one example, the
probability is nonzero that the computer will spontaneously
tunnel through a wall and into an electrical outlet.
> >> In any case, when an implementation does
> >> not meet the requirements placed on it by the standard that means it
> >> does not conform, and so what the standard says is irrelevant in any case.
> >
> > An implementation (of ISO C) is a piece of software. What it means to
> > meet the Standard's requirements is to say that the implementation
> > would behave suitably /if/ run on an appropriate data-processing
> > system. The Standard specifically does not address what such a
> > data-processing system (ie, computer/OS) might be -- 1 p 2 says:
> >
> > This International Standard does not specify [...] all minimal
> > requirements of a data-processing system that is capable of
> > supporting a conforming implementation.
> >
> > So saying an implementation is conforming doesn't mean an actual
> > program execution will behave in accordance with the Standard.
>
> Yes it does. If an actual program execution does not behave in
> accordance with the Standard, then the implementation (on that
> particular system) is non-conforming. [snip]
I think you're confusing two different things here, the
implementation and the physical computer it runs on. The
Standard covers only the implementation, not the physical
computer it runs on (ie, "a data-processing system that is
capable of supporting a conforming implementation"). Since the
Standard says this explicitly, and distinguishes them explicitly,
it imposes requirements only on the implementation, not on the
physical machine or on any actual program execution.
> In practice, of course, issues like "This strictly conforming program
> doesn't execute properly if the power is turned off" aren't blamed on
> the implementation.
>
> If I have a copy of an implementation that would be conforming on some
> particular system, but I don't have that system (or an emulation of
> it), then I don't really have a conforming implementation.
Not in the language of the Standard. By its description, you
would have a conforming implementation, but not a data-processing
system capable of supporting that conforming implementation. The
sentence in 1p2 clearly shows that the notion of a conforming
implementation exists independently of the system it runs on.
> >> Actually, the statement that some implementation conforms to standards
> >> X, Y and Z *is* a guarantee that it will behave in the way specified by
> >> those standards (given that all of the program is defined by one
> >> standard or another). Of course, some times things don't live up to
> >> their guarantees, but in that case it is not compliant.
> >
> > Perhaps there are other such standards, but ISO C is not one
> > of them. An implementation can be conforming without providing
> > any guarantee of what will happen during an actual program run.
> > See the comments above.
>
> The way I think of it is that the standard doesn't make guarantees; it
> only imposes restrictions. The only penalty for violating one if its
> restrictions is that the implementation or the program is
> non-conforming.
Please note that my comment about (not) providing any guarantee
is about an implementation, not about the Standard. The Standard
doesn't require that an implementation make an absolute guarantee
to be conforming, only a relative guarantee -- namely, /if/ the
implemention is run in a suitable environment, /then/ it will
behave according to the Standard's requirements. If this relative
guarantee is met, the implementation is conforming, regardless
of whether we have the supporting hardware environment or not.
> On 25 June, 19:23, Keith Thompson <ks...@mib.org> wrote:
> > Tim Rentsch <t...@alumnus.caltech.edu> writes:
> > > Flash Gordon <s...@spam.causeway.com> writes:
> > >> Tim Rentsch wrote:
> > >> > Flash Gordon <s...@spam.causeway.com> writes:
> > >> >> Tim Rentsch wrote:
>
> > >> >> Also, the observable behaviour of the physical machine
> > >> >> has to be the same as the required observable behviour of the abstr=
> act
> > >> >> machine.
> >
> > >> > That's nonsense, of course it doesn't. =A0The Standard might
> > >> > /specify/ that the behaviors must match, but that isn't
> > >> > the same as saying they /do/ match when a program is
> > >> > actually run. =A0Statements in the Standard can't change
> > >> > the laws of physics.
> >
> > >> None of the standard requirements, as far as I'm aware, ever require
> > >> violating the laws of physics.
> >
> > > Providing an absolute guarantee that an actual program execution be
> > > consistent with the semantic description of ISO C cannot be done under
> > > the laws of physics (at least not at we currently understand them).
> > > If you agree that the Standard does not expect any such absolute
> > > guarantee, then we are in agreement; =A0if not, I'd be curious to hear
> > > which passages in the Standard you think imply such an expectation.
> >
> > I'd be curious to hear which laws of physics must necessarily be
> > violated by a conforming C program.
>
> [I've *gotta* give this a shot]
>
> Isn't the very concept of a deterministic computation fly in the face
> of modern quantum mechanics?
Basically yes. We can't eliminate the possibility
(admittedly a small probability, but still finitely
large) that a quantum mechanical catastrophe will
occur, such as all the electrons in one register
flip-flop tunnelling over to another one, wrecking
the execution state.
> Nick Keighley wrote:
> > On 25 June, 19:23, Keith Thompson <ks...@mib.org> wrote:
> ...
> >> I'd be curious to hear which laws of physics must necessarily be
> >> violated by a conforming C program.
> >
> > [I've *gotta* give this a shot]
> >
> > Isn't the very concept of a deterministic computation fly in the face
> > of modern quantum mechanics?
>
> No. From the principles of quantum mechanics, you can derive the fact
> that determinism is a VERY accurate approximation to reality at the
> macroscopic level. It requires very special experimental set-ups to
> detect the indeterminate nature of the underlying fundamental reality.
> It's so difficult to detect that there are still people working on
> coming up with a way to explain those experimental results
> deterministically. Therefore, computers which support C's deterministic
> computation model are not in conflict with the laws of physics.
It depends on whether one is asking about a relative guarantee or
an absolute guarantee. On a relative scale, the probability of a
failure can be made pretty small (perhaps not as small as to be
arbitrarily small, but pretty doggone small!). On an absolute
scale, the probability of failure can never be reduced to zero.
Relative guarantees can be made; absolute guarantees cannot.
Your original statement was right. James was trying
a little conversational sleight-of-hand to change
the topic from absolute determinism to approximate
determinism. But for /deterministic/ computation,
as opposed to approximately deterministic computation,
your statement is right.
Then you didn't get my point, which is that it doesn't do to rely on
undefined behaviour when there is a perfectly defined alternative
available, _regardless_ of the likely pernicious results of the
undefined behaviour in any particular case. Where there is a better
alternative readily at hand, the difference between theoretically
allowed undefined behaviour and practically occurring undefined
behaviour is irrelevant.
In other words, it may in theory well be that atoi() is less likely to
have damaging undefined behaviour than gets(); but in practice, anyone
who even spends time pondering that likelihood instead of immediately
going for strtol() is a fool.
Richard
No, I got your point, I just had something else to say
about it.
> In other words, it may in theory well be that atoi() is less likely to
> have damaging undefined behaviour than gets(); but in practice, anyone
> who even spends time pondering that likelihood instead of immediately
> going for strtol() is a fool.
Perhaps so. But someone who doesn't distinguish between actual
behavior and Standard-specified behavior is a bigger fool.
I certainly do distinguish between actual behavior and
Standard-specified behavior. This does not lead me to conclude
that atoi() is appropriate in anything other than toy programs or
situations where the argument is tightly controlled (and in the
latter case, it's generally not worth the effort).
What is the actual behavior of atoi("99999999999999999999999999")?
How do you know? Are you sure it will remain the same on any
implementation your code is ever used with?
> Tim Rentsch <t...@alumnus.caltech.edu> writes:
> > ral...@xs4all.nl (Richard Bos) writes:
> [...]
> >> In other words, it may in theory well be that atoi() is less likely to
> >> have damaging undefined behaviour than gets(); but in practice, anyone
> >> who even spends time pondering that likelihood instead of immediately
> >> going for strtol() is a fool.
> >
> > Perhaps so. But someone who doesn't distinguish between actual
> > behavior and Standard-specified behavior is a bigger fool.
>
> I certainly do distinguish between actual behavior and
> Standard-specified behavior. This does not lead me to conclude
> that atoi() is appropriate in anything other than toy programs or
> situations where the argument is tightly controlled (and in the
> latter case, it's generally not worth the effort).
My intention was to make a generic comment without offering any
judgment on the specific case (ie, atoi()).
> What is the actual behavior of atoi("99999999999999999999999999")?
> How do you know? Are you sure it will remain the same on any
> implementation your code is ever used with?
Of course, the answers here are that I don't know for sure. My
point is that there are some situations where questions like
these are relevant, and other situations where they aren't so
relevant. I understand the black/white perspective of defined
versus undefined behavior, but that perspective isn't always the
most appropriate one; it's important to remember that and try to
take a perspective that's appropriate to the particular situation
under consideration. This may not be a deep thought, but it does
seem to bear repeating from time to time.
Under what circumstances, in your opinion, is it acceptable to use
atoi(), with its risk of undefined behavior, rather than strtol(),
which with a little care can be used safely?
<snip>
> Under what circumstances, in your opinion, is it acceptable to use
> atoi(), with its risk of undefined behavior, rather than strtol(),
> which with a little care can be used safely?
Obfuscated code is one obvious candidate, because atoi is two
characters terser, and has only one arg.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Forged article? See
http://www.cpax.org.uk/prg/usenet/comp.lang.c/msgauth.php
"Usenet is a strange place" - dmr 29 July 1999
OK, under what _legitimate_ circumstances, then? ;)
> Under what circumstances, in your opinion, is it acceptable to use
> atoi(), with its risk of undefined behavior, rather than strtol(),
> which with a little care can be used safely?
Quite seriously: when you just don't care very much. That is, in
trivial experimental programs, for one.
--
Ben Pfaff
http://benpfaff.org
Or when success is highly assured (e.g. your inputs will be the numbers
"0" through "63".)
I kinda feel the same way about it as I do "goto". Generally it's not
the best solution, but there are certain cases where it's fine (any
maybe even preferable) to use.
-Beej
> Tim Rentsch <t...@alumnus.caltech.edu> writes:
> > ral...@xs4all.nl (Richard Bos) writes:
> [...]
> >> In other words, it may in theory well be that atoi() is less likely to
> >> have damaging undefined behaviour than gets(); but in practice, anyone
> >> who even spends time pondering that likelihood instead of immediately
> >> going for strtol() is a fool.
> >
> > Perhaps so. But someone who doesn't distinguish between actual
> > behavior and Standard-specified behavior is a bigger fool.
Not so. Knowing is one thing; caring is another. In this case,
_especially_ those who know the difference should also know that they
should not care about it.
> I certainly do distinguish between actual behavior and
> Standard-specified behavior. This does not lead me to conclude
> that atoi() is appropriate in anything other than toy programs or
> situations where the argument is tightly controlled (and in the
> latter case, it's generally not worth the effort).
>
> What is the actual behavior of atoi("99999999999999999999999999")?
> How do you know? Are you sure it will remain the same on any
> implementation your code is ever used with?
I insist, and will continue to insist, that the onnly important question
is: why the tanj do you _care_ what it is, when you should have been
using strtol() instead?
Richard