Prev: integer
Next: shared memory question
From: Seebs on 4 Mar 2010 19:05 On 2010-03-04, Ike Naar <ike(a)localhost.claranet.nl> wrote: > It's also "non chinese" and "non swahili". It's C, and in C the order > of the operands of the == and != operators is irrelevant. To the compiler, yes. To the reader, no. > You don't read arithmetic expressions like you read a work of literature. You sort of do, actually. In general, while everyone knows that addition is commutative, people will tend (slightly) to see "x + 3" as "basically x, but with 3 more", and "3 + x" as "basically 3, but with x more". The lefthand operand has primacy, and this *does* matter. It's the same reason that: the man was eaten by the bear and the bear ate the man are not the same statement, even though they have the same information in them if you ignore connotations. One is telling you about the bear's diet; one is telling you about what happened to a man. So even if it's the same for the compiler, if you write: if (x != y) the reader assumes that x is the value which is in question, not y. Maybe the reader is wrong, but the assumption is sufficiently deeply wired in most brains that there is no point trying to outsmart the reader. The reader will pick up the connotation with very high reliability, *even if it's wrong*. Thus, your best bet when writing code so that humans can read it reliably remains to honor the convention even though there's no reason in C itself to do so. It's like indentation. We don't indent in C because the compiler cares, but because it helps readers understand. Bad indentation can result in readers misunderstanding code, because they trust the indentation to be a cue. Similarly, reversing the order of the comparands in an equality or inequality comparison, even though in theory it changes nothing semantically, can cause readers to misunderstand code. I write for humans, not compilers. Compilers aren't subject to assumptions, or to difficulty keeping track of the code. -s -- Copyright 2010, all wrongs reversed. Peter Seebach / usenet-nospam(a)seebs.net http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
From: Ersek, Laszlo on 4 Mar 2010 19:37 In article <slrnhovrde.6eh.usenet-nospam(a)guild.seebs.net>, Seebs <usenet-nospam(a)seebs.net> writes: > On 2010-03-04, John Gordon <gordon(a)panix.com> wrote: >> No, it does actually do something: it will throw a compile error if you >> mistype == as =. > > But gcc gives a warning for it, anyway. And "x == 7" is much more readable > than "7 == x". > > At least, for English speakers it is. I don't know; maybe there are languages > in which saying "if x is equal to y" implies that x is the constant and y > is the variable. I've found the following phrases in Wiktionary: http://en.wiktionary.org/wiki/equal "Two plus two equals four." "A and B are equal" "A is equal to B" "A is equal with B" In Hungarian, forms 1 and 3 don't exist, but forms 2 and 4 are used with the exact same structure. And yet I don't have any difficulty writing 7 == x and thinking, "7 is equal with x". Equality is symmetric. It took some self-education (let's not be inquisitive about the why), but it was so effective that now I frown on x == 7 .... I updated the function below to its current form two days ago; you'll love to hate it: static void bailout(void) { sigset_t tmp_set; if (pthread_equal(pthread_self(), main_thread)) { if (0 != opathn) { (void)unlink(opathn); } if (0 == sigemptyset(&tmp_set) && 0 == sigaddset(&tmp_set, SIGPIPE) && 0 == sigaddset(&tmp_set, SIGXFSZ)) { (void)pthread_sigmask(SIG_UNBLOCK, &tmp_set, 0); } } else { if (0 == sigemptyset(&tmp_set) && 0 == sigpending(&tmp_set)) { int chk; chk = sigismember(&tmp_set, SIGPIPE); if (0 == chk || (1 == chk && 0 == kill(pid, SIGPIPE))) { chk = sigismember(&tmp_set, SIGXFSZ); if ((0 == chk || (1 == chk && 0 == kill(pid, SIGXFSZ))) && 0 == kill(pid, SIGUSR1)) { pthread_exit(0); } } } } _exit(EX_FAIL); } (If called from the main thread, it removes the output file, if any. Then it tries to unblock any pending SIGPIPE or SIGXFSZ. If it succeeds (it should) and there is in fact any such signal pending for the whole process or specifically for the main thread, such that its action is not SIG_IGN (but SIG_DFL), then the process dies with one of those signals. If unblocking fails (for whatever reason -- it shouldn't), or no such signal was pending, or all relevant actions were SIG_IGN (yes, a signal may remain pending even though its action is SIG_IGN), then the process exits with status 1. (Unless a sub-thread encounters an EPIPE/EFBIG and raises a SIGPIPE or SIGXFSZ, see below, to the process level, just between unblocking and exiting, which is fine.) If called from any sub-thread, if any of the following fails, the entire process is terminated with exit status 1 as a last resort. Each sub-thread has SIGPIPE and SIGXFSZ blocked. If any such signal is pending on the thread, the thread forwards it to the process level, so that it will become deliverable to the main thread. If any such signal is already pending on the whole process, then the thread regenerates it for the whole process -- an idempotent operation. Then the thread wakes the main thread -- which is waiting for asynchronously generated signals anyway like SIGINT and SIGTERM -- with a SIGUSR1 error notification, and finally, the sub-thread terminates. sigismember() can theoretically return -1, that's why 1 == chk is checked after 0 == chk proves false. tmp_set must be emptied before it can be passed to sigpending().) Cheers, lacos
From: Keith Thompson on 4 Mar 2010 19:42 ike(a)localhost.claranet.nl (Ike Naar) writes: > In article <4b8fc2ce$0$22943$e4fe514c(a)news.xs4all.nl>, > Casper H.S. Dik <Casper.Dik(a)Sun.COM> wrote: >>Vladimir Jovic <vladaspams(a)gmail.com> writes: >> >>>Yes, you missed the point. I prefer this way : >> >>>if ( NULL != pointer1 && >>> 0x152 == pointer1->field7 ) >>> { >>> return; >>> } >> >>But it makes the code much more difficult to read. >> >>You're not testing that NULL now has a different value or that >>0x152 has a different value. > > The != operator is symmetric, ``NULL != pointer'' and ``pointer != NULL'' > mean exactly the same thing, and both expressions are easy to read. Yes, the != operator is symmetric. Yes, the two expressions mean exactly the same thing. No, ``NULL != pointer'' *isn't* easy to read *for a lot of people*. When I see a constant on the LHS and a variable on the RHS of an "==" or "!=" operator, I have to mentally swap the operands to understand what it means. If you find them equally easy to read, I envy you. Seriously. It probably means that you have a better intuitive understanding than I do. Consider that the following expressions all have the same meaning: pointer != NULL NULL != pointer !(pointer == NULL) !!pointer pointer == NULL ? 0 : 1 pointer == NULL == '/'/'/' Most sane people would prefer either of the first two forms to the others, simply because they're more readable. Please understand, or at least accept accept, than many of us prefer the first form to the second for exactly the same (probably not entirely rational) reason. [...] -- Keith Thompson (The_Other_Keith) kst-u(a)mib.org <http://www.ghoti.net/~kst> Nokia "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister"
From: Ersek, Laszlo on 4 Mar 2010 20:22 In article <lny6i7tx8t.fsf(a)nuthaus.mib.org>, Keith Thompson <kst-u(a)mib.org> writes: > pointer == NULL == '/'/'/' Fascinating :) Cheers, lacos
From: Golden California Girls on 4 Mar 2010 20:58
Nicolas George wrote: > If the programmer is trying to make a good, working program, it enables most > warnings and tries to correct them all. Programmers are its?! Now I'm sure there are some bosses who feel that way ... |