Maker Pro
Maker Pro

Programming for Electronics Engineers

R

Rich Grise

I recently wrote a Visual Basic 6 test program, and I used one goto to loop the
sequence of tests back to the top to wait for the next circuit board to be
installed. This main loop called the subroutines that did the actual testing,
however it was still about 200 lines of code long,

If you have one loop that's 200 lines long, then you're doing something
wrong. There's this little trick, called "subroutines", or sometimes
"functions".

And a "GOTO" at the end of it destroys your continuity. A Wend closes the
loop. A GOTO can go anywhere, and is more likely to leave crap on the
stack from the call it's pooping out of. It's a serious bug hole, and
hellishly difficult to debug.

Good Luck!
Rich
 
R

Rick Thompson

You can call them different things, and provide some structure around their
exact operation, but GOTOs are still around in pretty much all languages.
Prime example: Exception handling. In C++, for instance, the whole
try/catch/throw business amount to (try something) (if there's an error,
GOTO the catch statement).

Good point. I write a lot of C++ and I can't see how you could write a
complex system without try/catch, or setjmp/longjump, or whatever.

Occasionally, I also use real gotos for error recovery in a single
routine (file I/O with lots of potential error points, for example).
Interestingly, though, these tend to disappear as the program becomes
more mature.

I can get pretty irritated by statements on how to write PC programs.
One of my favourites is Stroustrup on macros: "Almost every macro
demonstrates a flaw in the programming language, in the program, or in
the programmer". Maybe he should do more programming and less book
writing.

Rick
 
A

Andrew Holme

Joel said:
You can call them different things, and provide some structure around their
exact operation, but GOTOs are still around in pretty much all languages.
Prime example: Exception handling. In C++, for instance, the whole
try/catch/throw business amount to (try something) (if there's an error,
GOTO the catch statement).

There's a difference between structured exception handling and the goto
statement: the exception handler calls destructors as objects go out of
scope. If you lump them together, you might as well throw :)
everything else in e.g. for & while loops; they all compile to jumps
and branches at the machine code level.
 
K

Ken Smith

Rich Grise said:
Again, it depends on what you're trying to accomplish. I designed a bank
of Sallen-Key filters using a spreadsheet once. When the only tool you
have is a hammer, all problems start to look like a nail. ;-)

I still use a spreadsheet for such things sometimes. I must have a
hundred Pascal programs that model various parts of systems I've designed.
Logic equations in Pascal look a lot like the ones in VHDL or Abel.

One of the nice things about using a Pascal program instead of the real
system to test ideas is that the Pascal program can compare the results to
some ideal value and flag the ones that are out of range. Filters
implemented with integers almost never are exactly the ideal.
 
R

Rick Thompson

There's a difference between structured exception handling and the goto
statement: the exception handler calls destructors as objects go out of
scope. If you lump them together, you might as well throw :)
everything else in e.g. for & while loops; they all compile to jumps
and branches at the machine code level.

In C++, goto also calls destructors; see the code below. The (one,
anyway) difference between exception handling and goto is that
exception handling is nonlocal, and goto is local (to the current
function).

Even Stroustrup admits that gotos have their uses; one obvious one is
a multi-level break. I've written a specialised C-based language which
has multi-level breaks to fix this (but no goto, and no plan for one!)

Rick
-----------
The code below produces:

Constructing wibble 1
Constructing wibble 2
Destructing wibble 2
About to exit...
Destructing wibble 1
-----------
#include <iostream>

class wibble {
int id;
public:
wibble(int id_) : id(id_) {
std::cout << "Constructing wibble " << id << std::endl;
}
~wibble() {
std::cout << "Destructing wibble " << id << std::endl;
}
};

int main(void) {
wibble w(1); // construct w1

goto block1;

label1:
std::cout << "About to exit...\n";
return 0; // destruct w1

block1:
{
wibble w(2); // construct w2
goto label1; // destruct w2
}
}
------------
 
K

Ken Smith

Rick Thompson said:
Good point. I write a lot of C++ and I can't see how you could write a
complex system without try/catch, or setjmp/longjump, or whatever.

You'd have to use numbering instead of indenting:


/* 10023 */ if (!IsBogus(Entry)) {
/* 10024 */ destruct->level = entry;
/* 10024 */ }
/* 10023 */ else {
/* 10024 */ destruct->level = DEFAULT_DESTRUCT_LEVEL;
/* 10024 */ Badness++;
/* 10024 */ }

See that way all you code doesn't end up 6 feet to the right.
 
K

Ken Smith

Rich Grise said:
And a "GOTO" at the end of it destroys your continuity. A Wend closes the
loop.

"WEND" is short for "What the hell did that END" You have to put a comment
on it to say what it ended.
A GOTO can go anywhere, and is more likely to leave crap on the
stack from the call it's pooping out of.

Someone more expert in C will have to comment on this for C but in Pascal,
no you can't. Jumps out of context are not allowed. Algol had the
"thunk" method to handle the jump out of context. It is quite a good
idea.
It's a serious bug hole, and
hellishly difficult to debug.

Given any program that uses GOTOs, you can recode it as one using a loop
enclosing a "switch" statement with the index of the switch being
reasigned within the cases. Thus it is proven that the ability to assign
to a variable is as bad as the ability to assign to the program counter.
 
R

Rick Thompson

"WEND" is short for "What the hell did that END" You have to put a comment
on it to say what it ended.


Someone more expert in C will have to comment on this for C but in Pascal,
no you can't. Jumps out of context are not allowed. Algol had the
"thunk" method to handle the jump out of context. It is quite a good
idea.

Not possible in C/C++. goto can only branch within a function, and
will clean up any stacks created by blocks that you leave.
setjmp/longjump are also stack-clean, by definition.

Rick
 
K

Keith Williams

There have been some attempts at "structured assembler" with 'for' and
'while' type kluges, generally by use of a simple preprocessor or a
bunch of weird macros. This makes debugging especially silly.

FOr a while I used a set of PL/I macros for M$ MASM. They worked out
quite well and were recognized by the source debugger. I can't
remember if they supported the complete PL/I SELECT/WHEN construct, but
they were quite useful and produced tight code (even understanding
near/far).
 
R

Richard Henry

Keith Williams said:
FOr a while I used a set of PL/I macros for M$ MASM. They worked out
quite well and were recognized by the source debugger. I can't
remember if they supported the complete PL/I SELECT/WHEN construct, but
they were quite useful and produced tight code (even understanding
near/far).

I recall a Zilog product call PLZ for programming Z-80s. There were two
flavors: PLZ-ASM, which was pretty much Z-80 assembler with some linkage
support, and PLZ-SYS, which added the IF-ELSE-FI and DO-OD and similar
structure controls. I recall the first compiler bug I ever found: if the
object of a SWITCH-CASE structure was 16 bits, and the lower byte was
exactly 0, the program would lose track of its jump table, read two bytes
somewhere else in the program as the jump-to address, and promptly go
insane.
 
K

keith

No, it would be more proper to have all math operations be declared
external subroutines:

Div_Int_By_Float(*var1,*var2)

....and you like 'C' because it uses punctuation marks instead of keywords?
like 'printf', evolving towards a pure, ideal language that does nothing
itself at all.

Scarry. I guess you're just going to have to put me down in the column
with other neandrathals who appreciate PL/I and VHDL, though I got along
with PASCAL too (other than it's total lack of I/O).
 
K

keith

I recall a Zilog product call PLZ for programming Z-80s. There were two
flavors: PLZ-ASM, which was pretty much Z-80 assembler with some linkage
support, and PLZ-SYS, which added the IF-ELSE-FI and DO-OD and similar
structure controls. I recall the first compiler bug I ever found: if the
object of a SWITCH-CASE structure was 16 bits, and the lower byte was
exactly 0, the program would lose track of its jump table, read two bytes
somewhere else in the program as the jump-to address, and promptly go
insane.

Failures of the implementaion aren't failures of the concept. The fact is
that such macros can be written properly and they do improve productivity.
 
P

Paul Burridge

Oops, I guess I scooped up about $40 million under dishonorable
conditions. I should give it all back, I suppose.

John, did I ever mention that along with Winston Churchill, you're the
one of the guys I most admire?
;-)
 
J

John Larkin

...and you like 'C' because it uses punctuation marks instead of keywords?

I despise C and 99% of C programs. I'd just like the language carried
to its logical conclusion, all punctuation and no internal operations
at all. Even the variable space and the stack should be external. So
to do a divide, one should properly say

Div_Int_By_Float(*varspace, *stack, *var1, *var2)

Functions then don't have an associated type, or return a value, since
there's nowhere in this language (C--) to return them to.

John
 
K

keith

I despise C and 99% of C programs. I'd just like the language carried
to its logical conclusion, all punctuation and no internal operations
at all. Even the variable space and the stack should be external. So
to do a divide, one should properly say

Div_Int_By_Float(*varspace, *stack, *var1, *var2)

That's going to make formulas real cute to read. ...besides the fact that
a divide should be a function, not proceedure (returns a single value).

Though I do have to admit your suggestion would kill the language, and
that would be a good thing.

Functions then don't have an associated type, or return a value, since
there's nowhere in this language (C--) to return them to.

Umm, you described a proceedure, not function. Not only that, but your
proceedure would have to assume a type for data, since it's not specified
anywhere in your API. Operators and overloads are far more elegant and
safer than passing by reference. Ick!
 
R

Rich Grise

No need. I used APL on a PC (pre PS/2) keyboard. Before that, 2741s
(essentially ruggedized communicating Selectric typewriters) with APL
keyboards and type-balls. If you can put the character set on a golf-
ball it's not going to take 300 keys.

Well, admittedly, the "300" was a modicum of hyperbole on my part. I've
since been enlightened, since (I don't remember who) posted that, "Yes,
anyone can learn to read APL - it's only impossible to read it _aloud_.

;-)

Thanks!
Rich
 
R

Rich Grise

[email protected] says... ....

Dunno about the last issue. If it's easier to write the function
again... As for the occasional user, I was an occasional APL user some
20 years ago. It was great. I'd argue that a great engineering
language should include matrix operations, where APL excels.

If that is your criteria for a "GEL", then I'd propose that Excel is a
GEL. It's amazingly powerful, easy for the occasional user, and easy
to understand and modify. I've even done logic
simulations/demonstrations with it.

I've heard that it's possible to do a "Towers of Hanoi" on a spreadsheet.

The mind boggles.

Thanks!
Rich
 
B

Bob Stephens

That's going to make formulas real cute to read. ...besides the fact that
a divide should be a function, not proceedure (returns a single value).

Though I do have to admit your suggestion would kill the language, and
that would be a good thing.



Umm, you described a proceedure, not function. Not only that, but your
proceedure would have to assume a type for data, since it's not specified
anywhere in your API. Operators and overloads are far more elegant and
safer than passing by reference. Ick!

I'll probably regret this, but since you guys are so adamant in your
dislike of 'C', what would you recommend as a replacement? N.B. if you
amswer Visual Basic, I'm writing you out of the will.


Bob
 
K

Ken Smith

Bob Stephens said:
I'll probably regret this, but since you guys are so adamant in your
dislike of 'C', what would you recommend as a replacement? N.B. if you
amswer Visual Basic, I'm writing you out of the will.

I think a new language evolved from Pascal (The Borland version) is the
best direction. APL has too many problems with its lack of checking.
Borland extended Pascal to allow multifile projects and adding libraries.
 
Top