Re: [SLUG] C Gurus
O Plameras was once rumoured to have said: This is a different code. I'd do it differently. But for another time. So would I. If I was trying to implement the original arrangement properly, I'd probably do it something like this... ---BEGIN--- #include stdio.h #include stdlib.h #include string.h #include getopt.h #include libintl.h #define _(x) gettext(x) #define VERSION 0.1 void somefunction(char *strout, int n) { strncpy(strout, _(some words), n); strout[n-1]='\0'; } void usage(int argc, char *argv[]) { fprintf(stderr,_(%s: do stuff\n\n), argv[0]); fprintf(stderr,_(usage:\n %s [flags]\n\n), argv[0]); fprintf(stderr,_(valid flags:\n)); fprintf(stderr,_( -h, --help display this message\n)); fprintf(stderr,_( -v, --version display the version number\n)); exit(1); } void version(int argc, char *argv[]) { fprintf(stderr, _(%s: version %s\n), argv[0], VERSION); exit(1); } static struct option opts[] = { {help, no_argument, NULL, 'h'}, {version, no_argument, NULL, 'v'}, {NULL, 0, NULL, 0} }; #ifndef BUF #define BUF 256 #endif int main (int argc, char *argv[]) { charstring[BUF]; int c; while (-1 != (c = getopt_long(argc, argv, hv, opts, NULL))) { switch (c) { case 'v': version (argc, argv); break; case 'h': usage (argc, argv); break; default: break; } } somefunction(string, BUF); printf (_(\n\nString is: %s\n\n), string); return 0; } ---END--- Thus keeping the i18n and GNU people happy too! C. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Crossfire wrote: So would I. If I was trying to implement the original arrangement properly, I'd probably do it something like this... ---BEGIN--- #include stdio.h #include stdlib.h #include string.h #include getopt.h #include libintl.h #define _(x) gettext(x) #define VERSION 0.1 void somefunction(char *strout, int n) { strncpy(strout, _(some words), n); strout[n-1]='\0'; } void usage(int argc, char *argv[]) { fprintf(stderr,_(%s: do stuff\n\n), argv[0]); fprintf(stderr,_(usage:\n %s [flags]\n\n), argv[0]); fprintf(stderr,_(valid flags:\n)); fprintf(stderr,_( -h, --help display this message\n)); fprintf(stderr,_( -v, --version display the version number\n)); exit(1); } void version(int argc, char *argv[]) { fprintf(stderr, _(%s: version %s\n), argv[0], VERSION); exit(1); } static struct option opts[] = { {help, no_argument, NULL, 'h'}, {version, no_argument, NULL, 'v'}, {NULL, 0, NULL, 0} }; #ifndef BUF #define BUF 256 #endif int main (int argc, char *argv[]) { charstring[BUF]; int c; while (-1 != (c = getopt_long(argc, argv, hv, opts, NULL))) { switch (c) { case 'v': version (argc, argv); break; case 'h': usage (argc, argv); break; default: break; } } somefunction(string, BUF); printf (_(\n\nString is: %s\n\n), string); return 0; } ---END--- Thus keeping the i18n and GNU people happy too! I'd cut the crap off to demonstrate the idea and get, #include stdio.h #include stdlib.h #include string.h void somefunction(char *strout) { char *string2 = some words; strcpy(strout, string2); } int main (void) { char *string1; string1 = malloc(11); somefunction(string1); printf (\n\nString is: %s\n\n,string1); return 0; } And compare to, #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string2 = some words; return string2; } int main (void) { printf (\n\nString is: %s\n\n, somefunction()); return 0; } -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Three free C books on offer (was Re: [SLUG] C Gurus)
O Plameras wrote: Erik de Castro Lopo wrote: If you come to the SLUG meeting on Friday, I will bring you a copy of this book so you can see for yourself. If you then publically admit that you were wrong on this issue you can keep the book [1]. It's nice of you to make that offer. Unfortunately, I can't come, physically but can be reached by email. Besides, your book will just gather dust. I suggest you gave it to SLUG enthusiasts who are keen to learn C. I'll make this offer, though. For every SLUG enthusiasts to whom you will give a book for free that can satisfy me that they learned from your book What about Hal Ashburner? He has told me that he found my book useful. Does he count? and say it's not a waste of their time, I'll offer to pay you half the bookshop's retail price . This offer is good for up to 25 enthusiasts. I'd be happy to take you up on this offer. Unfortunately I only have three remaining spare copies. So, the first three people who can attend Friday's SLUG meeting and are interested in this should email me privately (and CC Oscar) with the title of the book. - If one of the first three people don't show up at SLUG the book will go to the next person on the list. - If we don't get three people who sent email the books will go to people who are there on the night. Anyone interested can also inspect pages 39 to 42 for themselves. Erik -- +---+ Erik de Castro Lopo +---+ Being really good at C++ is like being really good at using rocks to sharpen sticks. -- Thant Tessman -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: Three free C books on offer (was Re: [SLUG] C Gurus)
Russell Davie qualifies. Give him 21 days and we'll see how he goes. I'll email him to see how he goes after 21 days. And so 24 more books to go. To Russell: Congratulations you have reasonable case to receive this offer with the brief you have provided. Please provide a photo of the Back Cover of the book, the one with the ISBN Number (and a photo of the page that has the price tag if there is) and email it to me. Can you provide me also with a short resume or bio-data with your qualification, age, training, current employer, and contact address apart from your email. To Erik: Please provide me with your Postal Address and I'll send you a cheque when I have check with Russell after 21 days. I did not receive Erik's original email on this can you re-send it to me, please ? Thanks. O Plameras Russell Davie wrote: On Wed, 23 Nov 2005 21:49:25 +1100 Erik de Castro Lopo [EMAIL PROTECTED] wrote: O Plameras wrote: Erik de Castro Lopo wrote: If you come to the SLUG meeting on Friday, I will bring you a copy of this book so you can see for yourself. If you then publically admit that you were wrong on this issue you can keep the book [1]. It's nice of you to make that offer. Unfortunately, I can't come, physically but can be reached by email. Besides, your book will just gather dust. I suggest you gave it to SLUG enthusiasts who are keen to learn C. I'll make this offer, though. For every SLUG enthusiasts to whom you will give a book for free that can satisfy me that they learned from your book What about Hal Ashburner? He has told me that he found my book useful. Does he count? I said in my offer . . . will . . . , but I will make this ONE and ONLY ONE exception. So, the answer is YES, he gets the offer if he wants. To Hal: Please provide a photo of the Back Cover of the book, the one with the ISBN Number (and a photo of the page that has the price tag if there is) and email it to me. Can you provide me also with a short resume or bio-data with your qualification, age, training, current employer, and contact address apart from your email. Can you write short description of your experiences with the book and email me along, please. and say it's not a waste of their time, I'll offer to pay you half the bookshop's retail price . This offer is good for up to 25 enthusiasts. I'd be happy to take you up on this offer. Unfortunately I only have three remaining spare copies. So, the first three people who can attend Friday's SLUG meeting and are interested in this should email me privately (and CC Oscar) with the title of the book. - If one of the first three people don't show up at SLUG the book will go to the next person on the list. - If we don't get three people who sent email the books will go to people who are there on the night. Anyone interested can also inspect pages 39 to 42 for themselves. Erik -- +---+ Erik de Castro Lopo +---+ Being really good at C++ is like being really good at using rocks to sharpen sticks. -- Thant Tessman -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html Erik (and Oscar) The title is Sams Teach Yourself C for Linux Programming in 21 Days ISBN: 0672315971 I'd love a copy and love to get to Slug on Friday, though live in Lismore. If nobody claims a book, may I request to be the default receiver? I am happy to pay postage! I yearn to learn C to be able to write an ap for tracking change in heart rate with a pulse oxymeter plugged into com port. And now really keen now after your passionate banter!. BTW, strange, how elx.com.au don't have it, and bookware.com.au do but omit the all important C programing in the title. The reviews from Amazon are astounding! regards Russell -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: Three free C books on offer (was Re: [SLUG] C Gurus)
O Plameras wrote: I did not receive Erik's original email on this can you re-send it to me, please ? http://lists.slug.org.au/archives/slug/2005/11/msg00511.html Erik -- +---+ Erik de Castro Lopo +---+ It has been discovered that C++ provides a remarkable facility for concealing the trival details of a program -- such as where its bugs are. -- David Keppel -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Benno wrote: On Tue Nov 22, 2005 at 17:51:38 +1100, O Plameras wrote: [EMAIL PROTECTED] wrote: U ... Coding 3. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string2 = some words; return string2; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } somefunction returns string2 which is trash! formally: The scope of string2 does not extend to main! string2 is the return value of char * somefunction which is extern ( or GLOBAL). Sure, but the scope of string2 is local to somefunction. The thing is string2 is only a pointer, it isn't the actual memory. Exactly, it is a pointer and that's all you need to access the string. Why make a program look complicated when it is really simple. The reality is string2 in the context of the codes discussed is always defined and can never be trash. The function could have also been written with perhaps less confusion as: char *somefunction() { return some words; } The reason I don't like this style is that presumably somefunction() will in the future actually *do something* to generate a string. And then simply returning something like this no longer works -- you need to allocate something on the heap. And then it changes the interface you have with the client, because currently they are not allowed to free() what is returned. (And on any decent OS should actually crash, because writing to rodata shouldn't be allowe). However once you alloc then the interface becomes subtly differnt because the client must free() or else leave a memory leak. Which is bad for any long running process. And of course if somefunction() has to return some error code, not just the string you also need to get more trickier with pointers, and end up with what I had before. *but*, having any interface where you allocate data inside a function and expect to free is elsewhere is genreally bad, because it is too easy to screw up, and forget the free, probably better to supply a buffer if possible (with a length of course). Of course that means having some expection of the size required in the first place. (Can people start to see why I say doing C right is difficult??) If somefunction is really constant you might as well refactor as: const char somewords[] = some words; and avoid the confusion. Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue Nov 22, 2005 at 18:55:24 +1100, O Plameras wrote: Benno wrote: snip The problem with this statement is you generalize your point as if it is written in stone for most people to put into their heads, which is wrong. Many newbies out there are smarter than you think and given the right encouragement they will be able to learn about Linux in particular and Open Source in general quicker than you and me have. Everything is a generalisation. (See that was a joke for the humour impaired). I said peopel should learn C, what is the problem? Those that learn it really well, will learn all the pitfalls, and will start to yearn for higher level abstraction to the problems they encounter. And then they will learn a higher level langauge. Some people find it difficult to conceptualize pointers and pointer arithmetic which includes yourself I suppose because you kept on saying these are difficult to learn. You keep on telling yourself it is extremely difficult; and it is extremely hard. Hey, I'm the one that found the pointer arithmetic bug in your code. I don't have a problem with pointers. I use them every day, they aren't scary. Being a good programmer in any language means understanding pointers. *But* there are better ways to refer to abstract data types than through pointers. Really. The reality of it all is anyone can learn C in one day and master it in one week. That is total crap. Having gone through a C programming course, and taught one at university I know that to be plainly untrue. By this I mean, after one week anyone will be able to read anyone's C code provided it is written correctly. Not a chance. Don't believe you. And besides you are making generalisations, which are bad. C is extremely good because many OSes and Compilers are written in C including Linux itself and many tools in Linux. I would say C is good despite that ;). I never said C is bad, I said it was difficult to program in well. It is your mental attitude that makes you believe it is difficult. My mental attitude? *Right*. We just saw evidence on the mailing list of people screwing up little things that would either not be either syntacticly or semanticaly correct in more strongly typed languages. It seems that getting this right in a different langauge is easier, because given a mistake you might actually know about it in advance of running it. (I'm waiting for Eric to have a go at weakly type scripting languages here ;). Open Source is notoriously lacking in documentations. Unless you know C you are lost and you hardly can't proceed if you are doing a project. That is simply untrue. There are many projects written purely in python, perl,ocaml,haskell,java. Try writing a PHP module in these languages. Right I give in, you can't write a php module in any of those languages. Now I'm not exactly a PHP expert, but i am guessing you can program a PHP module, in say, PHP? And even if I need C to write a PHP module, or a device driver, or a kernel, or a compiler, the open source landscape is way bigger than that, and you don't need to know C to be a part of it. snip my previous solution snip I do not know if you heard about the seven blind men who went to visit an elephant in order to describe what an elephant is. I have heard something along those lines before, they all started touching it up and got different ideas as to what it would be. Or maybe that was some other story. Anyway, I think the point of it was that they couldn't see the forest for the trees? Or maybe that the trees looked like dinosaurs. That would be cooler. In any case I couldn't agree more, learning how to program doesn't mean you have to be an elephant. Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
O Plameras wrote: pointers and pointer arithmetic are very difficult concepts for people to learn. They are important things to learn, but most people find them difficult. The problem with this statement is you generalize your point as if it is written in stone for most people to put into their heads, which is wrong. If its so easy, how come you got it so wrong earlier in this thread? Some people find it difficult to conceptualize pointers and pointer arithmetic which includes yourself I suppose because you kept on saying these are difficult to learn. I happen to know Benno and also know that his C skills are well above average. The reality of it all is anyone can learn C in one day and master it in one week. That statement is simply ludicrous. One week's experience with a language with as many subtlties as C is simply insufficient, even for a person with a background in other programming languages. I *really* think you should read this: http://www.norvig.com/21-days.html By this I mean, after one week anyone will be able to read anyone's C code provided it is written correctly. Reading is not writing. Learning a human language usually involves speaking as well as listening, not just one or the other. (And really C sucks for device drivers and low level stuff too now I think about it, its not as though C has a way to access x86 style ports, and its not as though its structs are tightly defined enough so you can just use them to describe device memory layouts, although people do and rely on how the compiler works.) I do not know if you heard about the seven blind men who went to visit an elephant in order to describe what an elephant is. Yes, its a lovely story. However, Benno spends 40 plus hours a week writing OS kernel (not Linux) code and device drivers in C. Few people on this list are more qualified to say that C is a bad language for this task than Benno. Erik -- +---+ Erik de Castro Lopo +---+ Copyrighting allows people to benefit from their labours, but software patents allow the companies with the largest legal departments to benefit from everyone else's work. -- Andrew Brown (http://www.guardian.co.uk/online/comment/story/0,12449,1387575,00.html) -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
O Plameras [EMAIL PROTECTED] wrote: I don't find C difficult at all. Says the guy who has already demonstrated his lack of knowledge on strlen() and how strings are represented. C has one of the least number of vocabularies to learn and master. That makes the language small, not simple. -- Sam Eddie Couter | mailto:[EMAIL PROTECTED] Debian Developer| mailto:[EMAIL PROTECTED] | jabber:[EMAIL PROTECTED] OpenPGP fingerprint: A46B 9BB5 3148 7BEA 1F05 5BD5 8530 03AE DE89 C75C signature.asc Description: Digital signature -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
This one time, at band camp, Erik de Castro Lopo wrote: Yes, its a lovely story. However, Benno spends 40 plus hours a week writing OS kernel (not Linux) code and device drivers in C. Few people on this list are more qualified to say that C is a bad language for this task than Benno. I've reviewed Benno's code and it sucks. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Benno [EMAIL PROTECTED] wrote: Anyway, you can write good stuff in C, but really, unless computation speed is the issue [ ... ] ... and even when it is, avoid C. The compiler/VM/runtime for higher level languages is usually smarter than you are. You'll have to write the high level code first to find out which bits need optimisation anyway. -- Sam Eddie Couter | mailto:[EMAIL PROTECTED] Debian Developer| mailto:[EMAIL PROTECTED] | jabber:[EMAIL PROTECTED] OpenPGP fingerprint: A46B 9BB5 3148 7BEA 1F05 5BD5 8530 03AE DE89 C75C signature.asc Description: Digital signature -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
O Plameras [EMAIL PROTECTED] wrote: The reality of it all is anyone can learn C in one day and master it in one week. By this I mean, after one week anyone will be able to read anyone's C code provided it is written correctly. You can't just make stuff up and pretend it's true! That's not how the world works. -- Sam Eddie Couter | mailto:[EMAIL PROTECTED] Debian Developer| mailto:[EMAIL PROTECTED] | jabber:[EMAIL PROTECTED] OpenPGP fingerprint: A46B 9BB5 3148 7BEA 1F05 5BD5 8530 03AE DE89 C75C signature.asc Description: Digital signature -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Benno wrote: On Tue Nov 22, 2005 at 18:55:24 +1100, O Plameras wrote: Benno wrote: snip The problem with this statement is you generalize your point as if it is written in stone for most people to put into their heads, which is wrong. Many newbies out there are smarter than you think and given the right encouragement they will be able to learn about Linux in particular and Open Source in general quicker than you and me have. Everything is a generalisation. (See that was a joke for the humour impaired). I said peopel should learn C, what is the problem? Those that learn it really well, will learn all the pitfalls, and will start to yearn for higher level abstraction to the problems they encounter. And then they will learn a higher level langauge. Some people find it difficult to conceptualize pointers and pointer arithmetic which includes yourself I suppose because you kept on saying these are difficult to learn. You keep on telling yourself it is extremely difficult; and it is extremely hard. Hey, I'm the one that found the pointer arithmetic bug in your code. It is a problem with not checking with the manual, not a pointer problem. The reality is the program works because it does what it was expected to do, i.e., print the required string. You cannot show a situation where that code will not print the correct string, because the original poster has a '\0' at the end of the string. If it crashes then a fairly knowledgeable programmer just run 'gdb' after compiling with a '-g'. It is not big deal. But if the codes themselves are badly written, then it is a big problem. I don't have a problem with pointers. I use them every day, they aren't scary. Being a good programmer in any language means understanding pointers. *But* there are better ways to refer to abstract data types than through pointers. Really. The reality of it all is anyone can learn C in one day and master it in one week. That is total crap. Having gone through a C programming course, and taught one at university I know that to be plainly untrue. So , why you write such a complicated looking code, when it is a lot simpler By this I mean, after one week anyone will be able to read anyone's C code provided it is written correctly. Not a chance. Don't believe you. And besides you are making generalisations, which are bad. No wonder you write such a bad C code, as you have proposed in your example. C is extremely good because many OSes and Compilers are written in C including Linux itself and many tools in Linux. I would say C is good despite that ;). I never said C is bad, I said it was difficult to program in well. It is your mental attitude that makes you believe it is difficult. My mental attitude? *Right*. We just saw evidence on the mailing list of people screwing up little things that would either not be either syntacticly or semanticaly correct in more strongly typed languages. It seems that getting this right in a different langauge is easier, because given a mistake you might actually know about it in advance of running it. (I'm waiting for Eric to have a go at weakly type scripting languages here ;). Open Source is notoriously lacking in documentations. Unless you know C you are lost and you hardly can't proceed if you are doing a project. That is simply untrue. There are many projects written purely in python, perl,ocaml,haskell,java. Try writing a PHP module in these languages. Right I give in, you can't write a php module in any of those languages. Now I'm not exactly a PHP expert, but i am guessing you can program a PHP module, in say, PHP? That's one reason I write in C. There are things I want to do in PHP that's not covered in current PHP modules. If I do not know C I'm stuck. And even if I need C to write a PHP module, or a device driver, or a kernel, or a compiler, the open source landscape is way bigger than that, and you don't need to know C to be a part of it. snip my previous solution snip I do not know if you heard about the seven blind men who went to visit an elephant in order to describe what an elephant is. I have heard something along those lines before, they all started touching it up and got different ideas as to what it would be. Or maybe that was some other story. Anyway, I think the point of it was that they couldn't see the forest for the trees? Or maybe that the trees looked like dinosaurs. That would be cooler. In any case I couldn't agree more, learning how to program doesn't mean you have to be an elephant. Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue, 2005-11-22 at 19:35 +1100, Jamie Wilkinson wrote: This one time, at band camp, Erik de Castro Lopo wrote: Yes, its a lovely story. However, Benno spends 40 plus hours a week writing OS kernel (not Linux) code and device drivers in C. Few people on this list are more qualified to say that C is a bad language for this task than Benno. I've reviewed Benno's code and it sucks. I reviewed a different part of Benno's code. It also sucked. -- Pete -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue Nov 22, 2005 at 19:37:41 +1100, Sam Couter wrote: Benno [EMAIL PROTECTED] wrote: Anyway, you can write good stuff in C, but really, unless computation speed is the issue [ ... ] ... and even when it is, avoid C. The compiler/VM/runtime for higher level languages is usually smarter than you are. You'll have to write the high level code first to find out which bits need optimisation anyway. Yeah, I should have qualified my statement a bit more :) I know there are VMs out there that can garbage collect a hell of a lot beterr than the C heap. But if you are at the point of trying to get things in a few cache lines, or with a small memory footprintf there is still a use for C. (But hell, it still doesn't even let you do that very well, there is no standard way to specify alignment of data or code.) Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Jamie Wilkinson wrote: This one time, at band camp, Erik de Castro Lopo wrote: Yes, its a lovely story. However, Benno spends 40 plus hours a week writing OS kernel (not Linux) code and device drivers in C. Few people on this list are more qualified to say that C is a bad language for this task than Benno. I've reviewed Benno's code and it sucks. This is apparent even on such a simple C code as printing a string in function 'main' initialized from another function. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Benno wrote: (I'm waiting for Eric to have a go at weakly type scripting languages here ;). Well most scripting langunages (Python, Perl, Ruby etc) are actually strongly typed, its just that the type checking is done dynamically at run time rather than statically at compile time. However, thats all a separate kettle of worms. Erik -- +---+ Erik de Castro Lopo +---+ Cunnilinugus and psychiatry brought us to this. -- Tony Soprano in HBO's the Sopranos -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue, 2005-11-22 at 19:45 +1100, O Plameras wrote: Jamie Wilkinson wrote: This one time, at band camp, Erik de Castro Lopo wrote: Yes, its a lovely story. However, Benno spends 40 plus hours a week writing OS kernel (not Linux) code and device drivers in C. Few people on this list are more qualified to say that C is a bad language for this task than Benno. I've reviewed Benno's code and it sucks. This is apparent even on such a simple C code as printing a string in function 'main' initialized from another function. I've reviewed Jamie's jokes and they suck. -- Pete -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Peter Hardy wrote: On Tue, 2005-11-22 at 19:35 +1100, Jamie Wilkinson wrote: This one time, at band camp, Erik de Castro Lopo wrote: Yes, its a lovely story. However, Benno spends 40 plus hours a week writing OS kernel (not Linux) code and device drivers in C. Few people on this list are more qualified to say that C is a bad language for this task than Benno. I've reviewed Benno's code and it sucks. I reviewed a different part of Benno's code. It also sucked. Can anyone say what device drivers he has written so I can avoid or re-write them ? -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
O Plameras wrote: Peter Hardy wrote: On Tue, 2005-11-22 at 19:35 +1100, Jamie Wilkinson wrote: This one time, at band camp, Erik de Castro Lopo wrote: Yes, its a lovely story. However, Benno spends 40 plus hours a week writing OS kernel (not Linux) code and device drivers in C. Few people on this list are more qualified to say that C is a bad language for this task than Benno. I've reviewed Benno's code and it sucks. I reviewed a different part of Benno's code. It also sucked. Can anyone say what device drivers he has written so I can avoid or re-write them ? Benno has code in the main Linux scheduler, the memory management system, as well as most of the network and disk drivers. Erik -- +---+ Erik de Castro Lopo +---+ Good advice for everyone : stay away from churches, mosques and synagouges. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Sam Couter wrote: O Plameras [EMAIL PROTECTED] wrote: The reality of it all is anyone can learn C in one day and master it in one week. By this I mean, after one week anyone will be able to read anyone's C code provided it is written correctly. You can't just make stuff up and pretend it's true! That's not how the world works. I learned C in two days. But this was at BellLabs, Dayton, Ohio in 1989, from the people who invented C. Again, newbies out there don't be intimidated with C. If you aspire to be the best of the best learn C. Five days of C language learning is a small change when compared to what will be in store for you once you have this tool. C language is the mother of many other languages. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tuesday 22 November 2005 14:31, [EMAIL PROTECTED] wrote: U ... Coding 3. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string2 = some words; return string2; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } somefunction returns string2 which is trash! formally: The scope of string2 does not extend to main! (even if it works, and it might, it's WRONG) What are you talking about ? Tell me why it is trash. some words is not a global variable in somefunction(). There is no rule to say that the storage used for some words shall be intact after somefunction() returns. It might be, and your example might work, but it's still illegal. James -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue Nov 22, 2005 at 19:39:54 +1100, O Plameras wrote: Benno wrote: On Tue Nov 22, 2005 at 18:55:24 +1100, O Plameras wrote: Benno wrote: It is a problem with not checking with the manual, not a pointer problem. The reality is the program works because it does what it was expected to do, i.e., print the required string. It isn't a problem with the manual it was a problem with the understanding of how strings are represented in the C lanague. You cannot show a situation where that code will not print the correct string, because the original poster has a '\0' at the end of the You didn't allocate enough memory for the string! You strcpy()ed all over the top of some memory you didn't own! If he had already malloced some data just after that you just nuked it! I mean it is just such a classical C error from which you so often get exploits. It is this type of oh well it works here attitude that leads to the giant mess of software systems that exist. Because chances are that code will be reused through the joy of CAP technology and then used somewhere else, where that buffer overrun will matter. If it crashes then a fairly knowledgeable programmer just run 'gdb' after compiling with a '-g'. It is not big deal. Its bad because it will crash in subtle ways. i.e: it will overwrite someone else memory. Which is subtle, and isn't easy to track. And might not cause something to crash, but cause you monthly accounts to be over by $100. It is a big deal if that code is running on a customers embedded device in the field. But if the codes themselves are badly written, then it is a big problem. Sure, but on C the code often has to be complicated because a/ It is inherent in the problem being solved. b/ The language doesn't give you good tools. (E.g: syntax + library) to deal with complex problems. I don't have a problem with pointers. I use them every day, they aren't scary. Being a good programmer in any language means understanding pointers. *But* there are better ways to refer to abstract data types than through pointers. Really. The reality of it all is anyone can learn C in one day and master it in one week. That is total crap. Having gone through a C programming course, and taught one at university I know that to be plainly untrue. So , why you write such a complicated looking code, when it is a lot simpler It isn't really that complicated it it a couple of pointer derferences. And, as I already explained I was simply fixing the code based on the existing design, not rewriting as I would have done. I also made a generalisation about the problem and assumed that Ashley was preparing to write a function that actually returned a computed string, which as explained in depth elsewhere requires significantly more work than just returning a static string. (Because if Ahsley just wanted a static string he could have just used one, the function becomes entirely redundant). And also because I yearn to teach and impart knowledge on those trying to learn C by explaining what the pointers meant, so that in the future Ashley and others on the list would have learnt something about pointers. I don't know wether I succeeded or not, I got a thanks from Ashley and he didn't ask any follow ups, so I assumed it helped, maybe I'm misguided. I also pointed out elsewhere the simplest possible program that can achieve the same output, but I think you'd agree that that isn't very interesting, except from a mental masturbation how small can I make it point of view. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Benno This is fun and educational, so no-swords-at-dawn but Doing stuff 'cause it works ouch! Look at C implemented on some utterly horrid hardware (pics and tiny-atmels) and the known way does not work. The only way to write robust C is to pedantically follow the rules. I hoped to show a newby that. And yes too on style (I agree with your sentiment). Anyway thanks for discussion smile Cheers James On Tuesday 22 November 2005 14:49, Benno wrote: On Tue Nov 22, 2005 at 17:35:23 +1100, Benno wrote: On Tue Nov 22, 2005 at 13:51:59 +0800, [EMAIL PROTECTED] wrote: U ... Coding 3. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string2 = some words; return string2; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } somefunction returns string2 which is trash! formally: The scope of string2 does not extend to main! (even if it works, and it might, it's WRONG) some words will be allocated in the .rodata section not on the stack so it will actually work. (Not that I'd recommend doing this!!). I can't find anything in the C spec about return the address of a string literal, it doesn't say wether it is allowed or not. I can't actually find it in the C spec but from googling it does appear that string literals are constants with static storage duration which means they have lifetime of the program. (But I still wouldn't use that style, it is confusing at best.) Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
[EMAIL PROTECTED] wrote: On Tuesday 22 November 2005 14:31, [EMAIL PROTECTED] wrote: U ... Coding 3. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string2 = some words; return string2; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } somefunction returns string2 which is trash! formally: The scope of string2 does not extend to main! (even if it works, and it might, it's WRONG) What are you talking about ? Tell me why it is trash. some words is not a global variable in somefunction(). It is not global, yes. but char *somefunction() is global to main which is the address of the first character in some words. And string = somefunction() assigns the address of the first character in some words to string. So, when I print string, I get the result. I can even re-write my preferred code as: char * somefunction() { same as original. } int main (void) { printf (\n\nString is: %s\n\n, somefunction()); return 0; } to make it even more readable. There is no rule to say that the storage used for some words shall be intact after somefunction() returns. It might be, and your example might work, but it's still illegal. After somefunction() returns, it has the address of the first character in some words. I assign that address to string. I print the contents of that address up to character '\0'. This is done by printf. This is a fundamental concept you're missing. James -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue Nov 22, 2005 at 20:01:10 +1100, O Plameras wrote: Sam Couter wrote: O Plameras [EMAIL PROTECTED] wrote: The reality of it all is anyone can learn C in one day and master it in one week. By this I mean, after one week anyone will be able to read anyone's C code provided it is written correctly. You can't just make stuff up and pretend it's true! That's not how the world works. I learned C in two days. But this was at BellLabs, Dayton, Ohio in 1989, from the people who invented C. Yeah, and I learnt it in 3 hours when I was 13, but the thing is Oscar, not everyone is as brilliant as you and me. Lets face it half the people out there are below average, well strictly that isn't true, but if you can misplace a parentheses, I'm allowed to misuse statistics, anyway, where was I oh yeah, half of the world is just not that bright, I well, it takes them more than a few days to learn C. In fact I've seen people who in theory are in the top 25% of the age-group based on dubious testing, and most of them struggle to come to terms with pointers. And since you are deferring to KR, I'll defer to the oracle, joel spolsky, from joel on Software fame. He says that most people don't even have the part of the brain required to use pointers! (Disclaimer: I don't think he actually meant that literally, and despite thorough neurological examanations, researchs are still unable to find this mythical pointer part of the brain.) Anyway, people should learn C, but that doesn't mean they should use. Its kind like math, you should learn how to long multiplication, but in the end its much more productive and less error-prone to just use a calculator. Again, newbies out there don't be intimidated with C. If you aspire to be the best of the best learn C. Five days of C language learning is a small change when compared to what will be in store for you once you have this tool. C language is the mother of many other languages. I'm glad Oscar finally agrees with me! Learning C is one of the most important things to do if you want to be a programmer. Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Benno wrote: On Tue Nov 22, 2005 at 19:39:54 +1100, O Plameras wrote: Benno wrote: On Tue Nov 22, 2005 at 18:55:24 +1100, O Plameras wrote: Benno wrote: It is a problem with not checking with the manual, not a pointer problem. The reality is the program works because it does what it was expected to do, i.e., print the required string. It isn't a problem with the manual it was a problem with the understanding of how strings are represented in the C lanague. You cannot show a situation where that code will not print the correct string, because the original poster has a '\0' at the end of the You didn't allocate enough memory for the string! You strcpy()ed all over the top of some memory you didn't own! If he had already malloced some data just after that you just nuked it! I mean it is just such a classical C error from which you so often get exploits. It is this type of oh well it works here attitude that leads to the giant mess of software systems that exist. Because chances are that code will be reused through the joy of CAP technology and then used somewhere else, where that buffer overrun will matter. If it crashes then a fairly knowledgeable programmer just run 'gdb' after compiling with a '-g'. It is not big deal. Its bad because it will crash in subtle ways. i.e: it will overwrite someone else memory. Which is subtle, and isn't easy to track. And might not cause something to crash, but cause you monthly accounts to be over by $100. It is a big deal if that code is running on a customers embedded device in the field. But if the codes themselves are badly written, then it is a big problem. Sure, but on C the code often has to be complicated because a/ It is inherent in the problem being solved. b/ The language doesn't give you good tools. (E.g: syntax + library) to deal with complex problems. I don't have a problem with pointers. I use them every day, they aren't scary. Being a good programmer in any language means understanding pointers. *But* there are better ways to refer to abstract data types than through pointers. Really. The reality of it all is anyone can learn C in one day and master it in one week. That is total crap. Having gone through a C programming course, and taught one at university I know that to be plainly untrue. So , why you write such a complicated looking code, when it is a lot simpler It isn't really that complicated it it a couple of pointer derferences. And, as I already explained I was simply fixing the code based on the existing design, not rewriting as I would have done. I also made a generalisation about the problem and assumed that Ashley was preparing to write a function that actually returned a computed string, which as explained in depth elsewhere requires significantly more work than just returning a static string. (Because if Ahsley just wanted a static string he could have just used one, the function becomes entirely redundant). And also because I yearn to teach and impart knowledge on those trying to learn C by explaining what the pointers meant, so that in the future Ashley and others on the list would have learnt something about pointers. I don't know wether I succeeded or not, I got a thanks from Ashley and he didn't ask any follow ups, so I assumed it helped, maybe I'm misguided. I also pointed out elsewhere the simplest possible program that can achieve the same output, but I think you'd agree that that isn't very interesting, except from a mental masturbation how small can I make it point of view. Did you compile and run the program ? It works. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue Nov 22, 2005 at 17:18:57 +0800, [EMAIL PROTECTED] wrote: Benno This is fun and educational, so no-swords-at-dawn but Doing stuff 'cause it works ouch! Yeah, definately a bad idea! Look at C implemented on some utterly horrid hardware (pics and tiny-atmels) and the known way does not work. The only way to write robust C is to pedantically follow the rules. I hoped to show a newby that. Couldn't agree more. Its just that in this case the rule isn't 100% clear, and reading my handy C99 spec doesn't actually illuminate the subject. The tricky thing is that it doesn't actually say in the spec (well anywhere I could find), what the storage type is for string literals. And I think technically that a string literal there doesn't allocate memory in function scope but in global scope. I *think* according to the rules it is equilant to: const static char __magic_string[] = some words; char * fn(void) { char *s = __magic_string; return s; } Which I think you would agree is correct, (but again doesn't exactly buy you much). But then again it could be such that a C compiler is allowed to treat it as: char * fn(void) { char __magic_string[] = some words; char *s = __magic_string; return s; } Where it is clearly wrong. In my experience compilers tend to do it the first way, but that doesn't mean they couldn't do it the second way. I'm just really annoyed that I can't find the clause in the spec that gives the answer one way or the other. I'm glad you brought it up, I've learned more about thigns about C that I didn't even know I didn't know ;). Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Benno wrote: On Tue Nov 22, 2005 at 20:01:10 +1100, O Plameras wrote: Sam Couter wrote: O Plameras [EMAIL PROTECTED] wrote: The reality of it all is anyone can learn C in one day and master it in one week. By this I mean, after one week anyone will be able to read anyone's C code provided it is written correctly. You can't just make stuff up and pretend it's true! That's not how the world works. I learned C in two days. But this was at BellLabs, Dayton, Ohio in 1989, from the people who invented C. Yeah, and I learnt it in 3 hours when I was 13, but the thing is Oscar, not everyone is as brilliant as you and me. I don't mean you know C once you know to print Hello world!. By learning means mastery of the fundamentals including pointers and pointer arithmetic. C language is still the number one language in terms of percent share as a development tool. Let me just clarify. I do not consider myself brilliant. But at the same time I will not diminish the abilities of many smart newbies who have the best potentials when they learn C. They can learn C from home and right now. You will not regret you learn C language. Forget about people saying negative vibes about C. Lets face it half the people out there are below average, well strictly that isn't true, but if you can misplace a parentheses, I'm allowed to misuse statistics, anyway, where was I oh yeah, half of the world is just not that bright, I well, it takes them more than a few days to learn C. In fact I've seen people who in theory are in the top 25% of the age-group based on dubious testing, and most of them struggle to come to terms with pointers. And since you are deferring to KR, I'll defer to the oracle, joel spolsky, from joel on Software fame. He says that most people don't even have the part of the brain required to use pointers! (Disclaimer: I don't think he actually meant that literally, and despite thorough neurological examanations, researchs are still unable to find this mythical pointer part of the brain.) Anyway, people should learn C, but that doesn't mean they should use. Its kind like math, you should learn how to long multiplication, but in the end its much more productive and less error-prone to just use a calculator. Again, newbies out there don't be intimidated with C. If you aspire to be the best of the best learn C. Five days of C language learning is a small change when compared to what will be in store for you once you have this tool. C language is the mother of many other languages. I'm glad Oscar finally agrees with me! Learning C is one of the most important things to do if you want to be a programmer. Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
[snip] U ... Coding 3. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string2 = some words; return string2; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } O Plameras was once rumoured to have said: After somefunction() returns, it has the address of the first character in some words. I assign that address to string. I print the contents of that address up to character '\0'. This is done by printf. This is a fundamental concept you're missing. No, you're missing it. Here's a slightly nastier example[1] which demonstrates why what you're doing is wrong and should not be done. ---BEGIN--- #include stdio.h #include stdlib.h #include string.h char * somefunction() { auto char string2[] = some words; return string2; } void anotherfunction() { auto inti,r[50]; /* build a 'random' sequence on the stack to prove the point. */ for (i = 0; i 50; i++) { r[i] = (i*13)%256; } } int main (void) { char *string; string = somefunction(); anotherfunction(); printf (\n\nString is: %s\n\n, string); return 0; } ---END--- string still contains a pointer to the start of the string some words, right? Now, before chickening out and running it, predict the outcome. This is why you don't return pointers from stuff defined in local subroutine scope. C. [1] I expect Benno and Erik to immediately spot the subtle difference. ;) -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
This is a different code. I'd do it differently. But for another time. Crossfire wrote: [snip] U ... Coding 3. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string2 = some words; return string2; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } O Plameras was once rumoured to have said: After somefunction() returns, it has the address of the first character in some words. I assign that address to string. I print the contents of that address up to character '\0'. This is done by printf. This is a fundamental concept you're missing. No, you're missing it. Here's a slightly nastier example[1] which demonstrates why what you're doing is wrong and should not be done. ---BEGIN--- #include stdio.h #include stdlib.h #include string.h char * somefunction() { auto char string2[] = some words; return string2; } void anotherfunction() { auto inti,r[50]; /* build a 'random' sequence on the stack to prove the point. */ for (i = 0; i 50; i++) { r[i] = (i*13)%256; } } int main (void) { char *string; string = somefunction(); anotherfunction(); printf (\n\nString is: %s\n\n, string); return 0; } ---END--- string still contains a pointer to the start of the string some words, right? Now, before chickening out and running it, predict the outcome. This is why you don't return pointers from stuff defined in local subroutine scope. C. [1] I expect Benno and Erik to immediately spot the subtle difference. ;) -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
O Plameras was once rumoured to have said: This is a different code. Of course its different code. This is not about how you'd do it, this is about why you DON'T do it. C. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue, Nov 22, 2005 at 08:24:18PM +1100, O Plameras wrote: [...] Did you compile and run the program ? It works. Many programs with bugs that overwrite arbitrary memory appear to work just fine, and then one day someone writes an exploit for it. The fact that a program gives the expected output in a particular environment with a particular compiler does not mean it is correct. Understanding this issue and the possible consequences would be very useful for when you make this mistake in another context, and have to figure out why your program is crashing. Your definition of works is short-sighted. -Andrew. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Crossfire wrote: O Plameras was once rumoured to have said: This is a different code. Of course its different code. This is not about how you'd do it, this is about why you DON'T do it. C. Programming is about coding to produce the stated results. Your code is silly as far as the objective of the program is concerned. No programmer would consider ever writing your kind of code considering the stated results. When you try to compile your code there are warnings which means your code is not ready to be ran. O Plameras. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Andrew Bennetts wrote: On Tue, Nov 22, 2005 at 08:24:18PM +1100, O Plameras wrote: [...] Did you compile and run the program ? It works. Many programs with bugs that overwrite arbitrary memory appear to work just fine, and then one day someone writes an exploit for it. The fact that a program gives the expected output in a particular environment with a particular compiler does not mean it is correct. Understanding this issue and the possible consequences would be very useful for when you make this mistake in another context, and have to figure out why your program is crashing. Your definition of works is short-sighted. -Andrew. So, can you show me how you would code considering the stated results ? O Plameras -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On 11/22/05, Crossfire [EMAIL PROTECTED] wrote: [snip] U ... Coding 3. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string2 = some words; return string2; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } O Plameras was once rumoured to have said: After somefunction() returns, it has the address of the first character in some words. I assign that address to string. I print the contents of that address up to character '\0'. This is done by printf. This is a fundamental concept you're missing.No, you're missing it.Here's a slightly nastier example[1] whichdemonstrates why what you're doing is wrong and should not be done. ---BEGIN---#include stdio.h#include stdlib.h#include string.hchar *somefunction(){auto char string2[] = some words;return string2; }voidanotherfunction(){auto inti,r[50];/* build a 'random' sequence on the stack to prove the point. */for (i = 0; i 50; i++) {r[i] = (i*13)%256; }}int main (void){char *string;string = somefunction();anotherfunction();printf (\n\nString is: %s\n\n, string);return 0; }---END---string still contains a pointer to the start of the string somewords, right?Now, before chickening out and running it, predict the outcome.This is why you don't return pointers from stuff defined in local subroutine scope.C.[1] I expect Benno and Erik to immediately spot the subtle difference. ;)--SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html Wow, I remember when this thread had just 3 messages. Anyway, just trying to clarify from the above code: string2 is a pointer to an automatic variable - a character array? Very bad to pass this address back to main(). But if you had said char * string2 = some words or even auto char * string2 = some words it will work (at least as I've just tested with gcc) because you've initialised a pointer to a string literal, which pretty much is set in stone for the life of the program. (Nor can you alter its contents) So: 1) char string2[] = string literal; - string2 is created with separate location (an address on the stack in the above code) to string literal and string literal is copied into it. 2) char *string2 = string literal; - string2 holds an address of string literal which is not on the stack Daniel. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
O Plameras was once rumoured to have said: Programming is about coding to produce the stated results. Your code is silly as far as the objective of the program is concerned. What? the objective I set for my program was quite straight forward. Obviously you failed to observe what it was, and mistook it for your objective. The point of the demonstration is why you never return pointers of locally scoped data from a function. It may look safe superficially, but it isn't. When you try to compile your code there are warnings which means your code is not ready to be ran. No. Warnings can be misleading. Especially if warning against the desired effect. They are warnings afterall. Warnings are also not the final level of protection against stupidity. Take this code for example: ---BEGIN--- #include stdio.h unsigned long * foo() { static unsigned longmagic = 0x1234; return magic; }; int main() { unsigned short *dptr; dptr = (unsigned short *)foo(); /* do something with *dptr... ? */ printf (dptr - 0x%04hX\n, *dptr); return 0; } ---END--- Look mah, no warnings. Its still blatantly wrong. (big endian machines should give you dptr - 0x, little endian machines should give you dptr - 0x1234, thus illustrating how wrong this is.) I don't care if you were taught at Bell Labs, it certainly isn't showing now. C. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Daniel Bush was once rumoured to have said: Wow, I remember when this thread had just 3 messages. Anyway, just trying to clarify from the above code: string2 is a pointer to an automatic variable - a character array? Very bad to pass this address back to main(). But if you had said char * string2 = some words or even auto char * string2 = some words it will work (at least as I've just tested with gcc) because you've initialised a pointer to a string literal, which pretty much is set in stone for the life of the program. (Nor can you alter its contents) Correct, but at the same time, the behaviour is not reliable. IIRC, ANSI C[1] makes no guaranty as to the lifetime of literal strings when their enclosing scope finishes. And not all literal strings are 'static' as my code demonstrated. C. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Crossfire wrote: O Plameras was once rumoured to have said: Programming is about coding to produce the stated results. Your code is silly as far as the objective of the program is concerned. What? the objective I set for my program was quite straight forward. Then, you have your objective, the original poster has his. That's why your code is different. Why bother ? There is one thing fundamentally wrong with your coding and this has been addressed by a previous poster. This is why I have said no programmer will code the way you have done it. Obviously you failed to observe what it was, and mistook it for your objective. The point of the demonstration is why you never return pointers of locally scoped data from a function. It may look safe superficially, but it isn't. When you try to compile your code there are warnings which means your code is not ready to be ran. No. Warnings can be misleading. Especially if warning against the desired effect. They are warnings afterall. Warnings are also not the final level of protection against stupidity. Take this code for example: ---BEGIN--- #include stdio.h unsigned long * foo() { static unsigned longmagic = 0x1234; return magic; }; int main() { unsigned short *dptr; dptr = (unsigned short *)foo(); /* do something with *dptr... ? */ printf (dptr - 0x%04hX\n, *dptr); return 0; } ---END--- Look mah, no warnings. Its still blatantly wrong. (big endian machines should give you dptr - 0x, little endian machines should give you dptr - 0x1234, thus illustrating how wrong this is.) I don't care if you were taught at Bell Labs, it certainly isn't showing now. I was just asked, and I replied truthfully. C. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On 22/11/05, Erik de Castro Lopo [EMAIL PROTECTED] wrote: I *really* think you should read this: http://www.norvig.com/21-days.html Erik, When are you going to sign the copy of the book I learned C from? http://www.amazon.com/gp/product/0672315971/102-2858012-6274528?v=glancen=283155s=booksv=glance And the other advice from Erik on this list about learning C. Get a book that is not specific to an OS or architecture. Actually, that'd make a good dedication ;-) -- Kind regards, Hal Ashburner -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Hal Ashburner wrote: Erik, When are you going to sign the copy of the book I learned C from? You know the deal. You bring the book and I'll sign it. Someone told me I will be at SLUG this Firday :-). http://www.amazon.com/gp/product/0672315971/102-2858012-6274528?v=glancen=283155s=booksv=glance And the other advice from Erik on this list about learning C. Get a book that is not specific to an OS or architecture. Actually, that'd make a good dedication ;-) Or a quote: Get a book that is not specific to an OS or architecture. -- Erik, (co-)author of C for Linux Programming in 21 days. Similar in some ways to: Anyone who quotes me in their .sig is an idiot. -- Rusty Russell Erik -- +---+ Erik de Castro Lopo +---+ C++ is a siren song. It *looks* like a HLL in which you ought to be able to write an application, but it really isn't. -- Alain Picard (comp.lang.lisp) -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Hal Ashburner wrote: On 22/11/05, Erik de Castro Lopo [EMAIL PROTECTED] wrote: I *really* think you should read this: http://www.norvig.com/21-days.html Erik, When are you going to sign the copy of the book I learned C from? http://www.amazon.com/gp/product/0672315971/102-2858012-6274528?v=glancen=283155s=booksv=glance And the other advice from Erik on this list about learning C. Get a book that is not specific to an OS or architecture. Actually, that'd make a good dedication ;-) -- Hi Hal, My son's library has the fourth edition with co-authors, Peter Aitken and Bradley L. Jones. In that edition Eric is not included as co-author yet. But the http://www.amazon.com/gp/product/0672315971/102-2858012-6274528?v=glancen=283155s=booksv=glance says he is. I had a quick look at the fourth edition and I noticed that the examples says word-size is 2 bytes meaning this fourth edition was written with 16-bit PCs as the test platform. I'm just wondering if the latest edition has examples that were modified for 32-bit PCs. Thanks. O Plameras -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue, Nov 22, 2005 at 10:12:07PM +1100, Crossfire wrote: IIRC, ANSI C[1] makes no guaranty as to the lifetime of literal ^^^ Not that I'm trying to get involved in this Gospel according to Oscar thread, but Crossfire, you forgot the footnote, and now I'm interested! Cheers, -- Steve -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Steve Kowalik was once rumoured to have said: On Tue, Nov 22, 2005 at 10:12:07PM +1100, Crossfire wrote: IIRC, ANSI C[1] makes no guaranty as to the lifetime of literal ^^^ Not that I'm trying to get involved in this Gospel according to Oscar thread, but Crossfire, you forgot the footnote, and now I'm interested! Damnit. :) I was going to make a point that I refer to classic ANSI C (C89), not C99. given that I did the bulk of my C learning pre C99, and C99 hasn't really done much to make life any better, nor have I gotten my hands on any C99 references. I also have access to a printed copy of the formal C89 defintion at work which I've referred to in the past over arguments to do with operator precidence. I feel like such an old man[2] sometimes dealing with this stuff... C. [2] Of course, My age is nowhere near that of 'old man' status... -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
This one time, at band camp, Alex Sayle wrote: http://www.joelonsoftware.com/articles/fog000319.html and a nice little(?) article on pascal strings, ASCIZ and a bit about pointers. That's totally awesome, thanks for posting :) -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue, 22 Nov 2005, Benno wrote: snip But if you are at the point of trying to get things in a few cache lines, or with a small memory footprintf there is still snip ^^ evidence that someone has been coding too much lately ;-) Cheers, - Simon -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue, Nov 22, 2005 at 09:42:49PM +1100, O Plameras wrote: Andrew Bennetts wrote: On Tue, Nov 22, 2005 at 08:24:18PM +1100, O Plameras wrote: Did you compile and run the program ? It works. [...] Your definition of works is short-sighted. So, can you show me how you would code considering the stated results ? I'd code it without the bug that overwrites memory you didn't allocate, as explained by Benno. Preferably, I'd do this by avoiding C and using a language like Python that makes this sort of error impossible. This is exactly the sort of bug that in many pieces of software is discovered to be an exploitable security hole. Even if a bug like this isn't exploitable in its current context, as code is modified, refactored and re-used (as so often happens), it might be later. Or maybe it'll just cause a mysterious crash one day due to the heap corruption this sort of pointer arithmetic error can cause. This can manifest as a crash during some call to malloc or free well after the corruption happened, which makes debugging difficult, particularly if you don't know how to reproduce the crash. The stated results aren't clear to me -- I'm not sure what problem the original code was meant to solve. However, code should be robust, and because of the pointer arithmetic bug yours isn't. This makes it a poor solution to whatever the problem is, and a maintenance headache. This is what I meant by short-sighted. -Andrew. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue, Nov 22, 2005 at 05:49:49PM +1100, Benno wrote: I can't actually find it in the C spec but from googling it does appear that string literals are constants with static storage duration which means they have lifetime of the program. (But I still wouldn't use that style, it is confusing at best.) I've used it for error messages; a 0 return means ok, non-0 is an error message to be spat out. I'm sure I've seen gnu software use it too; possibly even this way. fwiw, I'm far from sure it's a great idea, but it sure beats mallocing something that is never going to be changed. -- Matt -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
quote who=Erik de Castro Lopo Can anyone say what device drivers he has written so I can avoid or re-write them ? Benno has code in the main Linux scheduler, the memory management system, as well as most of the network and disk drivers. I was trying to think of a subtle and succinct way of saying that, but all I could come up with was, YOU ARE DOOMED. - Jeff -- Ubuntu USA Europe Tour: Oct-Nov 2005http://wiki.ubuntu.com/3BT Ah, now we see the violence inherent in the system. - From Monty Python to ESR, by way of Al Viro -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
O Plameras wrote: Hi Hal, My son's library has the fourth edition with co-authors, Peter Aitken and Bradley L. Jones. In that edition Eric is not included as co-author yet. Thats correct (although the spelling of my name os not). But the http://www.amazon.com/gp/product/0672315971/102-2858012-6274528?v=glancen=283155s=booksv=glance says he is. I had a quick look at the fourth edition and I noticed that the examples says word-size is 2 bytes meaning this fourth edition was written with 16-bit PCs as the test platform. I'm just wondering if the latest edition has examples that were modified for 32-bit PCs. In the book I co-authored, this issue is dealt with on pages 39 to 42. In this section I supply an example program called sizeof.c which prints out the sizes of the various numeric types (including long). I also show the output of this program on a 32 bit i386 CPU as well as a 64 bit DEC/Compaq Alpha CPU. If you come to the SLUG meeting on Friday, I will bring you a copy of this book so you can see for yourself. If you then publically admit that you were wrong on this issue you can keep the book [1]. Erik [1] I don't think this book is perfect. It was published in 1999 and I have leanrt a lot about C and programming since then. -- +---+ Erik de Castro Lopo +---+ I could never learn to use C++, because of the completely overwhelming desire to redesign the language every time I tried to use it, but this is the normal, healthy reaction to C++. -- Erik Naggum -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Erik de Castro Lopo wrote: If you come to the SLUG meeting on Friday, I will bring you a copy of this book so you can see for yourself. If you then publically admit that you were wrong on this issue you can keep the book [1]. I am just wondering where I was wrong and I did not say I was wrong ? O Plameras -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Wed, 2005-11-23 at 00:56 +1100, Matthew Hannigan wrote: On Tue, Nov 22, 2005 at 05:49:49PM +1100, Benno wrote: I can't actually find it in the C spec but from googling it does appear that string literals are constants with static storage duration which means they have lifetime of the program. (But I still wouldn't use that style, it is confusing at best.) I've used it for error messages; a 0 return means ok, non-0 is an error message to be spat out. I'm sure I've seen gnu software use it too; possibly even this way. fwiw, I'm far from sure it's a great idea, but it sure beats mallocing something that is never going to be changed. Well for long lived programs, you usually dont assume that *all* errors will be static, some may have dynamic content. So that implies (in the common case) that the emitter of the error will clean it up (unless you have a pseudo object system where you pass the used error back to the creator). Its the emitter cleaning it up that implies that all errors should be 'free'able. Rob -- GPG key available at: http://www.robertcollins.net/keys.txt. signature.asc Description: This is a digitally signed message part -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Erik de Castro Lopo wrote: If you come to the SLUG meeting on Friday, I will bring you a copy of this book so you can see for yourself. If you then publically admit that you were wrong on this issue you can keep the book [1]. Oh, I missed the offer. It's nice of you to make that offer. Unfortunately, I can't come, physically but can be reached by email. Besides, your book will just gather dust. I suggest you gave it to SLUG enthusiasts who are keen to learn C. I'll make this offer, though. For every SLUG enthusiasts to whom you will give a book for free that can satisfy me that they learned from your book and say it's not a waste of their time, I'll offer to pay you half the bookshop's retail price . This offer is good for up to 25 enthusiasts. Thanks for your offer anyway. O Plameras -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue, Nov 22, 2005 at 10:12:07PM +1100, Crossfire wrote: IIRC, ANSI C[1] makes no guaranty as to the lifetime of literal strings when their enclosing scope finishes. I'm fairly sure ANSI C does, C99 definitely does And not all literal strings are 'static' as my code demonstrated. String literals are defined with static storage duration by definition. C99 6.4.5.5 The multibyte character sequence [string literal] is then used to initalize an array of static storage duration and length just sufficient to contain the sequence. Where static storage duration is defined in 6.2.4.3 Its lifetime is the entire execution of the program and its stored value is initalized only once, prior to program startup. So it seems quite valid (as you probably know anyway it will be put in some read only section which isn't going to go away). But the code in question will have an interesting alternative property that it will confuse every single programmer who looks at the code for the rest of eternity. -i signature.asc Description: Digital signature -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue, 2005-11-22 at 18:29 +1100, Benno wrote: ... However once you alloc then the interface becomes subtly differnt because the client must free() or else leave a memory leak. Which is bad for any long running process. And of course if somefunction() has to return some error code, not just the string you also need to get more trickier with pointers, and end up with what I had before. *but*, having any interface where you allocate data inside a function and expect to free is elsewhere is genreally bad, because it is too easy to screw up, and forget the free, probably better to supply a buffer if possible (with a length of course). Of course that means having some expection of the size required in the first place. Which (taken to extremes) leads to the terrible interface that the MS DCE-RPC calls use all over the place, where you have N network round trips to find out that you needed a 55K buffer not a 30K buffer, or equally, a round trip to find that out and then a round trip to populate it. ... And the buffer you supply is itself allocated (unless you know the length a-priori), so it must be freed too. I think allocating something in a function and having it freed by the caller is fine as long as it is clearly documented. Rob -- GPG key available at: http://www.robertcollins.net/keys.txt. signature.asc Description: This is a digitally signed message part -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
[SLUG] C Gurus
G'day, As the original poster, I did expect to eat some humble pie asking such a trivial question. Thanks to those who gave serious answers. (As most of the respondents know me I expect I'll get a hard time for a while over that one.) I've been playing with gtk and found myself getting very confused, so I decided the fastest way of re-orientating myself was to seek the assistance of the SLUG Gurus. So I've sorted my confusion, and learned a great deal. Now back to banging my head against a brick wall called gtk. Regards, Ashley -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Wed Nov 23, 2005 at 09:48:36 +1100, Ian Wienand wrote: On Tue, Nov 22, 2005 at 10:12:07PM +1100, Crossfire wrote: IIRC, ANSI C[1] makes no guaranty as to the lifetime of literal strings when their enclosing scope finishes. I'm fairly sure ANSI C does, C99 definitely does And not all literal strings are 'static' as my code demonstrated. String literals are defined with static storage duration by definition. C99 6.4.5.5 The multibyte character sequence [string literal] is then used to initalize an array of static storage duration and length just sufficient to contain the sequence. Awwesome, that is the clause I was looking for but could not find! Where static storage duration is defined in 6.2.4.3 Its lifetime is the entire execution of the program and its stored value is initalized only once, prior to program startup. So it seems quite valid (as you probably know anyway it will be put in some read only section which isn't going to go away). But the code in question will have an interesting alternative property that it will confuse every single programmer who looks at the code for the rest of eternity. Yeah ;) -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Wed Nov 23, 2005 at 09:53:10 +1100, Robert Collins wrote: On Tue, 2005-11-22 at 18:29 +1100, Benno wrote: ... However once you alloc then the interface becomes subtly differnt because the client must free() or else leave a memory leak. Which is bad for any long running process. And of course if somefunction() has to return some error code, not just the string you also need to get more trickier with pointers, and end up with what I had before. *but*, having any interface where you allocate data inside a function and expect to free is elsewhere is genreally bad, because it is too easy to screw up, and forget the free, probably better to supply a buffer if possible (with a length of course). Of course that means having some expection of the size required in the first place. Which (taken to extremes) leads to the terrible interface that the MS DCE-RPC calls use all over the place, where you have N network round trips to find out that you needed a 55K buffer not a 30K buffer, or equally, a round trip to find that out and then a round trip to populate it. ... And the buffer you supply is itself allocated (unless you know the length a-priori), so it must be freed too. I think allocating something in a function and having it freed by the caller is fine as long as it is clearly documented. Yeah, now the cool thing is that tools like splint actually let you define and track such semantics. Basically it lets you annotate a function saything the return value is data that must be freed by the client, and can detect whether the cller drops a reference to that pointer before freeing it which is why way back when, I advocated that people should these tools when using C. (That said, if you don't start with itat the beginning of the project, siwtching to it mid project can be a major PITA -- but it can also find a lot of bugs you wouldn't find in testing.) Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Wednesday 23 November 2005 07:26, [EMAIL PROTECTED] wrote: I unreservedly apologise for being utterly wrong: 'what rule says that the scope and lifetime of a string ...' James IIRC, ANSI C[1] makes no guaranty as to the lifetime of literal strings when their enclosing scope finishes. I'm fairly sure ANSI C does, C99 definitely does And not all literal strings are 'static' as my code demonstrated. String literals are defined with static storage duration by definition. C99 6.4.5.5 The multibyte character sequence [string literal] is then used to initalize an array of static storage duration and length just sufficient to contain the sequence. Where static storage duration is defined in 6.2.4.3 Its lifetime is the entire execution of the program and its stored value is initalized only once, prior to program startup. So it seems quite valid (as you probably know anyway it will be put in some read only section which isn't going to go away). But the code in question will have an interesting alternative property that it will confuse every single programmer who looks at the code for the rest of eternity. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Ian Wienand wrote: On Tue, Nov 22, 2005 at 10:12:07PM +1100, Crossfire wrote: IIRC, ANSI C[1] makes no guaranty as to the lifetime of literal strings when their enclosing scope finishes. I'm fairly sure ANSI C does, C99 definitely does And not all literal strings are 'static' as my code demonstrated. String literals are defined with static storage duration by definition. C99 6.4.5.5 The multibyte character sequence [string literal] is then used to initalize an array of static storage duration and length just sufficient to contain the sequence. Where static storage duration is defined in 6.2.4.3 Its lifetime is the entire execution of the program and its stored value is initalized only once, prior to program startup. So it seems quite valid (as you probably know anyway it will be put in some read only section which isn't going to go away). But the code in question will have an interesting alternative property that it will confuse every single programmer who looks at the code for the rest of eternity. Not confusing if that programmer understands pointers and pointer arithmetic as well as know and understand that: 1. variable storage class of static has a lifetime of the program regardless of which function it is located. By the way this convention is there in KR which later became ANSI C. In fact, this is one of the very first rules we learn in Variable Storage Class Static. 2. An initialised variable storage class is static by definition. 3. A function can be typed like any variable storage class. 4. The functionality of return. O Plameras -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
This one time, at band camp, ashley maher wrote: So I've sorted my confusion, and learned a great deal. I want to thank you for the thread, I learned about 8 things in the last 24 hours :) -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Wed, Nov 23, 2005 at 09:24:46AM +1100, Robert Collins wrote: I've used it for error messages; a 0 return means ok, non-0 is an error message to be spat out. I'm sure I've seen gnu software use it too; possibly even this way. fwiw, I'm far from sure it's a great idea, but it sure beats mallocing something that is never going to be changed. Well for long lived programs, you usually dont assume that *all* errors will be static, some may have dynamic content. So that implies (in the common case) that the emitter of the error will clean it up (unless you have a pseudo object system where you pass the used error back to the creator). Its the emitter cleaning it up that implies that all errors should be 'free'able. Yeah, this was just for a hundred liner for my own use. FWIW, again, the code just did return Error: pants missing; rather than actually use a variable. I think that reads very cleanly. -- Matt -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
[SLUG] C Gurus
G'day, I know this is not even C 101 level but would some kind soul please explain to me why this is not even close to working. Regards, Ashley #include stdio.h #include stdlib.h #include string.h int somefunction(char *string1) { char *string2 = some words\0; string1 = (char *)calloc(strlen(string2 + 1), sizeof (char)); strcpy(string1, string2); return 0; } int main () { char *string; somefunction(string); printf (\n\nString is: %s\n\n, string); free (string); return 0; } -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
ashley maher wrote: try this instead: #include stdio.h #include stdlib.h #include string.h int somefunction(char **string1) { char *string2 = some words\0; *string1 = (char *)calloc(strlen(string2 + 1), sizeof (char)); strcpy(*string1, string2); return 0; } int main () { char *string; somefunction(string); printf (\n\nString is: %s\n\n, string); free (string); return 0; } I presume this is for some school assignment, in which case you should study more. If not, you should be aware there is a function called strdup() which does this. Trent -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue, 2005-11-22 at 13:26 +1100, ashley maher wrote: G'day, I know this is not even C 101 level but would some kind soul please explain to me why this is not even close to working. Regards, Ashley #include stdio.h #include stdlib.h #include string.h int somefunction(char *string1) { char *string2 = some words\0; string1 = (char *)calloc(strlen(string2 + 1), sizeof (char)); strcpy(string1, string2); return 0; } int main () { char *string; somefunction(string); printf (\n\nString is: %s\n\n, string); free (string); return 0; } You are pasing a pointer to char to somefunction. Its not altering the referenced memory area, rather its just allocating a new variable locally. int somefunction(char **string1location) { char * string1 = (char *)calloc(strlen(string2 + 1), sizeof (char)); *string1location = string1; .. } should work better. Rob -- GPG key available at: http://www.robertcollins.net/keys.txt. signature.asc Description: This is a digitally signed message part -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue, 2005-11-22 at 13:43 +1100, Robert Collins wrote: On Tue, 2005-11-22 at 13:26 +1100, ashley maher wrote: G'day, I know this is not even C 101 level but would some kind soul please explain to me why this is not even close to working. Regards, Ashley #include stdio.h #include stdlib.h #include string.h int somefunction(char *string1) { char *string2 = some words\0; string1 = (char *)calloc(strlen(string2 + 1), sizeof (char)); strcpy(string1, string2); return 0; } int main () { char *string; somefunction(string); printf (\n\nString is: %s\n\n, string); free (string); return 0; } You are pasing a pointer to char to somefunction. Its not altering the referenced memory area, rather its just allocating a new variable locally. int somefunction(char **string1location) { char * string1 = (char *)calloc(strlen(string2 + 1), sizeof (char)); *string1location = string1; .. } should work better. Rob thanks Rob -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue Nov 22, 2005 at 13:26:24 +1100, ashley maher wrote: G'day, I know this is not even C 101 level but would some kind soul please explain to me why this is not even close to working. So you are basicalyl missing what pointers mean. char * is a pointer to some memory that can hold a bunch of chars. It is not an actual string. I try to explain further: int somefunction(char *string1) { So this is some function that gets pointer to some memory. It gets a *copy* of an agument of the stack, and shoves it in a local variable called string1. string1 is a pointer to some memory. char *string2 = some words\0; Here you allocate variable string2, and point it to some memory with the data some words. (b.t.w: you don't need \0). string1 = (char *)calloc(strlen(string2 + 1), sizeof (char)); Here you allocate zome memory from the heap, specifically enough to a copy of the memory pointed to by string2. In doing so it redefines what ever value was passed in to the function. Oh wait, even more subtle than that, I missed it. You actually allocate 2 less than need to store string2, becuase you actually take the length of string2 + 1, which is the length of the string ome words, which is 2 less than need to store null terminated string2. strcpy(string1, string2); It now copies the contents of the memory pointed to by string2 into the new memory pointed to by string1. (Note, no need to use calloc, you could have just used malloc, since you just overwrote all that memory anyway.) return 0; Up to here you haven't done anything that is visible globally or to the calling function, exception allocate some memory on the heap. And now since you return you have created a memory leak, because there is no longer any reference to string1. } int main () { char *string; Ok, this decalres a string point. That is a pointer to some memory. But since you didn't initialise it, it currently point to some random place in memory. somefunction(string); You call this function that doesn't modify the string at all. printf (\n\nString is: %s\n\n, string); And then you print out some random data. free (string); And then you try and free something not previously allocated by malloc, so it dies in a heap. return 0; } I suggest compiling with -Wall, which will point out a lot of these errors before you execute the code. Another style point is that it is generally consider bad to allocate memory in one function and free it in another. I suspect the closest thing to what you wanted to do here would be: int somefunction(char **string1) { /* a function that takes a pointer to a pointer to memory */ char *string2 = some words; *string1 = malloc(strlen(string2) + 1); /* allocate memory and assign it to the char pointer, to which string1 points to. Known as dereferencing. */ if ((*string1) == NULL) /*SHould at least check return value! */ return -1; strcpy(*string1, string2); /* Copy the string */ return 0; } int main(void) { char * string; int r; r = somefunction(string); /* Pass the address of string to somefunction */ if (r != 0) { fprintf(stderr, Couldn't allocate memory\n); return 1; } /* now we know that string actually points somewhere */ printf(String is %s\n, string); free(string); return 0; } Of course thatisn't really the correct way to write it either, that would depend on what you are actually trying to achieve which I can't grok from the code. Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Hi ashley, I have three sets of codes that will do the task as I see it from your codes. I presented these three codes from the least to the most preferred coding. The common idea in all the three codes: 'somefunction' has static array of characters that is to be printed in 'main'; to accomplish this, just pass that address of the first character in a string to be printed. I changed the TYPE of 'somefunction' from 'int' to 'char *' to achieve this end. I used malloc instead of calloc in Coding 2. It is sufficient in the context of your original codes. Notice I did not use calloc or malloc in Coding 3 as I am just passing an address. Coding 1. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string1; char *string2 = some words\0; string1 = (char *)calloc(strlen(string2 + 1), sizeof (char)); strcpy(string1, string2); return string1; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } Coding 2. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string1; char *string2 = some words\0; string1 = malloc(strlen(string2)); strcpy(string1, string2); return string1; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } Coding 3. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string2 = some words; return string2; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } Hope this helps. O Plameras ashley maher wrote: G'day, I know this is not even C 101 level but would some kind soul please explain to me why this is not even close to working. Regards, Ashley #include stdio.h #include stdlib.h #include string.h int somefunction(char *string1) { char *string2 = some words\0; string1 = (char *)calloc(strlen(string2 + 1), sizeof (char)); strcpy(string1, string2); return 0; } int main () { char *string; somefunction(string); printf (\n\nString is: %s\n\n, string); free (string); return 0; } -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue Nov 22, 2005 at 16:16:29 +1100, O Plameras wrote: Hi ashley, I have three sets of codes that will do the task as I see it from your codes. I presented these three codes from the least to the most preferred coding. The common idea in all the three codes: 'somefunction' has static array of characters that is to be printed in 'main'; to accomplish this, just pass that address of the first character in a string to be printed. I changed the TYPE of 'somefunction' from 'int' to 'char *' to achieve this end. I used malloc instead of calloc in Coding 2. It is sufficient in the context of your original codes. Notice I did not use calloc or malloc in Coding 3 as I am just passing an address. Coding 1. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string1; char *string2 = some words\0; string1 = (char *)calloc(strlen(string2 + 1), sizeof (char)); Should be strlen(string2) + 1 strcpy(string1, string2); return string1; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } Coding 2. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string1; char *string2 = some words\0; string1 = malloc(strlen(string2)); Should be strlen(string2) + 1 strcpy(string1, string2); return string1; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } Moral of the story is don't code in C ;) Or if you do use as many tools to help you as possible. -Wall, and a C linter are a good start. Valgrind is also meant to be good, although I haven't used it. Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Benno wrote: On Tue Nov 22, 2005 at 16:16:29 +1100, O Plameras wrote: Hi ashley, I have three sets of codes that will do the task as I see it from your codes. I presented these three codes from the least to the most preferred coding. The common idea in all the three codes: 'somefunction' has static array of characters that is to be printed in 'main'; to accomplish this, just pass that address of the first character in a string to be printed. I changed the TYPE of 'somefunction' from 'int' to 'char *' to achieve this end. I used malloc instead of calloc in Coding 2. It is sufficient in the context of your original codes. Notice I did not use calloc or malloc in Coding 3 as I am just passing an address. Coding 1. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string1; char *string2 = some words\0; string1 = (char *)calloc(strlen(string2 + 1), sizeof (char)); Should be strlen(string2) + 1 Your are wrong. The string is some words\0. there is no need for extra char. strcpy(string1, string2); return string1; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } Coding 2. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string1; char *string2 = some words\0; string1 = malloc(strlen(string2)); Should be strlen(string2) + 1 Your are wrong. The string is some words\0. there is no need for extra char. strcpy(string1, string2); return string1; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } Moral of the story is don't code in C ;) Or if you do use as many tools to help you as possible. -Wall, and a C linter are a good start. Valgrind is also meant to be good, although I haven't used it. I don't understand this. Please explain. Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
U ... Coding 3. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string2 = some words; return string2; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } somefunction returns string2 which is trash! formally: The scope of string2 does not extend to main! (even if it works, and it might, it's WRONG) Moral of the story is don't code in C ;);) Or if you do use as many tools to help you as possible. -Wall, and a C linter are a good start. Valgrind is also meant to be good, although I haven't used it. If you're going to drive a sports car, learn to use the clutch! He's learning. For sleek and mean there is no better (than C), but it does require care and diciplin James -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
[EMAIL PROTECTED] wrote: U ... Coding 3. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string2 = some words; return string2; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } somefunction returns string2 which is trash! formally: The scope of string2 does not extend to main! (even if it works, and it might, it's WRONG) What are you talking about ? Tell me why it is trash. Moral of the story is don't code in C ;);) Or if you do use as many tools to help you as possible. -Wall, and a C linter are a good start. Valgrind is also meant to be good, although I haven't used it. If you're going to drive a sports car, learn to use the clutch! He's learning. For sleek and mean there is no better (than C), but it does require care and diciplin James -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
This one time, at band camp, O Plameras wrote: Benno wrote: On Tue Nov 22, 2005 at 16:16:29 +1100, O Plameras wrote: Hi ashley, I have three sets of codes that will do the task as I see it from your codes. I presented these three codes from the least to the most preferred coding. The common idea in all the three codes: 'somefunction' has static array of characters that is to be printed in 'main'; to accomplish this, just pass that address of the first character in a string to be printed. I changed the TYPE of 'somefunction' from 'int' to 'char *' to achieve this end. I used malloc instead of calloc in Coding 2. It is sufficient in the context of your original codes. Notice I did not use calloc or malloc in Coding 3 as I am just passing an address. Coding 1. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string1; char *string2 = some words\0; string1 = (char *)calloc(strlen(string2 + 1), sizeof (char)); Should be strlen(string2) + 1 Your are wrong. The string is some words\0. there is no need for extra char. How do you think strlen() works? Also, it's pretty clear you were writing this anyway, but typoed the placement of the closing parenthesis. Your are wrong. The string is some words\0. there is no need for extra char. Your jedi mind tricks do not work on me! Moral of the story is don't code in C ;) Or if you do use as many tools to help you as possible. -Wall, and a C linter are a good start. Valgrind is also meant to be good, although I haven't used it. I don't understand this. Please explain. Benno's talking about the buffer overruns caused by the incorrect pointer arithmetic in your examples. You can track them down with as many tools to help you as possible, e.g. gcc -Wall, valgrind. Or use pascal where the length of a string isn't determined by the position of the null :) -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue Nov 22, 2005 at 16:52:06 +1100, O Plameras wrote: Benno wrote: On Tue Nov 22, 2005 at 16:16:29 +1100, O Plameras wrote: Coding 1. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string1; char *string2 = some words\0; string1 = (char *)calloc(strlen(string2 + 1), sizeof (char)); Should be strlen(string2) + 1 Your are wrong. The string is some words\0. there is no need for extra char. I am right. You are wrong. I love this game. So, even if you were right about the extra \0 being counted, which you aren't, it would still not be long enough because you have: strlen(string2 + 1); not: strlen(string2) + 1; strcpy(string1, string2); return string1; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } Coding 2. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string1; char *string2 = some words\0; string1 = malloc(strlen(string2)); Should be strlen(string2) + 1 Your are wrong. The string is some words\0. there is no need for extra char. Bzzt. Wrong. C strings are NULL terminated. \0 is null. In memory you will have two NULL terminated, strlen is going to hit it first. Don't belive me? try strlen(A\0this doesn't count); It returns 1. In fact here is a whole program you can copy and compile to test the above: include stdio.h #include string.h #include assert.h int main(void) { char *s = pants\0; char *s2 = pants; printf(strlen(s) == %d\n, strlen(s)); printf(strlen(s2) == %d\n, strlen(s2)); printf(strlen(s) + 1 == %d\n, strlen(s) + 1); printf(strlen(s + 1) == %d\n, strlen(s + 1)); printf(strlen(\A\\0this doesn't count\) == %d\n, strlen(A\0this doesn't count)); assert(strlen(s) == strlen(s2)); } It outputs: strlen(s) == 5 strlen(s2) == 5 strlen(s) + 1 == 6 strlen(s + 1) == 4 strlen(A\0this doesn't count) == 1 strcpy(string1, string2); return string1; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } Moral of the story is don't code in C ;) Or if you do use as many tools to help you as possible. -Wall, and a C linter are a good start. Valgrind is also meant to be good, although I haven't used it. I don't understand this. Please explain. C is a very difficult programming language to program in and get right. (As seen in this thread). Programming errors in C are likely to lead to buggy unstable, insecure software. Therefore if you program in C you should try and get as much help from tools to ensure that what you have programmed is correct. Some of those tools are: 1/ Using the compilers warning system. 2/ Using something like valgrind to test for memory errors. 3/ Use a static analysis tool like splint. (Apart from that C is a very unproductive language to program in, so unless you really need it then use something higher level -- please!) Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue Nov 22, 2005 at 17:01:59 +1100, Jamie Wilkinson wrote: This one time, at band camp, O Plameras wrote: Benno wrote: Your are wrong. The string is some words\0. there is no need for extra char. How do you think strlen() works? Also, it's pretty clear you were writing this anyway, but typoed the placement of the closing parenthesis. Your are wrong. The string is some words\0. there is no need for extra char. Your jedi mind tricks do not work on me! Moral of the story is don't code in C ;) Or if you do use as many tools to help you as possible. -Wall, and a C linter are a good start. Valgrind is also meant to be good, although I haven't used it. I don't understand this. Please explain. Benno's talking about the buffer overruns caused by the incorrect pointer arithmetic in your examples. You can track them down with as many tools to help you as possible, e.g. gcc -Wall, valgrind. Or use pascal where the length of a string isn't determined by the position of the null :) So yeah, I was reading about pascal strings the other day. Pretty cool. Apparently Mac9 used them in its libraries. (Could easily be wrong there.) The idea is that the first byte of memory holds the length of the string. (Which limits you to a 256 length string.) But means operations strlen is O(1), not O(n). And something like strdup can avoid a double iteration through the list, and strcat can avoid trawling the first list. Etc, etc. If course declaring a string inline becomes a bit tricker: char *s = \005pants; And also standard C compiler will waste a byte NULL-terminating it even though you don't need to. So there is your trivia for the day. Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Jamie Wilkinson wrote: This one time, at band camp, O Plameras wrote: Benno wrote: On Tue Nov 22, 2005 at 16:16:29 +1100, O Plameras wrote: Hi ashley, I have three sets of codes that will do the task as I see it from your codes. I presented these three codes from the least to the most preferred coding. The common idea in all the three codes: 'somefunction' has static array of characters that is to be printed in 'main'; to accomplish this, just pass that address of the first character in a string to be printed. I changed the TYPE of 'somefunction' from 'int' to 'char *' to achieve this end. I used malloc instead of calloc in Coding 2. It is sufficient in the context of your original codes. Notice I did not use calloc or malloc in Coding 3 as I am just passing an address. Coding 1. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string1; char *string2 = some words\0; string1 = (char *)calloc(strlen(string2 + 1), sizeof (char)); Should be strlen(string2) + 1 Your are wrong. The string is some words\0. there is no need for extra char. How do you think strlen() works? Ok I checked 'man strlen()'. And it will not include the \0 in the count. My mistake. Also, it's pretty clear you were writing this anyway, but typoed the placement of the closing parenthesis. Your are wrong. The string is some words\0. there is no need for extra char. Your jedi mind tricks do not work on me! Moral of the story is don't code in C ;) Or if you do use as many tools to help you as possible. -Wall, and a C linter are a good start. Valgrind is also meant to be good, although I haven't used it. I don't understand this. Please explain. Benno's talking about the buffer overruns caused by the incorrect pointer arithmetic in your examples. You can track them down with as many tools to help you as possible, e.g. gcc -Wall, valgrind. Or use pascal where the length of a string isn't determined by the position of the null :) -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
This one time, at band camp, Benno wrote: So yeah, I was reading about pascal strings the other day. Pretty cool. Apparently Mac9 used them in its libraries. (Could easily be wrong there.) The idea is that the first byte of memory holds the length of the string. (Which limits you to a 256 length string.) But means operations strlen is O(1), not O(n). And something like strdup can avoid a double iteration through the list, and strcat can avoid trawling the first list. Etc, etc. If course declaring a string inline becomes a bit tricker: char *s = \005pants; And also standard C compiler will waste a byte NULL-terminating it even though you don't need to. So there is your trivia for the day. Also limits you to 255 char length strings, at least back in the day Borland Pascal did... -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue Nov 22, 2005 at 13:51:59 +0800, [EMAIL PROTECTED] wrote: U ... Coding 3. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string2 = some words; return string2; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } somefunction returns string2 which is trash! formally: The scope of string2 does not extend to main! (even if it works, and it might, it's WRONG) some words will be allocated in the .rodata section not on the stack so it will actually work. (Not that I'd recommend doing this!!). I can't find anything in the C spec about return the address of a string literal, it doesn't say wether it is allowed or not. If course if the code was: char * somefunction() { char string2[] = some words; return string2; } That would definately be wrong (and would sometimes work ;). Gcc warns about this, but not the above in gcc -Wall. (Not that that means anything..) To see exactly how it dies try this: int main(void) { char *s = foo(); char *d; d = alloca(37); /* Allocate stuff on the stack -- will trash somefunction return */ strcpy(d, foo bar baz blerg ); printf(s: %s\n, s); return 0; } Whereas as with the orginal somefunction this would work. Moral of the story is don't code in C ;);) Or if you do use as many tools to help you as possible. -Wall, and a C linter are a good start. Valgrind is also meant to be good, although I haven't used it. If you're going to drive a sports car, learn to use the clutch! He's learning. For sleek and mean there is no better (than C), but it does require care and diciplin Well there is assembler ;) But there is definately times when using C is a good idea, it is just easy to fuck up. Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Benno wrote: On Tue Nov 22, 2005 at 16:52:06 +1100, O Plameras wrote: Benno wrote: On Tue Nov 22, 2005 at 16:16:29 +1100, O Plameras wrote: Coding 1. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string1; char *string2 = some words\0; string1 = (char *)calloc(strlen(string2 + 1), sizeof (char)); Should be strlen(string2) + 1 Your are wrong. The string is some words\0. there is no need for extra char. I am right. You are wrong. I love this game. So, even if you were right about the extra \0 being counted, which you aren't, it would still not be long enough because you have: strlen(string2 + 1); not: strlen(string2) + 1; strcpy(string1, string2); return string1; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } Coding 2. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string1; char *string2 = some words\0; string1 = malloc(strlen(string2)); Should be strlen(string2) + 1 Your are wrong. The string is some words\0. there is no need for extra char. Bzzt. Wrong. C strings are NULL terminated. \0 is null. In memory you will have two NULL terminated, strlen is going to hit it first. Don't belive me? try strlen(A\0this doesn't count); It returns 1. In fact here is a whole program you can copy and compile to test the above: include stdio.h #include string.h #include assert.h int main(void) { char *s = pants\0; char *s2 = pants; printf(strlen(s) == %d\n, strlen(s)); printf(strlen(s2) == %d\n, strlen(s2)); printf(strlen(s) + 1 == %d\n, strlen(s) + 1); printf(strlen(s + 1) == %d\n, strlen(s + 1)); printf(strlen(\A\\0this doesn't count\) == %d\n, strlen(A\0this doesn't count)); assert(strlen(s) == strlen(s2)); } It outputs: strlen(s) == 5 strlen(s2) == 5 strlen(s) + 1 == 6 strlen(s + 1) == 4 strlen(A\0this doesn't count) == 1 strcpy(string1, string2); return string1; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } Moral of the story is don't code in C ;) Or if you do use as many tools to help you as possible. -Wall, and a C linter are a good start. Valgrind is also meant to be good, although I haven't used it. I don't understand this. Please explain. C is a very difficult programming language to program in and get right. (As seen in this thread). Programming errors in C are likely to lead to buggy unstable, insecure software. Therefore if you program in C you should try and get as much help from tools to ensure that what you have programmed is correct. Some of those tools are: I don't find C difficult at all. C has one of the least number of vocabularies to learn and master. If you understand pointers and pointer arithmetic you have the right stuff. So, learn pointers and pointer arithmetic. C is extremely good because many OSes and Compilers are written in C including Linux itself and many tools in Linux. Open Source is notoriously lacking in documentations. Unless you know C you are lost and you hardly can't proceed if you are doing a project. So, my advise to newbies in Linux, forget about people that discourages you from writing in C language. Use C and you will quickly realise the real beauty and opportunities of Open Source. It gives you more freedom and independence. The object of programming is to get what you want in a simple and easy to understand programming. That's why my preferred the solution is #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string2 = some words; return string2; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } This is tremendously simpler than what you have proposed, as ff: int somefunction(char **string1) { /* a function that takes a pointer to a pointer to memory */ char *string2 = some words; *string1 = malloc(strlen(string2) + 1); /* allocate memory and assign it to the char pointer, to which string1 points to. Known as dereferencing. */ if ((*string1) == NULL) /*SHould at least check return value! */ return -1; strcpy(*string1, string2); /* Copy the string */ return 0; } int main(void) { char * string; int r; r = somefunction(string); /* Pass the address of string to somefunction */ if (r != 0) { fprintf(stderr, Couldn't allocate memory\n); return 1; } /* now we know that string actually points somewhere */ printf(String is %s\n, string); free(string); return 0; } I am discouraged by simply looking at these codes much more bother to read it. The
Re: [SLUG] C Gurus
On Tue Nov 22, 2005 at 17:35:23 +1100, Benno wrote: On Tue Nov 22, 2005 at 13:51:59 +0800, [EMAIL PROTECTED] wrote: U ... Coding 3. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string2 = some words; return string2; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } somefunction returns string2 which is trash! formally: The scope of string2 does not extend to main! (even if it works, and it might, it's WRONG) some words will be allocated in the .rodata section not on the stack so it will actually work. (Not that I'd recommend doing this!!). I can't find anything in the C spec about return the address of a string literal, it doesn't say wether it is allowed or not. I can't actually find it in the C spec but from googling it does appear that string literals are constants with static storage duration which means they have lifetime of the program. (But I still wouldn't use that style, it is confusing at best.) Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
This one time, at band camp, O Plameras wrote: (Apart from that C is a very unproductive language to program in, so unless you really need it then use something higher level -- please!) I disagree with this. There are lots of things I can do with C that cannot be done with other high level languages easily. Yeah, set theory, matrix algebra, all of these are much easier to describe in C than, say, Python. :) -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
[EMAIL PROTECTED] wrote: U ... Coding 3. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string2 = some words; return string2; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } somefunction returns string2 which is trash! formally: The scope of string2 does not extend to main! string2 is the return value of char * somefunction which is extern ( or GLOBAL). (even if it works, and it might, it's WRONG) Moral of the story is don't code in C ;);) Or if you do use as many tools to help you as possible. -Wall, and a C linter are a good start. Valgrind is also meant to be good, although I haven't used it. If you're going to drive a sports car, learn to use the clutch! He's learning. For sleek and mean there is no better (than C), but it does require care and diciplin This is totally trivial. What has driving sportscar to do with coding in C ? What sportscar do you drive ? James -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Benno wrote: On Tue Nov 22, 2005 at 17:35:23 +1100, Benno wrote: On Tue Nov 22, 2005 at 13:51:59 +0800, [EMAIL PROTECTED] wrote: U ... Coding 3. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string2 = some words; return string2; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } somefunction returns string2 which is trash! formally: The scope of string2 does not extend to main! (even if it works, and it might, it's WRONG) some words will be allocated in the .rodata section not on the stack so it will actually work. (Not that I'd recommend doing this!!). I can't find anything in the C spec about return the address of a string literal, it doesn't say wether it is allowed or not. I can't actually find it in the C spec but from googling it does appear that string literals are constants with static storage duration which means they have lifetime of the program. (But I still wouldn't use that style, it is confusing at best.) Try compiling my codes with '-g' and run 'gdb'. Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue Nov 22, 2005 at 17:43:49 +1100, O Plameras wrote: Benno wrote: On Tue Nov 22, 2005 at 16:52:06 +1100, O Plameras wrote: C is a very difficult programming language to program in and get right. (As seen in this thread). Programming errors in C are likely to lead to buggy unstable, insecure software. Therefore if you program in C you should try and get as much help from tools to ensure that what you have programmed is correct. Some of those tools are: I don't find C difficult at all. ... but you still didn't know how strings work. C has one of the least number of vocabularies to learn and master. Yep that is true. If you understand pointers and pointer arithmetic you have the right stuff. So, learn pointers and pointer arithmetic. pointers and pointer arithmetic are very difficult concepts for people to learn. They are important things to learn, but most people find them difficult. C is extremely good because many OSes and Compilers are written in C including Linux itself and many tools in Linux. I would say C is good despite that ;). I never said C is bad, I said it was difficult to program in well. Open Source is notoriously lacking in documentations. Unless you know C you are lost and you hardly can't proceed if you are doing a project. That is simply untrue. There are many projects written purely in python, perl,ocaml,haskell,java. So, my advise to newbies in Linux, forget about people that discourages you from writing in C language. Use C and you will quickly realise the real beauty and opportunities of Open Source. It gives you more freedom and independence. Hey, I agree. Learn it, and then learn when to use it and when to use a higher level language. The object of programming is to get what you want in a simple and easy to understand programming. Sure, that is why I prefer higher-level languages that provide more abstraction. That's why my preferred the solution is snip function that returns a pointer to a stack This is tremendously simpler than what you have proposed, as ff: snip my previous solution I wasn't attempting to have something simpler, I was try to give him what I'm thinking he was trying to do, but I'm not a mind reader. I assumed that there was some reason for the given structuring. Hell if I wanted to give him the simplist solution to print out a string it would have been: #include stdio.h int main(void) { puts(Some string\n); } I am discouraged by simply looking at these codes much more bother to read it. Well, that is sad. The trouble other programmers have with C is that they make their codes complicated than it should. That is possible. With any language really knowing it means, knowing the simplest and most clear way to achieve what you want. 1/ Using the compilers warning system. 2/ Using something like valgrind to test for memory errors. 3/ Use a static analysis tool like splint. (Apart from that C is a very unproductive language to program in, so unless you really need it then use something higher level -- please!) I disagree with this. There are lots of things I can do with C that cannot be done with other high level languages easily. Sure, and that is why I said unless you really need to. For example lets say you have some data in a file. With the format: Label: number And you want the average of those numbers. Writing that in python takes about 10 lines of code and about 1 minute, and you usually get it right first time. Writing that in C with the standard library is not so simple. And if that is too contrived think about large complex open source problems like revision control and how most of the latest ones are written in high level languages. Because really, speed of the processor isn't an issue here, but good algorithms are. And I challenge anyone to write a doubly linked list right the first time. Anyway, you can write good stuff in C, but really, unless computation speed is the issue you would do much better to write it in a higher level language where you can spend time refining algorithms not worrying about memory management. (And really C sucks for device drivers and low level stuff too now I think about it, its not as though C has a way to access x86 style ports, and its not as though its structs are tightly defined enough so you can just use them to describe device memory layouts, although people do and rely on how the compiler works.) Cheers, Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue Nov 22, 2005 at 17:53:16 +1100, O Plameras wrote: Benno wrote: On Tue Nov 22, 2005 at 17:35:23 +1100, Benno wrote: On Tue Nov 22, 2005 at 13:51:59 +0800, [EMAIL PROTECTED] wrote: U ... Coding 3. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string2 = some words; return string2; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } somefunction returns string2 which is trash! formally: The scope of string2 does not extend to main! (even if it works, and it might, it's WRONG) some words will be allocated in the .rodata section not on the stack so it will actually work. (Not that I'd recommend doing this!!). I can't find anything in the C spec about return the address of a string literal, it doesn't say wether it is allowed or not. I can't actually find it in the C spec but from googling it does appear that string literals are constants with static storage duration which means they have lifetime of the program. (But I still wouldn't use that style, it is confusing at best.) Try compiling my codes with '-g' and run 'gdb'. Umm? And ?? What is it meant to show me? I've already said that a string literal is place in the rodata section in every compiler I've used, so I know what the implementation does. But what the implementation does and what the spec says are two widly different things. Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue Nov 22, 2005 at 17:51:38 +1100, O Plameras wrote: [EMAIL PROTECTED] wrote: U ... Coding 3. #include stdio.h #include stdlib.h #include string.h char * somefunction() { char *string2 = some words; return string2; } int main (void) { char *string; string = somefunction(); printf (\n\nString is: %s\n\n, string); return 0; } somefunction returns string2 which is trash! formally: The scope of string2 does not extend to main! string2 is the return value of char * somefunction which is extern ( or GLOBAL). Sure, but the scope of string2 is local to somefunction. The thing is string2 is only a pointer, it isn't the actual memory. The function could have also been written with perhaps less confusion as: char *somefunction() { return some words; } The reason I don't like this style is that presumably somefunction() will in the future actually *do something* to generate a string. And then simply returning something like this no longer works -- you need to allocate something on the heap. And then it changes the interface you have with the client, because currently they are not allowed to free() what is returned. (And on any decent OS should actually crash, because writing to rodata shouldn't be allowe). However once you alloc then the interface becomes subtly differnt because the client must free() or else leave a memory leak. Which is bad for any long running process. And of course if somefunction() has to return some error code, not just the string you also need to get more trickier with pointers, and end up with what I had before. *but*, having any interface where you allocate data inside a function and expect to free is elsewhere is genreally bad, because it is too easy to screw up, and forget the free, probably better to supply a buffer if possible (with a length of course). Of course that means having some expection of the size required in the first place. (Can people start to see why I say doing C right is difficult??) If somefunction is really constant you might as well refactor as: const char somewords[] = some words; and avoid the confusion. Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue Nov 22, 2005 at 17:50:42 +1100, Jamie Wilkinson wrote: This one time, at band camp, O Plameras wrote: (Apart from that C is a very unproductive language to program in, so unless you really need it then use something higher level -- please!) I disagree with this. There are lots of things I can do with C that cannot be done with other high level languages easily. Yeah, set theory, matrix algebra, all of these are much easier to describe in C than, say, Python. :) Database querying, website generation, accounting software... it should be pointed out that finding better languages than C for operating system implementation is an active research area, as are hardcore static analysis tools to make sure your code is right, and doesn't contain the really subtle bugs seen in the code snippets posted today. -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Benno wrote: pointers and pointer arithmetic are very difficult concepts for people to learn. They are important things to learn, but most people find them difficult. They are also very easy to get wrong as this thread has shown. Erik -- +---+ Erik de Castro Lopo +---+ Working with Perforce in my day job makes me really appreciate just how good GNU Arch is. -- Erik de Castro Lopo -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
On Tue Nov 22, 2005 at 18:38:25 +1100, Erik de Castro Lopo wrote: Benno wrote: pointers and pointer arithmetic are very difficult concepts for people to learn. They are important things to learn, but most people find them difficult. They are also very easy to get wrong as this thread has shown. Right, which is why tools like -Wall -Werror, splint and valgrind come ine. Do you think I've mentioned -Wall -Werror enough this thread? Probably not, one more time, if you must use C, use -Wall -Werror. Benno -- SLUG - Sydney Linux User's Group Mailing List - http://slug.org.au/ Subscription info and FAQs: http://slug.org.au/faq/mailinglists.html
Re: [SLUG] C Gurus
Benno wrote: On Tue Nov 22, 2005 at 17:43:49 +1100, O Plameras wrote: Benno wrote: On Tue Nov 22, 2005 at 16:52:06 +1100, O Plameras wrote: C is a very difficult programming language to program in and get right. (As seen in this thread). Programming errors in C are likely to lead to buggy unstable, insecure software. Therefore if you program in C you should try and get as much help from tools to ensure that what you have programmed is correct. Some of those tools are: I don't find C difficult at all. ... but you still didn't know how strings work. C has one of the least number of vocabularies to learn and master. Yep that is true. If you understand pointers and pointer arithmetic you have the right stuff. So, learn pointers and pointer arithmetic. pointers and pointer arithmetic are very difficult concepts for people to learn. They are important things to learn, but most people find them difficult. The problem with this statement is you generalize your point as if it is written in stone for most people to put into their heads, which is wrong. Many newbies out there are smarter than you think and given the right encouragement they will be able to learn about Linux in particular and Open Source in general quicker than you and me have. Some people find it difficult to conceptualize pointers and pointer arithmetic which includes yourself I suppose because you kept on saying these are difficult to learn. You keep on telling yourself it is extremely difficult; and it is extremely hard. The reality of it all is anyone can learn C in one day and master it in one week. By this I mean, after one week anyone will be able to read anyone's C code provided it is written correctly. C is extremely good because many OSes and Compilers are written in C including Linux itself and many tools in Linux. I would say C is good despite that ;). I never said C is bad, I said it was difficult to program in well. It is your mental attitude that makes you believe it is difficult. Open Source is notoriously lacking in documentations. Unless you know C you are lost and you hardly can't proceed if you are doing a project. That is simply untrue. There are many projects written purely in python, perl,ocaml,haskell,java. Try writing a PHP module in these languages. So, my advise to newbies in Linux, forget about people that discourages you from writing in C language. Use C and you will quickly realise the real beauty and opportunities of Open Source. It gives you more freedom and independence. Hey, I agree. Learn it, and then learn when to use it and when to use a higher level language. The object of programming is to get what you want in a simple and easy to understand programming. Sure, that is why I prefer higher-level languages that provide more abstraction. That's why my preferred the solution is snip function that returns a pointer to a stack This is tremendously simpler than what you have proposed, as ff: snip my previous solution I wasn't attempting to have something simpler, I was try to give him what I'm thinking he was trying to do, but I'm not a mind reader. I assumed that there was some reason for the given structuring. Hell if I wanted to give him the simplist solution to print out a string it would have been: #include stdio.h int main(void) { puts(Some string\n); } He was trying to print a string initialised from a function other than function main. I am discouraged by simply looking at these codes much more bother to read it. Well, that is sad. The trouble other programmers have with C is that they make their codes complicated than it should. That is possible. With any language really knowing it means, knowing the simplest and most clear way to achieve what you want. 1/ Using the compilers warning system. 2/ Using something like valgrind to test for memory errors. 3/ Use a static analysis tool like splint. (Apart from that C is a very unproductive language to program in, so unless you really need it then use something higher level -- please!) I disagree with this. There are lots of things I can do with C that cannot be done with other high level languages easily. Sure, and that is why I said unless you really need to. For example lets say you have some data in a file. With the format: Label: number And you want the average of those numbers. Writing that in python takes about 10 lines of code and about 1 minute, and you usually get it right first time. Writing that in C with the standard library is not so simple. And if that is too contrived think about large complex open source problems like revision control and how most of the latest ones are written in high level languages. Because really, speed of the processor isn't an issue here, but good algorithms are.