Re: [DNG] Icerbergs aren't small just because they're mostly underwater
On Mon, Jan 25, 2016 at 10:41:38PM +, Rainer Weikusat wrote: [cut] > > But the loop in > > static char const *get_name(char const *arg0) > { > char const *n, *r; > > n = r = arg0; > while (*r) if (*r++ == '/') n = r; > return n; > } > > is not of this type. It contains an init-statement, ^^^ Any for-loop has an equivalent while-loop, and vice-versa, meaning that there is no a "type" of loop that can be expressed in a for and cannot be expressed in an equivalent while, or vice-versa. Your loop above is in all equivalent to: for(n=r=arg0; *r; r++) if (*r =='/') n=r+1; return n; so I don't understand your statement. Maybe I misinterpreted the whole discussion, but really there is no difference whatsoever between for and while, to the point that some more orthogonal languages have only one of the two constructs. HND KatolaZ -- [ Enzo Nicosia aka KatolaZ --- GLUG Catania -- Freaknet Medialab ] [ me [at] katolaz.homeunix.net -- http://katolaz.homeunix.net -- ] [ GNU/Linux User:#325780/ICQ UIN: #258332181/GPG key ID 0B5F062F ] [ Fingerprint: 8E59 D6AA 445E FDB4 A153 3D5A 5F20 B3AE 0B5F 062F ] ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater
Peter Olsonwrites: >> On January 25, 2016 at 5:54 PM Rainer Weikusat >> wrote: > > [...] > >> A related but IMHO more interesting set of questions could be: >> >> 1. Should every trivial crap $someone ever implemented since 1978 end up >>in general purpose library just because $someone happend to have to >>power to put it into it? >> >> 2. Should people be required to memoize every trivial crap $someone ever >>implemented since 1978 just because that someone happened to have to >>power to ...? >> >> 3. Should people who consider themselves Very Superior Entities because >>the have memoized every trivial crap $someone ever ... and so on, be >>taken as seriously as they continuously demand? > > It must be trivial crap because nobody ever made a programming error parsing > path names when they rolled their own routines for it. It's trivial because its about 3 or 4 lines of code, at least for a reasonable implementation. That's a property of the code and not one of hypothetical people who could be writing code. Eg, in order to write code, one has to learn to write first and this is anything but trivial as it needs years of practice. > Also: Windows and Mac path names follow different rules. The (fairly recently introduced) BSD basename library function (whose semantics are quite different from the semantics of the one I posted) doesn't deal with anything but UNIX(*) pathnames. Programs I write as part of my slowly growing set of "tools usable for starting/ manageing processes" certainly don't have to deal with "Windows and Mac path names", either. > Use the libraries. "Use libraries insofar you consider them useful." And a library implementation of 'basename' is not something I'd consider useful, especially when using it portably would require more code than not using it (the string would need to be copied, including handling errors in that, and the result would need to be copied, including handling errors in that, and all the weird special cases someone considered sensible would need to be dealt with one by one in order to achieve what I wanted to achieve and even then, there'd be differences). YMMV. ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater
KatolaZwrites: > On Mon, Jan 25, 2016 at 05:44:11PM -0500, Peter Olson wrote: > > [cut] > >> >> This also brings up the question of whether you should roll your own >> get_name or >> use basename(3) which already does the same thing except in some edge cases. >> It's easier for the student to understand the code if it is implemented as >> get_name, but the student ought to learn about dirname and basename pretty >> early >> in their study. > > Apart from students' interest, the Unix phylosophy is all about > designing simple, orthogonal, robust components and functions that can > be reused and combined together to accomplish tasks unforseen to their > initial developer. Unix is not about reinventing the wheel every > single day. There's indeed something whose 'philosophy' is based on assembling complex constructions from more-or-less unfit-for-purpose components which happen to be available in order to solve seemingly not-so-difficult problems by creative ingenuitity but it's not called UNIX(*). https://en.wikipedia.org/wiki/The_Incredible_Machine_%28series%29 [SCNR] ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater
> On January 26, 2016 at 2:30 PM Rainer Weikusat >wrote: > > Peter Olson writes: > >> On January 25, 2016 at 5:54 PM Rainer Weikusat > >> wrote: > > > > [...] > > > >> A related but IMHO more interesting set of questions could be: > > [..] > > > It must be trivial crap because nobody ever made a programming error parsing > > path names when they rolled their own routines for it. > > It's trivial because its about 3 or 4 lines of code, at least for a > reasonable implementation. That's a property of the code and not one of > hypothetical people who could be writing code. Eg, in order to write > code, one has to learn to write first and this is anything but trivial > as it needs years of practice. > > > Also: Windows and Mac path names follow different rules. > > The (fairly recently introduced) BSD basename library function (whose > semantics > are quite different > from the semantics of the one I posted) > doesn't deal with anything but UNIX(*) pathnames. How quite different? I just looked at Windows implementation of basename and note that it avoids the ".ext" of the file. Thanks, Windows :-) > Programs I write as part of my slowly growing set of "tools usable for > starting/ manageing processes" certainly don't have to deal with > "Windows and Mac path names", either. I try to avoid non-UNIX(*) environments as well, but if I am serious about free software I should take portability into account where I can. > > Use the libraries. > > "Use libraries insofar you consider them useful." And a library > implementation of 'basename' is not something I'd consider useful, > especially when using it portably would require more code than not using > it (the string would need to be copied, including handling errors in > that, and the result would need to be copied, including handling errors > in that, and all the weird special cases someone considered sensible > would need to be dealt with one by one in order to achieve what I wanted > to achieve and even then, there'd be differences). This patch illustrates the rathole of compatibility across OS implementations: https://lists.gnu.org/archive/html/guile-devel/2014-07/msg00012.html > it (the string would need to be copied, including handling errors in Living on the edge? Most parsing of path names occurs at main(), but I hope you won't run out of memory in the middle of a long job. After all, alloca always works :-; Peter Olson ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater
Peter Olsonwrites: [...] >> it (the string would need to be copied, including handling errors in > > Living on the edge? The standardized definition of the function requests that unless one is happy with the original string being changed. ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater (was: "Common knowledge?"-question)
On Mon, Jan 25, 2016 at 05:44:11PM -0500, Peter Olson wrote: [cut] > > This also brings up the question of whether you should roll your own get_name > or > use basename(3) which already does the same thing except in some edge cases. > It's easier for the student to understand the code if it is implemented as > get_name, but the student ought to learn about dirname and basename pretty > early > in their study. Apart from students' interest, the Unix phylosophy is all about designing simple, orthogonal, robust components and functions that can be reused and combined together to accomplish tasks unforseen to their initial developer. Unix is not about reinventing the wheel every single day. HND KatolaZ -- [ Enzo Nicosia aka KatolaZ --- GLUG Catania -- Freaknet Medialab ] [ me [at] katolaz.homeunix.net -- http://katolaz.homeunix.net -- ] [ GNU/Linux User:#325780/ICQ UIN: #258332181/GPG key ID 0B5F062F ] [ Fingerprint: 8E59 D6AA 445E FDB4 A153 3D5A 5F20 B3AE 0B5F 062F ] ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater
> On January 25, 2016 at 5:54 PM Rainer Weikusat >wrote: [...] > A related but IMHO more interesting set of questions could be: > > 1. Should every trivial crap $someone ever implemented since 1978 end up >in general purpose library just because $someone happend to have to >power to put it into it? > > 2. Should people be required to memoize every trivial crap $someone ever >implemented since 1978 just because that someone happened to have to >power to ...? > > 3. Should people who consider themselves Very Superior Entities because >the have memoized every trivial crap $someone ever ... and so on, be >taken as seriously as they continuously demand? It must be trivial crap because nobody ever made a programming error parsing path names when they rolled their own routines for it. Also: Windows and Mac path names follow different rules. Use the libraries. I actually like the example of Python's os.path library, which implements a unified set of portable routines for manipulating path names. Peter Olson Off topic P.S.: memoize means something different from memorize, which you clearly meant. ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater (was: "Common knowledge?"-question)
On Mon, Jan 25, 2016 at 12:23:01PM +, Rainer Weikusat wrote: > KatolaZwrites: > > [...] > > > I still don't see the need for an internal buffer to print out a > > formatted string, to be honest :) > > Everything in code can always be implemented in a number of different > ways, hence, whatever the code ends up doing is "not really needed" --- > it could have achieved the same in a different way. > > In this case, the function is part of a 79 lines program whose main > looks like this: > > int main(int argc, char **argv) > { > char const *name; > int status; > > name = get_name(*argv); > openlog(name, LOG_PID | LOG_PERROR, LOG_DAEMON); > if (argc < 3) usage(); > > print_start(name, argv[1]); > > switch (fork()) { > case -1: > die(__func__, "fork"); > > case 0: > execvp(argv[2], argv + 2); > > syslog(LOG_ERR, "main: execvp: %m(%d)", errno); > _exit(1); > } > > wait(); > print_stop(status); > > return 0; > } > > and whose purpose is to enable me to write > > starting "unleashed VPN" \ > daemon -n chdir / monitor -n qvpn ssh-vpn mes-pgsql 5000 unleashed > unleashed4 > > in an init script to get a 'start: ok (or failed)' message printed to > file descriptor 2 with having to put two printf invocation around the > start command. And in the context of that, using stdio for the sole > purpose of performing a trivial string formatting operation seemed very > inappropriate --- that's new-fangled, ill-thought out stuff supposed to > make UNIX(*) easier to use by moron^WUCB students and who really needs > that? I did not dispute your preference for not using stdio, but the choice to copy strings into internal buffers just to change one character and spit them on stdout. And in fact my 6-lines proposal for doing exactly the same was: void another_print_start(char *name, char *what){ char c[3] = " :"; c[2] = name[0] & ~0x20; write(2, c+2, 1); write(2, name+1, strlen(name) -1); write(2, c, 2); write(2, what, strlen(what)); } You asked for comments, I commented that alloca was probably not needed and potentially dangerous, and that you could achieve the same with simpler code, but apparently you didn't like the comment :D > > The program also contains a very nice example of why the post-increment > operators is useful (and I means 'useful', not 'common because of > mindless copying of example code'): > > static char const *get_name(char const *arg0) > { > char const *n, *r; > > n = r = arg0; > while (*r) if (*r++ == '/') n = r; > return n; > } That's pretty straight-forward C-programming, IMHO, but I agree that it could be seen as interesting by a mor^H^H^Hstudent who approaches C for the first time. Peace, love and hacking. KatolaZ -- [ Enzo Nicosia aka KatolaZ --- GLUG Catania -- Freaknet Medialab ] [ me [at] katolaz.homeunix.net -- http://katolaz.homeunix.net -- ] [ GNU/Linux User:#325780/ICQ UIN: #258332181/GPG key ID 0B5F062F ] [ Fingerprint: 8E59 D6AA 445E FDB4 A153 3D5A 5F20 B3AE 0B5F 062F ] ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater
On Mon, Jan 25, 2016 at 01:47:46PM +0100, Didier Kryn wrote: > Le 25/01/2016 13:23, Rainer Weikusat a écrit : > > while (*r) if (*r++ == '/') n = r; > > Does it mean > > while (*r) > { > if (*r == '/') > { >n = r; >r++; > } > } > > or > > while (*r) > { > if (*r == '/') > { >r++; >n = r; > } > } Neither. The incrementation in the original is not condiitional on the rquality test. Which means that in the original, n gets assigned the address of the character *after* the last '/' found. In the other versions you get an infinite loop as soon as you encounter a character that isn't '/'. -- hendrik > > > I think the second answer is the good one. It is more readable > and less error-prone than your example and the compiler will produce > exactly the same instructions. You don't need to do the work of the > compiler; it does it better. Better concentrate on writing programs > easier to read and less error-prone. These pre-increment and > post-increment instructions should be deprecated - I already > advocated that on this list, although it is not the place :-) > > The reason why seasonned programmers prefer the kind of > expression you wrote, with post-increment, is a perfect example of a > style dictated by pure aesthetics. This an error I used to make when > I was younger, but, with age and learning, I have found true reasons > to do otherwise. > > Didier > > Didier > > ___ > Dng mailing list > Dng@lists.dyne.org > https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater
Le 25/01/2016 13:23, Rainer Weikusat a écrit : while (*r) if (*r++ == '/') n = r; Does it mean while (*r) { if (*r == '/') { n = r; r++; } } or while (*r) { if (*r == '/') { r++; n = r; } } I think the second answer is the good one. It is more readable and less error-prone than your example and the compiler will produce exactly the same instructions. You don't need to do the work of the compiler; it does it better. Better concentrate on writing programs easier to read and less error-prone. These pre-increment and post-increment instructions should be deprecated - I already advocated that on this list, although it is not the place :-) The reason why seasonned programmers prefer the kind of expression you wrote, with post-increment, is a perfect example of a style dictated by pure aesthetics. This an error I used to make when I was younger, but, with age and learning, I have found true reasons to do otherwise. Didier Didier ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater
Le 25/01/2016 13:47, Didier Kryn a écrit : while (*r) { if (*r == '/') { r++; n = r; } } It's not even that. A for loop would do it: for ( ; *r; r++ ) n = r+1; ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater
Didier Kryn: > Le 25/01/2016 13:23, Rainer Weikusat a écrit : > > while (*r) if (*r++ == '/') n = r; > > Does it mean > > while (*r) >{ > if (*r == '/') > { > n = r; > r++; > } >} > > or > > while (*r) >{ > if (*r == '/') > { > r++; > n = r; > } >} > > > I think the second answer is the good one. It is more readable and > less error-prone than your example and the compiler will produce exactly > the same instructions. You don't need to do the work of the compiler; it > does it better. Better concentrate on writing programs easier to read > and less error-prone. These pre-increment and post-increment > instructions should be deprecated - I already advocated that on this > list, although it is not the place :-) > > The reason why seasonned programmers prefer the kind of expression > you wrote, with post-increment, is a perfect example of a style dictated > by pure aesthetics. This an error I used to make when I was younger, > but, with age and learning, I have found true reasons to do otherwise. Uhh. I do prefer the short version, it should be perfectly understandable to anyone versed in c. I do prefer code to not to spread out onto mult. lines as your example does, since the shorter version make it easier to see the whole surronding function, and that aids the understanding. Inserting pairs of {}'s makes things less prone to questions about what goes where, but there is no need to state the obvious, and inserting more whitespace than necessary does not help. Putting things that are closely related close and as in this case in one line, makes it easier to mentally think "basename" and move on. /// I have written a similar thing myself cmdline_pgm = strrchr(argv[0], '/'); if (cmdline_pgm == NULL) cmdline_pgm = argv[0]; else cmdline_pgm++; It worked and I moved on. Should I do it again, I'd consider Rainers code. /// As for Rainers original question, his code is pretty understandable for me except for the "&= 0x20", which forced me to think. Regards, /Karl Hammar --- Aspö Data Lilla Aspö 148 S-742 94 Östhammar Sweden +46 173 140 57 ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater
Didier Krynwrites: > Le 25/01/2016 13:23, Rainer Weikusat a écrit : >> while (*r) if (*r++ == '/') n = r; > > Does it mean > > while (*r) > { > if (*r == '/') > { >n = r; >r++; > } > } > > or > > while (*r) > { > if (*r == '/') > { >r++; >n = r; > } > } > > > I think the second answer is the good one. It is more readable and > less error-prone than your example and ... doesn't work. r (for 'running pointer') needs to be incremented on every iteration until it hits the end of the string. In case it currently pointed to a '/', 'n' ('pointer to [start of] name') needs to be set to the char behind the slash. As soons as *r == 0 aka !*r, n will point to the char after the last slash in the original string, ie, to the program name part of a program pathname. This is even already 'optimized for simplicity' as gcc will (usually) issue code to reload the char r points and thus, if this was supposed 'optimized', it really ought to be something like (all untested) char const *r, *n; int c; n = r = arg0; while (c = *r++) if (c == '/') n = r; A multi-line version could look like this: while (c = *r) { ++r; if (c == '/') n = r; } Or, for people who think everything ought to be expressed as for-loop because everything can be expressed as for-loop, char const *r, *n; int c0, c1; for (n = r = arg0, c1 = 0; c0 = *r; r++) { if (c1 == '/') n = r; c1 = c0; } This is a nice progression from '[maybe unusal but] straight-forward' to 'conventional [& contorted]'. ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater
Le 25/01/2016 16:08, Rainer Weikusat a écrit : Didier Krynwrites: Le 25/01/2016 13:23, Rainer Weikusat a écrit : while (*r) if (*r++ == '/') n = r; Does it mean while (*r) { if (*r == '/') { n = r; r++; } } or while (*r) { if (*r == '/') { r++; n = r; } } I think the second answer is the good one. It is more readable and less error-prone than your example and ... doesn't work. r (for 'running pointer') needs to be incremented on every iteration until it hits the end of the string. In case it currently pointed to a '/', 'n' ('pointer to [start of] name') needs to be set to the char behind the slash. As soons as *r == 0 aka !*r, n will point to the char after the last slash in the original string, ie, to the program name part of a program pathname. This is even already 'optimized for simplicity' as gcc will (usually) issue code to reload the char r points and thus, if this was supposed 'optimized', it really ought to be something like (all untested) char const *r, *n; int c; n = r = arg0; while (c = *r++) if (c == '/') n = r; A multi-line version could look like this: while (c = *r) { ++r; if (c == '/') n = r; } It might be done with a for loop. eg: for ( ; *r ; ++r) if(*r=='/') n=r; n++; The for loop is the best construct for a loop with an incremental cursor. While is rather meant for things like while ( (c=fgets(s, sizeof(s), stdin) ) At the end of the day, there are many ways to write even simple things :-) Didier ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater
Didier Krynwrites: [...] >> A multi-line version could look like this: >> >> while (c = *r) { >> ++r; >> if (c == '/') n = r; >> } >> > > It might be done with a for loop. eg: > > for ( ; *r ; ++r) if(*r=='/') n=r; > n++; [...] > The for loop is the best construct for a loop with an incremental > cursor. That's nicely exemplified by the fact that the code above does a redundant increment (or did a redundant increment would it work, the {} are missing) solely to work around the fact that the "for loop mechanics" of checking the condition before the loop body is executed and performing a "variable increment step" afterwards are ill-suited to this particular problem ... ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater
Peter Olsonwrites: >> On January 25, 2016 at 7:40 AM KatolaZ wrote: >> On Mon, Jan 25, 2016 at 12:23:01PM +, Rainer Weikusat wrote: [...] >> > static char const *get_name(char const *arg0) >> > { >> > char const *n, *r; >> > >> > n = r = arg0; >> > while (*r) if (*r++ == '/') n = r; >> > return n; >> > } >> >> That's pretty straight-forward C-programming, IMHO, but I agree that >> it could be seen as interesting by a mor^H^H^Hstudent who approaches C >> for the first time. [...] > This also brings up the question of whether you should roll your own get_name > or > use basename(3) which already [...] A related but IMHO more interesting set of questions could be: 1. Should every trivial crap $someone ever implemented since 1978 end up in general purpose library just because $someone happend to have to power to put it into it? 2. Should people be required to memoize every trivial crap $someone ever implemented since 1978 just because that someone happened to have to power to ...? 3. Should people who consider themselves Very Superior Entities because the have memoized every trivial crap $someone ever ... and so on, be taken as seriously as they continuously demand? ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater
Le 25/01/2016 23:44, Peter Olson a écrit : This also brings up the question of whether you should roll your own get_name or use basename(3) which already does the same thing except in some edge cases. It's easier for the student to understand the code if it is implemented as get_name, but the student ought to learn about dirname and basename pretty early in their study. Using basename() and dirname(0 haven't the power to trigger an interesting discussion :-) Didier ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater
Le 25/01/2016 19:11, Rainer Weikusat a écrit : Didier Krynwrites: [...] A multi-line version could look like this: while (c = *r) { ++r; if (c == '/') n = r; } It might be done with a for loop. eg: for ( ; *r ; ++r) if(*r=='/') n=r; n++; [...] The for loop is the best construct for a loop with an incremental cursor. That's nicely exemplified by the fact that the code above does a redundant increment (or did a redundant increment would it work, the {} are missing) There needs only be one increment of n at the end of the loop, but, maybe it should be: if(n) n++; because I guess n starts from 0. solely to work around the fact that the "for loop mechanics" of checking the condition before the loop body is executed and performing a "variable increment step" afterwards are ill-suited to this particular problem ... I must agree, and I didn't think it was true before reading your example, that the post-increment may have a true semantic value beyond an attempt to optimise execution which would be futile. Which doesn't mean I'm convinced it :-) Didier ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater
Rainer Weikusatwrites: > Didier Kryn writes: > > [...] > >>> A multi-line version could look like this: >>> >>> while (c = *r) { >>> ++r; >>> if (c == '/') n = r; >>> } >>> >> >> It might be done with a for loop. eg: >> >> for ( ; *r ; ++r) if(*r=='/') n=r; >> n++; > > [...] > >> The for loop is the best construct for a loop with an incremental >> cursor. > > That's nicely exemplified by the fact that the code above does a > redundant increment (or did a redundant increment would it work, the {} > are missing) solely to work around [...] > the "for loop While making fun of other people's statements in this way may be ... well ... fun, it's not very nice and also not exactly useful. A C 'for loop' is a pretty strange control construct (one could call it 'overly generic'). It's definition (from K 2nd ed) is for (expression1; expression2; expression3) statement is equivalent to expression1; while (expression2) { statement expression3; } [in absence of a continue in 'statement'] That's a generalization of a loop with the abstract structure ; while () { ; ; } with Sequence of statements intializing a set of loop control variables. Test expression. Used to compare loop control variables or values depending on loop control variables with a termination condition (or 'continuation condition' for C). If the loop should execute once more, the , a sequence of statements making up the loop body, are executed. These may perform operation depending on the current value of loop control variables but don't modify them themselves. Sequence of statements changing the loop control variables possibly based on results from the to 'the next state' prior to evualting the again. but the C for (;;;) doesn't enforce any of these semantic conventions but is really more of a macro which tranposes the text inside the (;;;) as indicated above. Each of the expressions of a for (;;;) may contain arbitrary C expressions, ie, anything except C control constructs. If one happens to be writing a loop following the abstract description given above, for (;;;) can be used to express it fairly straight-forwardly if it isn't too complicated. The 'classic' example would be the C-approximation of a counting loop, for (int i = 0; i < 10; i++) printf("%d\n", i); But the loop in static char const *get_name(char const *arg0) { char const *n, *r; n = r = arg0; while (*r) if (*r++ == '/') n = r; return n; } is not of this type. It contains an init-statement, n = r = arg0; followed by a test expression, while (*r) followed by another test of the same value, if (*r == '/') followed by a step-statement, if (*r++ == '/) followed by an assignment which should only be executed if the test was true but which should use the value modified by the step expression. ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
Re: [DNG] Icerbergs aren't small just because they're mostly underwater (was: "Common knowledge?"-question)
> On January 25, 2016 at 7:40 AM KatolaZwrote: > > > On Mon, Jan 25, 2016 at 12:23:01PM +, Rainer Weikusat wrote: > > KatolaZ writes: > > > > [...] [...] > > The program also contains a very nice example of why the post-increment > > operators is useful (and I means 'useful', not 'common because of > > mindless copying of example code'): > > > > static char const *get_name(char const *arg0) > > { > > char const *n, *r; > > > > n = r = arg0; > > while (*r) if (*r++ == '/') n = r; > > return n; > > } > > That's pretty straight-forward C-programming, IMHO, but I agree that > it could be seen as interesting by a mor^H^H^Hstudent who approaches C > for the first time. > > Peace, love and hacking. > > KatolaZ This also brings up the question of whether you should roll your own get_name or use basename(3) which already does the same thing except in some edge cases. It's easier for the student to understand the code if it is implemented as get_name, but the student ought to learn about dirname and basename pretty early in their study. Peter Olson ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
[DNG] Icerbergs aren't small just because they're mostly underwater (was: "Common knowledge?"-question)
KatolaZwrites: [...] > I still don't see the need for an internal buffer to print out a > formatted string, to be honest :) Everything in code can always be implemented in a number of different ways, hence, whatever the code ends up doing is "not really needed" --- it could have achieved the same in a different way. In this case, the function is part of a 79 lines program whose main looks like this: int main(int argc, char **argv) { char const *name; int status; name = get_name(*argv); openlog(name, LOG_PID | LOG_PERROR, LOG_DAEMON); if (argc < 3) usage(); print_start(name, argv[1]); switch (fork()) { case -1: die(__func__, "fork"); case 0: execvp(argv[2], argv + 2); syslog(LOG_ERR, "main: execvp: %m(%d)", errno); _exit(1); } wait(); print_stop(status); return 0; } and whose purpose is to enable me to write starting "unleashed VPN" \ daemon -n chdir / monitor -n qvpn ssh-vpn mes-pgsql 5000 unleashed unleashed4 in an init script to get a 'start: ok (or failed)' message printed to file descriptor 2 with having to put two printf invocation around the start command. And in the context of that, using stdio for the sole purpose of performing a trivial string formatting operation seemed very inappropriate --- that's new-fangled, ill-thought out stuff supposed to make UNIX(*) easier to use by moron^WUCB students and who really needs that? The program also contains a very nice example of why the post-increment operators is useful (and I means 'useful', not 'common because of mindless copying of example code'): static char const *get_name(char const *arg0) { char const *n, *r; n = r = arg0; while (*r) if (*r++ == '/') n = r; return n; } ___ Dng mailing list Dng@lists.dyne.org https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng