VON NEUMANN VS HARVARD

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View


Excerpted from AVR Butterfly Site at: http://retrodan.tripod.com

VON NEUMANN vs. HARVARD ARCHITECTURE

If you are new to Microcontrollers one of the arguments you are going to
hear bantered about is Harvard Architecture versus the Von Neumann
Architecture.


THE VON NEUMANN ARCHITECTURE

Most computers we are familiar with use an architecture called Von Neumann.
The term arose out of Neumann's 1945 draft report on the ADVAC computer. He
was not, however the original inventor of it.

                                       +---------+
                                       |   RAM   |
                                       | - - - - |
                           BottleNeck  | PROGRAM |
                    [CPU] <==========> | - - - - |
                                       |  DATA   |
                                       +---------+

A Von Neumann machine has one large monolithic RAM structure that contains
both program memory and data memory mixed together. Since both program steps
and data must be loaded from the same place, it can create a problem called
the Von Neumann Bottle-Neck.


THE HARVARD ARCHITECTURE

Most microcontrollers use a different system called Harvard architecture.
The larger program storage and the smaller data memory are separated. The
first such machine, the Harvard Mark I had it's programs hard-coded on
paper-tape and the volatile data was loaded into electric relays.


                +----------+                     +------+
                |  PROGRAM |                     | DATA |
                |   ROM    | <----> [CPU] <----> | RAM  |
                +----------+                     +------+


Harvard style machines allow program steps to be fetched at the same time as
data, thereby creating potentially faster through-put and less of a
bottle-neck. They also have the benefit that run away processes can't damage
the program stored in the non-volatile program area so they're more stable.
Many C programs lack proper boundary checking and a null pointer or an
over-run buffer can overwrite and crash a program that shares RAM with data.
If you are new to this architecture you need to keep this in mind. When
creating a routine that needs a few bytes of storage, I would normally
create that space within the routine itself. On a Harvard machine, those
bytes would not be in volatile RAM but part of the hard coded program memory
stored in ROM (or FlashRAM).



AVR BUTTERFLY PROGRAM SPACE (FLASH)

The AVR Butterfly (Atmega169) program space is 16K long and is divided into
two main areas. The top 1-2K and is usually loaded with a bootloader that is
protected from an overwrite and the rest is available for your programs. At
the beginning of each program space is an area for interupt vectors. The
first such vector is the Power-Up/Reset Vector and should contain an RJMP to
the first line of your program.


   .---------------------------------------------------.
   | POWER-UP VECTOR (NORMALLY POINTS TO YOUR PROGRAM) |
   |             OTHER INTERUPT VECTORS                |
   |- - - - - - - - - - - - - - - - - - - - - - - - - -|
   |                                                   |
   |           YOUR PROGRAM SPACE (14-15K)             |
   |                                                   |
   |                                                   |
   .---------------------------------------------------.
   |           BOOT:INTERUPT VECTORS                   |
   |- - - - - - - - - - - - - - - - - - - - - - - - - -|
   |        BOOTLOADER PROGRAM SPACE (1-2K)            |
   `---------------------------------------------------'


AVR BUTTERFLY DATA SPACE (SRAM)

The data space on the AVRs is a little unusual. The 32 internal accumulators
are memory mapped as the first 32 bytes of data memory, followed by all the
I/O ports which are mapped into memory space followed by the 1K of actual
SRAM starting at $100.


   .---------------------------------------------------.
   |$00-$1F: 32 Internal Accumulator/Working-Registers |
   +---------------------------------------------------+
   |$20-$5F:    64 Input/Output Ports                  |
   |-   -   -   -   -   -   -   -   -   -   -   -   -  |
   |$60-$FF     160 Extra I/O Ports                    |
   +---------------------------------------------------|
   |$100                                               |
   |           1024 Bytes SRAM $100 to $4FF            |
   |                                                   |
   |                                                   |
   |-   -   -   -   -   -   -   -   -   -   -   -   -  |
   |$4FF    (Normal Location for Stack)                |
   `---------------------------------------------------'




Re: VON NEUMANN VS HARVARD


So what? This is so mundane and boring.

UFO Joe wrote:
Quoted text here. Click to load it


Re: VON NEUMANN VS HARVARD


Quoted text here. Click to load it
[snip]

There are theories and there are actual devices that
have some performance, some features and a price tag.
At one point, when you have to actually solve a problem,
get some embedded system doing a job, then you just
compare the available devices, their prices, the
development tools and the support.

And you won't get the ultimate mega machine for
1$ a piece.

Rene
--
Ing.Buero R.Tschaggelar - http://www.ibrtses.com
& commercial newsgroups - http://www.talkto.net

Re: VON NEUMANN VS HARVARD



Quoted text here. Click to load it

In my opinion everything that uses the harvard architecture is very,
very outdated.

The main problem with the HA is that you have seperate memory spaces.
C doesn't like that. You'll have to test which memory space a pointer
is pointing to. Functions like memcpy, printf, etc, etc, won't work
with any pointer. Ofcourse you can kludge things together, but in the
end you'll find yourself locked to that target. With ever shorter
product life times you'll want to move your code to other platforms or
develop on a PC and then transfer the algorithm to an embedded device.

Modern processors use an instruction and data cache which basically
'emulate' the harvard architecture without its downsides.

--
Reply to nico@nctdevpuntnl (punt=.)
Bedrijven en winkels vindt U op www.adresboekje.nl

Re: VON NEUMANN VS HARVARD


[....]
Quoted text here. Click to load it

In my opinion everthing that uses C is very, very outdated.  The C
language doesn't support the passing of or the returning of complex data
types.  It is also stuck with the dangerous and silly notion of the
"pointer".  

High performance processors like DSPs often have different classes of
memories.  Instructions, integers and floats can all have their own
address spaces.  Writing C compilers for such things is a real nightmare
and even with a good compiler writing in C is a sickening task.


--
--
snipped-for-privacy@rahul.net   forging knowledge


Re: VON NEUMANN VS HARVARD



Quoted text here. Click to load it

A pointer is as dangerous as the programmer using it. By your remark
about complex data it seems you have little experience with C. It is
not a problem to pass a pointer to complex data types or objects (most
programs do this all the time) and alter the contents. C even offers
ways to make function parameters read-only so you'll get a compiler
warning if you overwrite arguments.

Besides, modern DSPs like the Analog Devices Blackfin series have a
MMU which can be used to make certain memory areas read only. Since it
has a single address space, you can run an embedded OS like micro
Linux if you like.

Quoted text here. Click to load it

Old style thinking, old style hardware. All these performance tuning
kludges can be replaced by using a cache memory which allows for
efficient code generation by a C/C++ compiler on a single memory space
CPU. Keep in mind that on CPUs with seperate memory spaces, a lot more
instruction codes are wasted which could be used for nifty things like
read-modify-write bit set/toggle/clear operations.

--
Reply to nico@nctdevpuntnl (punt=.)
Bedrijven en winkels vindt U op www.adresboekje.nl

Re: VON NEUMANN VS HARVARD


Quoted text here. Click to load it

No, a pointer is by its nature dangerous.  Because of it, you have to do
all sorts of strange stuff to do bounds checking in C.  In other langages,
range checking is much easier to do.


Quoted text here. Click to load it

Yes, you can pass a pointer but like I said, you can neither pass not
return a complex type.  You have to pass a pointer if you wish your
subroutine to work with a complex type.  You seem to claim to have a lot
experience with C and yet you missed that point.

The syntax of C hides the fact that it is a pass by reference in the
call statement so you have to look at other lines of the code to know if
the routine modifies the value.



Quoted text here. Click to load it

Yes and this has zero to do with the statements in my post.


[....]

Quoted text here. Click to load it

The cache uses much more silicon to get the same performance.  You can get
better performance by having multiple address spaces.

--
--
snipped-for-privacy@rahul.net   forging knowledge


Re: VON NEUMANN VS HARVARD


Quoted text here. Click to load it

Nonsense. It's trivially easy to pass and return structures - the only
limit is your stack size:
------------------------
/* complex_type.c */
/* to demonstrate passing and returning structures from a C function */
#include <stdio.h>

struct FourItems {
    int item1;
    int item2;
    int item3;
    int item4;
} A;

struct FourItems manipulate(struct FourItems Q) {
    printf("Q.1 = %d, Q.2 = %d, Q.3 = %d, Q.4 = %d\n",
        Q.item1, Q.item2, Q.item3, Q.item4);

    Q.item1 = 5;
    Q.item2 = 12;
    Q.item3 = 3;
    Q.item4 = 7;
    return Q;
}

int main(int argc, char *argv[]) {
    struct FourItems B;

    A.item1 = 1;
    A.item2 = 2;
    A.item3 = 3;
    A.item4 = 4;

    printf("A.1 = %d, A.2 = %d, A.3 = %d, A.4 = %d\n",
        A.item1, A.item2, A.item3, A.item4);

    B = manipulate(A);
    printf("B.1 = %d, B.2 = %d, B.3 = %d, B.4 = %d\n",
        B.item1, B.item2, B.item3, B.item4);

    exit(0);
}

-----------------------------
Here's its output:

$ complex_type
A.1 = 1, A.2 = 2, A.3 = 3, A.4 = 4
Q.1 = 1, Q.2 = 2, Q.3 = 3, Q.4 = 4
B.1 = 5, B.2 = 12, B.3 = 3, B.4 = 7

-----------------------------
And here's a list of the generated code:
$ cat complex_type.lst
GAS LISTING /tmp/ccQA6n9P.s                     page 1


   1                            .file   "complex_type.c"
   2                            .file 1 "complex_type.c"
  10                    .Ltext0:
  11                            .file 2
"/usr/lib/gcc-lib/i486-slackware-linux/3.3.6/include/stddef.h"
  12                            .file 3 "/usr/include/bits/types.h"
  13                            .file 4 "/usr/include/stdio.h"
  14                            .file 5 "/usr/include/wchar.h"
  15                            .file 6 "/usr/include/_G_config.h"
  16                            .file 7 "/usr/include/gconv.h"
  17                            .file 8
"/usr/lib/gcc-lib/i486-slackware-linux/3.3.6/include/stdarg.h"
  18                            .file 9 "/usr/include/libio.h"
  19                            .section        .rodata
  20                            .align 32
  21                    .LC0:
  22 0000 512E3120              .string "Q.1 = %d, Q.2 = %d, Q.3 = %d, Q.4 =
%d\n"
  22      3D202564
  22      2C20512E
  22      32203D20
  22      25642C20
  23                            .text
  24                    .globl manipulate
  26                    manipulate:
  27                    .LFB3:
   1:complex_type.c **** /* complex_type.c */
   2:complex_type.c **** /* to demonstrate passing and returning structures from
a C function */
   3:complex_type.c **** #include <stdio.h>
   4:complex_type.c ****
   5:complex_type.c **** struct FourItems {
   6:complex_type.c ****        int item1;
   7:complex_type.c ****        int item2;
   8:complex_type.c ****        int item3;
   9:complex_type.c ****        int item4;
  10:complex_type.c **** } A;
  11:complex_type.c ****
  12:complex_type.c **** struct FourItems manipulate(struct FourItems Q) {
  28                            .loc 1 12 0
  29 0000 55                    pushl   %ebp
  30                    .LCFI0:
  31 0001 89E5                  movl    %esp, %ebp
  32                    .LCFI1:
  33 0003 53                    pushl   %ebx
  34                    .LCFI2:
  35 0004 83EC04                subl    $4, %esp
  36                    .LCFI3:
  37 0007 8B5D08                movl    8(%ebp), %ebx
  13:complex_type.c ****        printf("Q.1 = %d, Q.2 = %d, Q.3 = %d, Q.4 =
%d\n",
  38                            .loc 1 13 0
  39 000a 83EC0C                subl    $12, %esp
  40 000d FF7518                pushl   24(%ebp)
  41 0010 FF7514                pushl   20(%ebp)
  42 0013 FF7510                pushl   16(%ebp)
  43 0016 FF750C                pushl   12(%ebp)
  44 0019 68000000              pushl   $.LC0
  44      00
  45                    .LCFI4:
  46 001e E8FCFFFF              call    printf
  46      FF

GAS LISTING /tmp/ccQA6n9P.s                     page 2


  47 0023 83C420                addl    $32, %esp
  14:complex_type.c ****                Q.item1, Q.item2, Q.item3, Q.item4);
  15:complex_type.c ****
  16:complex_type.c ****        Q.item1 = 5;
  48                            .loc 1 16 0
  49 0026 C7450C05              movl    $5, 12(%ebp)
  49      000000
  17:complex_type.c ****        Q.item2 = 12;
  50                            .loc 1 17 0
  51 002d C745100C              movl    $12, 16(%ebp)
  51      000000
  18:complex_type.c ****        Q.item3 = 3;
  52                            .loc 1 18 0
  53 0034 C7451403              movl    $3, 20(%ebp)
  53      000000
  19:complex_type.c ****        Q.item4 = 7;
  54                            .loc 1 19 0
  55 003b C7451807              movl    $7, 24(%ebp)
  55      000000
  20:complex_type.c ****        return Q;
  56                            .loc 1 20 0
  57 0042 8B450C                movl    12(%ebp), %eax
  58 0045 8903                  movl    %eax, (%ebx)
  59 0047 8B4510                movl    16(%ebp), %eax
  60 004a 894304                movl    %eax, 4(%ebx)
  61 004d 8B4514                movl    20(%ebp), %eax
  62 0050 894308                movl    %eax, 8(%ebx)
  63 0053 8B4518                movl    24(%ebp), %eax
  64 0056 89430C                movl    %eax, 12(%ebx)
  21:complex_type.c **** }
  65                            .loc 1 21 0
  66 0059 89D8                  movl    %ebx, %eax
  67 005b 8B5DFC                movl    -4(%ebp), %ebx
  68 005e C9                    leave
  69 005f C20400                ret     $4
  70                    .LFE3:
  72                            .section        .rodata
  73 0028 00000000              .align 32
  73      00000000
  73      00000000
  73      00000000
  73      00000000
  74                    .LC1:
  75 0040 412E3120              .string "A.1 = %d, A.2 = %d, A.3 = %d, A.4 =
%d\n"
  75      3D202564
  75      2C20412E
  75      32203D20
  75      25642C20
  76 0068 00000000              .align 32
  76      00000000
  76      00000000
  76      00000000
  76      00000000
  77                    .LC2:
  78 0080 422E3120              .string "B.1 = %d, B.2 = %d, B.3 = %d, B.4 =
%d\n"
  78      3D202564
  78      2C20422E

GAS LISTING /tmp/ccQA6n9P.s                     page 3


  78      32203D20
  78      25642C20
  79                            .text
  80                    .globl main
  82                    main:
  83                    .LFB5:
  22:complex_type.c ****
  23:complex_type.c **** int main(int argc, char *argv[]) {
  84                            .loc 1 23 0
  85 0062 55                    pushl   %ebp
  86                    .LCFI5:
  87 0063 89E5                  movl    %esp, %ebp
  88                    .LCFI6:
  89 0065 83EC18                subl    $24, %esp
  90                    .LCFI7:
  91 0068 83E4F0                andl    $-16, %esp
  92 006b B8000000              movl    $0, %eax
  92      00
  93 0070 29C4                  subl    %eax, %esp
  24:complex_type.c ****        struct FourItems B;
  25:complex_type.c ****
  26:complex_type.c ****        A.item1 = 1;
  94                            .loc 1 26 0
  95                    .LBB2:
  96 0072 C7050000              movl    $1, A
  96      00000100
  96      0000
  27:complex_type.c ****        A.item2 = 2;
  97                            .loc 1 27 0
  98 007c C7050400              movl    $2, A+4
  98      00000200
  98      0000
  28:complex_type.c ****        A.item3 = 3;
  99                            .loc 1 28 0
 100 0086 C7050800              movl    $3, A+8
 100      00000300
 100      0000
  29:complex_type.c ****        A.item4 = 4;
 101                            .loc 1 29 0
 102 0090 C7050C00              movl    $4, A+12
 102      00000400
 102      0000
  30:complex_type.c ****
  31:complex_type.c ****        printf("A.1 = %d, A.2 = %d, A.3 = %d, A.4 =
%d\n",
 103                            .loc 1 31 0
 104 009a 83EC0C                subl    $12, %esp
 105 009d FF350C00              pushl   A+12
 105      0000
 106 00a3 FF350800              pushl   A+8
 106      0000
 107 00a9 FF350400              pushl   A+4
 107      0000
 108 00af FF350000              pushl   A
 108      0000
 109 00b5 68400000              pushl   $.LC1
 109      00
 110                    .LCFI8:

GAS LISTING /tmp/ccQA6n9P.s                     page 4


 111 00ba E8FCFFFF              call    printf
 111      FF
 112 00bf 83C420                addl    $32, %esp
  32:complex_type.c ****                A.item1, A.item2, A.item3, A.item4);
  33:complex_type.c ****
  34:complex_type.c ****        B = manipulate(A);
 113                            .loc 1 34 0
 114 00c2 8D45E8                leal    -24(%ebp), %eax
 115 00c5 83EC0C                subl    $12, %esp
 116 00c8 FF350C00              pushl   A+12
 116      0000
 117 00ce FF350800              pushl   A+8
 117      0000
 118 00d4 FF350400              pushl   A+4
 118      0000
 119 00da FF350000              pushl   A
 119      0000
 120 00e0 50                    pushl   %eax
 121 00e1 E8FCFFFF              call    manipulate
 121      FF
 122 00e6 83C41C                addl    $28, %esp
  35:complex_type.c ****        printf("B.1 = %d, B.2 = %d, B.3 = %d, B.4 =
%d\n",
 123                            .loc 1 35 0
 124 00e9 83EC0C                subl    $12, %esp
 125 00ec FF75F4                pushl   -12(%ebp)
 126 00ef FF75F0                pushl   -16(%ebp)
 127 00f2 FF75EC                pushl   -20(%ebp)
 128 00f5 FF75E8                pushl   -24(%ebp)
 129 00f8 68800000              pushl   $.LC2
 129      00
 130 00fd E8FCFFFF              call    printf
 130      FF
 131 0102 83C420                addl    $32, %esp
  36:complex_type.c ****                B.item1, B.item2, B.item3, B.item4);
  37:complex_type.c ****
  38:complex_type.c ****        exit(0);
 132                            .loc 1 38 0
 133 0105 83EC0C                subl    $12, %esp
 134 0108 6A00                  pushl   $0
 135                    .LCFI9:
 136 010a E8FCFFFF              call    exit
 136      FF
  39:complex_type.c **** }
 137                            .loc 1 39 0
 138                    .LBE2:
 139                    .LFE5:
 141                            .comm   A,16,4
 212                    .Letext0:
 2232                           .ident  "GCC: (GNU) 3.3.6"

GAS LISTING /tmp/ccQA6n9P.s                     page 5


DEFINED SYMBOLS
                            *ABS*:0000000000000000 complex_type.c
     /tmp/ccQA6n9P.s:26     .text:0000000000000000 manipulate
     /tmp/ccQA6n9P.s:82     .text:0000000000000062 main
                            *COM*:0000000000000010 A

UNDEFINED SYMBOLS
printf
exit
-------------------------

I have no idea why it's claiming 'printf' and 'exit' are undefined. ?:-/

Cheers!
Rich


Re: VON NEUMANN VS HARVARD


[....]
Quoted text here. Click to load it

Yes you are right, it works on gcc.  Some years back I tried it on quite a
different C compiler and it choked.  Is this a case of a bad compiler or
is it something added in, lets say, the last 7 years.


BTW:  Can this be done with an array?


--
--
snipped-for-privacy@rahul.net   forging knowledge


Re: VON NEUMANN VS HARVARD


Quoted text here. Click to load it
Dang! I don't know! How do you declare the function whose return value is
an array?

int[] foo(int[]); // ?

You have to hard-code the size, I think - or maybe union it onto a
structure? Then you'd still have to have a fixed size.

Probably not. Anybody want to try?

I'm gonna crosspost this to comp.lang.c , but set followups to
sci.electronics.design, because those c.l.c folks are a little touchy
about marginally off-topic posts and banter and stuff.

Thanks,
Rich




Re: VON NEUMANN VS HARVARD



Quoted text here. Click to load it

you should use a pointer as the return value:

int* foo(int[]);

Quoted text here. Click to load it

or you could pass the size as a parameter (emulating multiple return
values) that can be filled in by the function:

int* foo(int[] input, int *size);

and then before your return assign size:

        *size = number_of_members_in_the_returned_array
        return the_array_you_want_to_return

--
burton samograd                    kruhft .at. gmail
kruhft.blogspot.com    www.myspace.com/kruhft    metashell.blogspot.com

Re: VON NEUMANN VS HARVARD



Rich Grise wrote:
Quoted text here. Click to load it

It has always been possible to return structures in C.  You cannot
return an array from a function but you can return a structure
containing an array (as perhaps it's only member) or a pointer that
points into an array.

Robert Gamble


Re: VON NEUMANN VS HARVARD


[...]
Quoted text here. Click to load it

No, not always.  That capability, along with structure assignment, was
added not long after K&R1 (Kernighan & Ritchie, _The C Programming
Language_, 1st Edition, which was the de facto language definition
before the 1989 ANSI standard was published).

Though I suppose in this business a few decades or so is close enough
to "always".

--
Keith Thompson (The_Other_Keith) snipped-for-privacy@mib.org  <http://www.ghoti.net/~kst
San Diego Supercomputer Center             <*>  <http://users.sdsc.edu/~kst
We've slightly trimmed the long signature. Click to see the full one.
Re: VON NEUMANN VS HARVARD


Quoted text here. Click to load it

I thought this might have been the case but I don't have a copy of K&R1
and wasn't able to quickly confirm this with a web search before I
posted.  Thanks for the information.

Quoted text here. Click to load it

Robert Gamble


Re: VON NEUMANN VS HARVARD


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Robert Gamble wrote:
Quoted text here. Click to load it

Sorry, but you are mistaken.

  "There are a number of restrictions on C structures. The essential rules are
  that the only operations that you can perform on a structure are take its
  address with &, and access one of its memebers. This implies that structures
  may not be assigned to or copied as a unit, and that they can not be passed
                                                       ===============
  to or returned from functions."
        =======================

  The C Programming Language
  Brian W. Kernighan * Dennis M. Ritchie
  Copyright (c) 1978 by Bell Telephone Laboratories, Incorporated

It has been possible to pass and return _pointers to structures_ in C, but
only recent standards (i.e. 89 and after) permitted passing and returning
actual structures.


[snip]


HTH
- --
Lew Pitcher

Master Codewright & JOAT-in-training | GPG public key available on request
Registered Linux User #112576 (http://counter.li.org /)
Slackware - Because I know what I'm doing.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)

iD8DBQFEPu5SagVFX4UWr64RAnGiAKCdgETkkIeNzxP5Tv9eRMVoNMNDrACfZsgX
4mJdM+L09jlZnyitjMNHahw=
=ZtRY
-----END PGP SIGNATURE-----

Re: VON NEUMANN VS HARVARD



Quoted text here. Click to load it

No, the ability to pass and return structures was added
into Unix Version 7 C.  Along with the enumeration type.

_Recent Changes to C_,
November 15, 1978,
Page 277, Unix Programmers Manul, V.2
1979, 1983,  Bell Telephone Laboratories
Holt Reinhart and Wilson

There was a warning that the PDP-11 version didn't handle
reentrancy within an interrupt properly, though.

Mark Zenier   snipped-for-privacy@eskimo.com  
Googleproofaddress(account:mzenier provider:eskimo domain:com)


Re: VON NEUMANN VS HARVARD


Quoted text here. Click to load it

That compiler was broken. The C89 standard allowed passing and returning
structures.

Quoted text here. Click to load it

You can't. Not directly.

Quoted text here. Click to load it

Close. Just declare a structure with the array as an element ant return
that. Just be aware that it means the array is getting copied around
which can be rather inefficient.

struct arr_ret {
    int a[5];
};

struct arr_ret foo(int*);

Generally I would pass a pointer to the first element of the return
array instead, just like memcpy, strcpy etc.

Quoted text here. Click to load it

You're question is about C and that is fine here and we don't mind a bit
of banter so I've re-instated the cross-post. Just remove the cross-post
if the thread drifts off C on to other things.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk /
We've slightly trimmed the long signature. Click to see the full one.
Re: VON NEUMANN VS HARVARD


[....]
Quoted text here. Click to load it

But if you do that, you loose the ability to check for overruns.  The
point was that using pointers makes checking very hard to implement.  If
you are only returning a 3 or 4 element array, the cost of the extra
overhead may be worth it.

It was part of my explaination[1] of why the C language is so horrid.
[1] troll

I have to admit it isn't as bad as C++ or Intercal.

--
--
snipped-for-privacy@rahul.net   forging knowledge


Re: VON NEUMANN VS HARVARD


Quoted text here. Click to load it

OK, I can accept that.

Quoted text here. Click to load it

In some respects C is a horrid language and there are a number of things
I wish were different.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk /
We've slightly trimmed the long signature. Click to see the full one.
Re: VON NEUMANN VS HARVARD


Quoted text here. Click to load it

You seem to miss the point that C CAN IN FACT pass and return a complex
data type. You don't need to use a pointer though lots of C programs
do. If you want you can pass the struct itself:

  struct foo {
    int x;
    int y;
  }

  struct foo doubleFoo(struct foo f) {
    f.x = f.x * 2;
    f.y = f.y * 2;
    return f;
  }

  int main(void) {
    struct foo bar;
    bar.x = 1;
    bar.y = 1;
    bar = doubleFoo(bar);
    return 0;
  }


Site Timeline