The new, improved, but still off "Scroll Lock" saga

Ok, the scroll lock saga is now much closer, but still has the curious business about the Pause key pausing program execution. This just ain’t so. I gave an example that anybody could run to demonstrate this, and a loong explanation why this may appear to be happening, but that apparently wasnt enough evidence.

So, as more evidence, I opened up my big can of programming whup-butt, and wrote a bunch of programs, in various languages, to test this very thing. Below are the programs written in FORTRAN, Pascal, Perl, and C. All they do is loop forever, writing output.

Perl example:

$i = 0;
while( 1 ) { print "This is a test of interrupting output…$i
"; $i++ }


**** FORTRAN EXAMPLE
I = 0

10 WRITE( 6, 100 ) I
I = I + 1
GOTO 10

100 FORMAT( ‘This is FORTRAN LOOP test #’, I10 )
END


/* C Example */
#include <stdio.h>

int main( void )
{
int i; i = 0;
while( 1 ) { printf("This is a test… %9d
", i ); i++; }
}

{ Pascal Example }

program runs( input, output );
var i: integer;
begin
while( true ) do begin writeln(‘This is test #’, i:10 ); i := i + 1; end;
end.


I compiled the FORTRAN example with Lahey FORTRAN 95
I compiled the Perl example with ActiveState Perl 5.8
I compiled the Pascal example with Borland Pascal 6
I compiled the C example with Borland C 5.5

I ran them all the same way: runs.exe >OutFile.Txt
oops, except for the perl one: perl runs.pl >OutFile.Txt

After 10 seconds I pressed the Pause key.
In every case, (Gomer Pyle voice) Surprise, Surprise, Surprise!,
the program kept running, as indicated by the Windows task Manager, the disk light being almost full on, and a growing disk file appearing on the disk:

07-Oct-03 03:07:33 PM 0 OutFile.Txt

07-Oct-03 03:07:48 PM 45,438,768 OutFile.Txt

07-Oct-03 03:07:57 PM 86,303,806 OutFile.Txt

07-Oct-03 03:08:22 PM 245,665,261 OutFile.Txt

07-Oct-03 03:08:38 PM 315,097,096 OutFile.Txt

07-Oct-03 03:07:49 PM 374,349,508 OutFile.Txt


Now it’s quite possible that every program Ms. P has run lately has some built-in quirk whereby it polls the Pause key. That’s not completely out of the question. I’m just trying to show that this isnt a feature that’s built into the operating system, and it’s not a part of any common computer language behavior.

Oh, and I almost forgot, tere’s still the bit about: " Some DOS communication programs used the Break key as a shortcut to terminate a modem connection, but that was really a function of the program, not the operating system."

??? Huh ??? Do you have a source for this? Because all indications are that the break key only broke modem connecionts on the very old Teletypes, which inherited this from telegraph days.

I don’t recall a single comm program that did this, for several reasons.

#1:It would be silly to have the break key do anything other than send a “break”.

#2: The way you usually ended an on-line session was to send some “BYE” command to the mainframe that way it could properly log you off and IT would hang up the phone, this was much prefferred that you just breaking the connection abruptly, and perhaps leaving your connection open racking up connect time charges.

#3: Even if you did want your modem to hangup, 99% of the comm programs expected to be talking thru a “hayes command set” modem, where the one and only command for hanging up was “AT”, followed by “AT H”. Either you could issue these commands right from the keyboard, or there would be some “Hang up” command in the comm program that would do the same. But sending “break” was never a hang-up option on any comm program I’ve ever seen.

Regards,

grg88

Oh, and I forgot again, the discussion of the vertical bar operators is C is CLOSE, but still off enough to make the C standards comittee wince:

"A single pipe indicates “bitwise OR,” "

This is exactly correct

"and two pipes together (||) signify “logical OR.”

Well, not quite. I can’;t blame you for being tripped up by this quirk of the C language. A bitwise OR is serindipitous, it does the logical OR function too. The BIG difference with || is that the || operator is very very sneaky-- it firsts evaluates what’s to the left of the ||, if that expression is true (or non-zero), then it KNOWS it doesnt matter what’s on the right side, the answer has to be true, and it doesnt bother evaluating that right side. Same thing with &&, if the left side is false, the answer is going to be false, no matter what’s on the right of the &&. This business of not evaluating parts of an expression is called “boolean shortcut” to the cognoscenti.

It may seem subtle, but it makes a HUGE difference in practice, as C programmers have gotten used to this twist of dialect:

if( pointervar != NULL || *pointerval == something )…

if “pointerval” is NULL, then evaluating *pointerval results in an immediate program halt, as it’s usually undefined to see what NULL pointers are pointing at. If you write that line with a single bar, it’s going to barf whenever pointerval is NULL. It’s only by the subtle graces of the || operator that the right side of that boom-worthy expression is never evaluated.

But there’s many cases where you do want both sides evaluated, no matter what, so the single-bar still has its place as a logical operator.

Regards,

grg88

Good grief. This is not Compiler Construction Class. Nor was the article a treatise on the C/C++ language and standards. If it were, I wouldn’t be writing it.

I’m painfully aware of the “optimizing” effect of only evaluating one side of the OR (which means that if the first test is TRUE, it doesn’t bother to evaluate the other test). As well as the impact of having poor code that leads to a potential access violation in the situation you have shown (first test of the OR). I have encountered this, as well as the disturbing tendency for some compilers not to test in the same order as the tests are written in the code (going from back to front, for example).

But the point is…read my description of what goes on with the pipes characters, and read yours. Which is going to be more readable and understandable by the public here? That is what I have to try to keep in mind here with that.

Every reference I can find for a description of the “||” characters is “logical OR”. Every reference I have calls it “logical OR”, but you say that term is “not quite” correct. By what other term is it called to differentiate it from the bitwise OR?

Hi Una,

Don’t want to pick nits here, but the majority of the public isn’t likely to understand what you wrote in any case. It may have been safer to write something along the lines of “The pipe (|) character is used in some languages, such as C, C++, C#, Perl, Python and so on as an arithmetic operator (|) and a logical operator (||)” and not go into the details.

Besides the reverse semantics you noted in your reply, a number of languages now have pragmas or compiler directives to enable “full evaluation” of boolean expressions, so it should be considered unsafe to rely on left-to-right short-circuit evaluation unless you know your compiler has full evaluation turned off.

I’d also like to make comment on Break key usage. Command shells on *nix (and even some console programs on Win32 like wget) use the Ctrl-Break key combination to toss the “current process” into the background (still running), giving back your shell commandline to perform other tasks. In *nix, you might then use “fg” to bring the process back to the foreground so you can interact with it again. If anyone knows how you’d do this on Win32 I’d like to know!

Ant.

On my Windows XP Professional, with ActiveState Perl, a long-output program definitely stops for PAUSE if it is emitting output to the screen.

When using minicom on my Linux box to connect over serial cable to my Sun Sparcstation IPX running Open BSD “scroll lock” does in fact stop any text from scrolling. Im not sure which program is actually responsible for stopping the scrolling though.

“boolean shortcuts” are a sin against god purely because they encourage “certain” people to write instructions in what SHOULD BE a boolean expression. Excuse me while I throw up. :stuck_out_tongue: Jesus the syntax of C is so fucking ugly. :-S Here endeth the rant.

Bawahahahaha
This is too much.

And just what % of people registered with SDMB have any idea of what is being said here?

Asimov and Sagen were two of the best at explaining things to the average Joe.
Una is by far easier to read and understand than any of the ‘nit-pickers’ !

Some might say that if it was as exact as math, there would not be more than one OS because there would only be one correct way to do it.

Well, there is more than one path in math also.

The amount of ignorant arrogance about what the staff reports are all about being shown by the nit-pickers in these threads should be an embarrassment to Cecil.

Una did a good job and the rest of you are looking like foolish school boys all flustered because a LADY did good and you just can’t stand it.

At this point, no matter if you nit-pickers are correct or not, you are doing major dis service to the SDMB and Cecil’s ideas of stamping out ignorance. :smack:

*:: In an effort to not be a total ass about this, I brought you guys the umbrellas. :: *

" Which is going to be more readable and understandable by the public here? "

That’s called a “false dichotomy”. One can write clearly and correctly too. Oh, and while we’re at the correctness stuff:

" as well as the disturbing tendency for some compilers not to test in the same order as the tests are written in the code (going from back to front, for example)."

As usual, there’s a small kernel of fact in that statement, but heavily obfuscated.

#1: There’s no way a C compiler could choose to evaluate a short-circuit boolean expression in anything other than left to right order. It would break each and every program that makes use of this feature, which is, unfortunately, a high percentage of them. That should have been obvious to you after a second’s reflection.

#2: Now what may have fooled you is that the standard C calling sequence requires parameters to be evaluated right-to-left. It’s usually considered bad form to write code that depends on this quirk.

So it seems you’ve confused a short-circuit expression like:

 AtLeastOneZero = ( A == 0 ) || ( B == 0 ) || ( C == 0 )

(which is always evaluated left to right)

with a function call with parameters:

   DoBigCalculation( funcEvaledLast(),  funcEvaledmid(),  funcEvaledFirst() );

(Where the parameters are evaluated right-to-left)
Pardon me if I think you’re a bit unclear on these concepts.

So where are these reviewers that are supposed to be scanning your emanations with a fine-tooth bit-comb?


From JWK:
“On my Windows XP Professional, with ActiveState Perl, a long-output program definitely stops for PAUSE if it is emitting output to the screen.”

Yes John, you are 100% correct, I should have repeated in my last posting that the Pause key does pause OUTPUT to the SCREEN. It does not Pause a running program that is not writing to the screen thru the old standard CON driver. It will pause a program, INDIRECTLY, that tries to write to CON if the Pause key’s been pressed, but only if the program has a single thread, and is doing the standard blocking writes to the CON device.
And it doesnt do that too well in Windows/XP. as you’ve probably noticed there’s usually a many-second delay and many screenfulls of output before the Pause keypress actually stops all the buffered-up output.

The Pause key does NOT, and never has, as repeatedly claimed by Ms. P, directly pause execution of any program, at least not any that I’ve ever seen, written, or run.

Regards,
grg88.

They are still both called bitwise and logical OR just as you said. They are “quite” correct usage of the terms rather than “not quite.” This is simply a case of a pseudo troll (grg88) trying to sound smart. While he was correct about other things, he wasn’t correct about saying that this was wrong. Rather, for the sake of sounding like a clever person, he decided to point out how they are similar even though the article in no way asserted that they weren’t similar and in the process incorrectly referred to the usage of the terms “bitwise OR” and “logical OR” as “not quite” correct. FYI the bitwise OR is not called the bitwise-OR-which-is-very-similar-to-the-logical-OR.

…And I’m sorry to add to this fiasco, but I’ve got to say that Una was actually correct to describe the “|” and “||” operators as “bit-wise” and “logical” OR operators the way she did. Even Kernigan and Ritchie (the creator of the C language) define these in “The C Programming Language” this way:

grg88 doesn’t realize that the single “|” is almost exlusively meant to be used in “bit” operations, which is very important in low-level computer tasks, and NOT (usually, anyway) the way grg88 uses it in an “if” statement. The bitwise-OR can be used as a logical-OR because it still is just comparing bits of two (or more) values. It just compares ALL of the bits, because a bitwise OR (by virtue of its name) has to OR each and every value that is ORed, no matter what they are. Yes, it can be used as a logical operator, but it is not called a logical operator because it’s a fundamentally bitwise operation, and to use it in an if statement to “force” evaluation of something is not good programming practice (or so I’ve been told).

Going to bed…

" he wasn’t correct about saying that this was wrong"

I can see you’re also an accomplished fudger. I never said it was wrong. All said is “Not Quite Correct”.

As I’ve stated before, quite a few people consider anything misleading or only part of the story to be “Not Quite Correct”.

To present the || operator without even mentioning that it evaluates to a logical 1 or 0, or it does short-circuit evaluation, is leaving out a whole lot of the story, like all of the significant differences between it and the single |…

Why bother doing a half-ascii job when the uses of the | character has nothing to do with the original question?

I feel this is incorrect. The correct statement in my opinion is that there is no way a compiler should under normal circumstances choose to evaluate from right to left. Yet I have seen it happen, with witnesses, and thus I never rely on the order of operations around an “OR” as being fixed. This has happened in Borland C++ for OS/2 as well as C++ Builder and MS VC 6. I have seen even crazier things happen as well, mostly with Borland C++ for OS/2. Perhaps that explains why…

You are 100% correct if what you are saying is that it is NOT supposed to do this. If you evaluate what I said:

And you want to use the Logic of Spock to rebut me, you must prove:

  1. That no compiler ever did something it wasn’t supposed to or ever exhibited unwanted and/or undesired behaviour (and believe me, I’ve seen some behaviour that falls far, far outside of any standard for C compilers - thus, there are many coding practices and shortcuts I never rely upon). I would list some of them but my friend Dr_Theopolus just advised me by phone something along the lines of “Great God, if you want this thread to go on for years, by all means start talking about incorrect compiler behaviour.”

  2. That no compiler I personally ever used ever did this.

I thought a false dichotomy was when one put forth that their conclusion was the only reasonable option of two options, and that the other option was demonstrably or by inspection wrong and/or over the top. I do not assert that your explanation was wrong, only that:

  1. The purpose of the article was not to delve into the details of the C/C++/.Net/C# languages.

  2. The explanation is correct in calling it a “logical OR”.

  3. Thus my brief explanation was correct as-written.

Also, if we’re grinding words and phrases into a fine paste, by saying “one can write clearly and correctly” it would seem you are asserting in effect that my explanation was incorrect, something that has now evolved from being “not quite” correct.

Regarding the Pause key: after spending some time I have found that all of my programs do trap the Pause key. This is because they were console programs using FORTRAN (with inline assembly code as well…which I’ll be damned if I can really understand) that were intended to have large amounts of functionality from the console. Thus, you are correct as far as I can tell on the Pause key behaviour, but I am waiting on some other references to back either you, me, or “none of the above” up on this. I think you’ll understand if I wait for other independent confirmation, right? At absolute worst, the article may need only a minor change to clarify that “it can have the effect of pausing” the program.

SchoolyD, thank you very much for posting the K&R quote. That was actually where I had checked my terminology prior to writing the article long ago, but since 1) my K&R book is missing, and 2) it’s not online, being in copyright, I was too uncertain to state it as a reference unless I could back it up with an actual quote, since any possible error in quoting it or editing change I may have made might invalidate my entire article.

While I really and honestly do appreciate the support for my position, I feel it is very wrong to refer to grg88 as a pseudo or any other type of troll. It is against the rules, and it does not IMO describe grg88 and is not fair to him. I feel that grg88 is very passionate and exacting on this subject where he does indeed have a special knowledge, just like I am on my subjects where I am a specialist (such as coal, energy, public domain art, coal, cars, firearms, sex, and coal). Plus the fact that he has been right on several points show that while I feel there is a high level of nitpicking here, he also is doing a good job of demonstrating some valid points.

Una

It’s funny. I happened to be re-reading that exact section last night, and when I encountered this discussion a couple of hours later, I couldn’t help but post it. I think it was some sort of divine intervention (of course, I don’t know why God would care that much about the difference between bitwise and logical operators).

Dallas

We’d better wrap up this thread!

Some final thoughts:

It’s generally inefficient to try to prove a universal negative. Rather than have me test every C compiler ever released to “prove” my contention, it’s much more efficient if you’d win the argument by providing JUST ONE example that fits your assertions.

On the other hand, I have a pretty good test case formy contention that no C compiler would ever evaluate || other than left to right. The Linux and gnu program code base makes copious use of short-circuit boolean evaluations. Let’s see,
I don’t have the code handy, but as a rough estimate, probably about 800,000 lines of code, let’s guess one “||” operator every 40 lines of code, that’s maybe 20,000 instances of “||”.

And it all compiles with Microsoft C, Borland C, dgpp C, gcc, Sun C, HP C, Silicon Graphics C, Hitachi C, Cray C, Metroworks C, various versions, across almost 10 years now. That’s 10 C compilers.

Ok, I’ve given 200,000-some examples that work okay, all you need to is come up with ONE to prove me wrong.
Regards,

George

grg88:

I cannot come up with an compileable example since by definition (something I was and am in 100% agreement with you on) it is not standard nor accepted behaviour of a compiler. I referred to “the disturbing tendency for some compilers not to test in the same order as the tests are written in the code (going from back to front, for example).” This happened numerous times whilst working on a project long ago in Borland C++ for OS/2 (but only once or twice in VC 5.0 (not 6.0 as I said earlier, my mistake), in fairness), and the code was nothing spectacular or fancy - it just would fail in exactly the way you described, but evaluating in the reverse order of operations.

Since it was one of the first compilers I used for more than 20 hours a week, it beat into me a healthy suspicion and wariness which results in me doing things like overdefining scope with too many parentheses and braces, as well as separating out complex conditional statements and not nesting loops as much as another programmer might. In fact, because mistakes or unwanted behaviours in my code result in serious, direct, personal financial implications, my code is somewhat bulky and ugly with lots of checks, double checks, and quintuple checks for things that should - and should not - happen. I imagine you would really shudder to see it, but it pays my bills and it does work reliably and consistently for my clients.

And it did not exhibit this bad behaviour consistently, as moving the code up or down in the source file would change the behaviour to the normal, accepted, standard behaviour. Sound like memory problems? Maybe - the stack and the heap always looked fine to us, but maybe we missed something. And it was not just me who was inflicted with it, several people in our office shared the joy as well.

The only disagreement here involves my throw-away comment that I have seen compilers do things they should not have, and not just from memory corruption. One can Google for other undesired behaviours in general seen in other compilers and discover that some do have bugs of various sorts, which is one reason that VC 6 is on service pack…what now? I don’t even know. But I’m not going to go there.

A C compiler that does not evaluate && or || left-to-right is a C compiler with a severe bug. Period.

Absolutely no disagreement here.

You didn’t mention what you used to connect to the remote machine. If it was some form of terminal emulator (telnet, ssh, etc.), it may just be mapping that key to the “stop” control character, generally Control-S (ASCII code 19). From the command line on the remote machine, if you type Control-V, then Pause/Break, you will see “^S” if this is correct.

Ouch! Remind me not to nominate you for Supreme Court Justice with that rationale. I think the person you quoted may have meant to write “short-circuit” instead of “shortcut”. The C statement below is both.


pointervar == 0 || DoFunction(pointervar);

This does work in C. However, I’ve never seen it done in practice, and AFAIK, it’s generally frowned upon. Note that in Perl, such a construct is widely used, largely because it is a shortcut, saving 2 or more lines of code in a language that values terseness. Example:


open(IN, "input.dat") || die "Can't open file";

or, more dramatically:


$arg = &FunctionA || &FunctionB;

which is a single line, with its intent more obvious than the 6-line plus extra variable:



my $tmp = &FunctionA;
if ($tmp) { 
    $x = $tmp;      
} else {
    $x = &FunctionB;
}


The only language I know which doesn’t have a short-circuiting Or operator is Visual Basic. If everything else is a sin against God, count me with the satanists :stuck_out_tongue:

Than you Ms. P, I can’t find a single thing to quibble about in your latest reply!

Regards to all, and apologies to the majority that expected some info about scroll lock!