[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: 6502 illegal opcodes questions
In article <1149212396.254683.197660@g10g2000cwb.googlegroups.com>,
mdj <mdj.mdj@gmail.com> wrote:
> Paul Schlyter wrote:
>
>>> !!! There's nothing unfortunate about it improving with age :) There
>>> were a few examples of backwards compatibility being broken in the
>>> early editions, but these issues are well and truly behind us.
>>> Obviously if you write code that depends on new features, you break
>>> compatibility old editions.
>>
>> .... I'm more annoyed with old code whith ceases to work with new JVM versions...
>>
>> Actually, I keep a copy of Nescape 4.7 in working condition (with its
>> own, quite old, JVM), mostly to be able to browse web sites with
>> applets which no longer run properly on modern web browsers.
>
> There was a very deliberate fractioning introduced between Java 1.1 and
> 1.2 (which marks the beginning of the Java 2 plaftorm)
>
> The primary reason for this was to divorce 1.2 onwards from the
> compatibility issues introduced by Microsofts J++ virtual machine - it
> became a serious problem that a web browser running standard Java 1.1
> couldn't run many applets out there, as those applets relied on Win32
> API calls via the Microsoft extensions. This, coupled with the fact
> that it was extremely difficult to switch the VM in Internet Explorer
> caused Sun to draw a compatbility line between the two versions, and
> implement a different applet plugin mechansim so both could co-exist.
>
> Still, this didn't solve the whole problem, as many standard 1.1
> Applets wouldn't run on Microsofts VM, which unfortunately shipped
> standard with Windows, making Java look a lot worse than it actually
> was.
Which explains why Sun later prohibited Microsoft to implement its own JVM.
That's when Microsoft switched to C#.
>>>> The qsort() function is *quite* portable ---- as are most other ANSI C
>>>> library functions which do not access external hardware or OS services.
>>>
>>> Indeed C programs that do no I/O are more portable that those that do,
>>> but they're also completely useless :-)
>>
>> I was talking about portable code, not necessarily about complete applications.
>> Code doing no I/O can still be useful, as a library called by your own program.
>
> Indeed. The language level portability issues remain, however, but yes
> when developing libraries it is sometimes possible to avoid platform
> specific API's. More often, you need to handle multiple cases when
> developing portable C libraries.
Yep -- portable C code usually has a lot of #if's and #ifdef's .....
>> Btw in C you cannot write a program which do no output whatsoever. Even the
>> minimal C program:
>>
>> int main()
>> {
>> return 42;
>> }
>>
>> outputs a return code to the OS, which can be tested in shell scripts/etc.
>> And if you remove the return statement, the required output will be garbage.
>
> Hmm, I wasn't aware the standard actually required that an
> implementation honour the return code,
The standard requires main() to return an int. Sometimes one sees:
void main()
........
which violates the standard.
> or program arguments for that matter.
Program arguments need not be handled. There are two acceptable versions
of the main() function:
int main(void) in C++ one can also write: int main()
int main( int argc, char *argv[] )
> Perhaps an implementation is required to provide a harness for
> code conforming to the API. Admittedly though it's useless on systems
> that don't implement such codes, but then platforms that don't do that
> are pretty much now all obsolete.
>
> In any case, we're talking about a value left on the stack at end of
> program execution, which in my book doesn't constitute I/O
Whether the return value from main() is left on the stack, in some CPU
register, or at some other location, is implementation specific.
However, the startup code (which is part of every C runtime library)
is expected to take care of the return value from main(), and to
return it to the host OS according to the API of that OS. And this
usually involves more than just leaving a value on the stack.
>> One good thing about standards is that there are so many to choose among... :-/
>
> And so many non-comforming implementations of those standards :-)
....yep.... :-/
>> ...but if I want to output the value to some terminal or file, I'd
>> like the output to be A0 rather than FFFFFFA0 .... :-)
>
> Of course, but formatted output is the responsibility of the API. Java
> provides both C style (admittedly recently) and it's own 'OO' style I/O
> facilities which can both accomplish that task very easily. If you're
> relying on the default behavior to output things the way you want it,
> then you're asking for trouble.
>
> Ironically, a lot of features have been added in recent editions to
> appease C programmers who wanted to do things the 'old' way. Most
> notably was the addition of variable argument lists, which allows the
> implementation of System.out.printf() :-)
That's nice! But it's also a hole in the fairly strict type checking
in Java.
>>> I've actually implemented a C compatible expression parser. Leaving out
>>> the unsigned types dramatically simplifies things.
>>
>> I believe you! Leaving out most operators too will make the parser even
>> simpler.... :-)
>
> :-) The operators are relatively easy. dealing with implicit conversion
> between data types is much more frustrating, and a source of
> inefficiency, as there's always more than one way to handle the
> conversions, with one being more efficient than the other...
...well then the choice is easy: do it the most efficient way... :-)
Of course there's some work in ensureing that they way you chose really
was the most efficient.
>> ...or constants! In C++ a 'const' declared int (or float, or....) is
>> really a constant and not merely a write protected variable. So you can
>> do things like:
>>
>> const int arraysize = 1234;
>> int array[arraysize];
>>
>> Doing this is illegal in C - there you *must* use a macro (or a literal
>> integer constant).
>
> Works fine in Java, though.
True.
>>> The compiler will inline the method for you.
>>> The same rule applies to C++, where use of the preprocessor is
>>> generally frowned upon. It's there for backwards compatibility.
>>
>> Even in C++, the preprocessor is useful for conditional compilation. You
>> can't do that with methods..... The #pragma directove (an idea borrowed
>> from Ada) can be quite handy too.
>
> It's still frowned upon, in favour of using a constant plus
> if/else/switch constructs to do conditional compilation.
That causes a problem: a source line which shouldn't be used in some
particular environment can also be a syntax error in such an environment.
Consider for instance:
#if SIZE16BITS
int i = 8000;
else /* assume 32 bits or more */
int i = 4000000;
#endif
If rewritten as:
int i;
if (SIZE16BITS)
i = 8000;
else /* assume 32 bits or more */
i = 4000000;
the "i = 4000000" will cause an integer constant overflow on 16-bit systems,
even though that line is never supposed to be executed there. You'd
have to do tricks like:
int i;
if (SIZE16BITS)
i = 8000;
else /* assume 32 bits or more */
i = 4000000L;
to make it compile also on 16-bit systems.
> One big advantage of this approach is that if you compile with debug
> turned on, the optimiser won't remove the conditional code, which makes
> source level debugging simpler.
A decent source level debugger should of course also keep track of
sourse lines having conditional compilation code.
> Such preprocessor techniques are unnecessary in modern languages. One
> frustrating side effect of using it in C++ is that it still has global
> namespace.
I dondt think one can talk about namespaces at all regarding macros in
preprocessors. The preprocessor does not know what a namespace is. It
hardly knows anything about the underlying source language. Heck, you
can even replace reserved words with macros -- try to do THAT using
the global namespace in a normal way.....
>> And C/C++ macros contain the # (stringize) operator, which converts a
>> symbolic name to a string containing that name. You can't do that with
>> methods either....
>
> Facilities like this one are commonplace in languages that don't retain
> type information at runtime. In Java, the .getName() class method
> provides the same behavior, but better since it's evaluated at runtime
> rather than compile time.
Is there a .setName() method too? If there is, one might be able to
do quite interesting things with it.... :-)
> But then, many people want to treat Java as if it's C++ minus features,
> rather than the very different language that it is.
These peope are wrong of course. Java resembles C++ only
superficially, mostly by having similar syntax. But the semantics
under that syntax is quite different, and more resembles
"strait-jacket languages" like Pascal --- of course with a lot of
features not available in Pascal. I usually think of Java as "the
UCSD Pascal of our times": it has portable object code which must be
run on a virtual machine. However, it is object oriented, it is net
aware, and it is 32-bit rather than 16-bit. And Java is also a
subsystem, not a whole OS like UCSD Pascal was.
> Matt
--
----------------------------------------------------------------
Paul Schlyter, Grev Turegatan 40, SE-114 38 Stockholm, SWEDEN
e-mail: pausch at stockholm dot bostream dot se
WWW: http://stjarnhimlen.se/