Welcome, Guest. Please login or register.

Author Topic: Learning C with the Amiga  (Read 32440 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline SamuraiCrow

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2281
  • Country: us
  • Gender: Male
    • Show only replies by SamuraiCrow
Re: Learning C with the Amiga
« Reply #59 on: February 04, 2007, 06:24:33 PM »
Quote

Cymric wrote:
Quote
Karlos wrote:
Wrong again. Constant items (pointers included) may be allocated in write protected pages of memory on some implementations (ok, not amigaos), physically preventing it from being altered after it has been assigned.

Quite true. The following code will run happily on an Amiga:

Code: [Select]
   char *s = "Hi!";
    ....
    s[1] = 'a';
    ....
   

but will crash on a Unix computer because the string 'Hi!' is saved in memory which cannot be written to. The program will crash with a 'segmentation fault', a sure indicator of the program poking in memory where it shouldn't be. The problem is that there is nothing wrong with the above code: it's the implementation by the compiler which fscks things up.



Actually AmigaOS 4.0 final DOES do memory protection on constant data by making it read-only.  It's only versions 3.x and earlier that don't work correctly.

For a better implementation of strings than is present in the C language use the Better String library.  Beware of the dual-licence it is under, though, since neither GPL nor the most recent BSD licence allow for the programmer to place the code under a different licence than it was originally under.
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show only replies by Karlos
Re: Learning C with the Amiga
« Reply #60 on: February 04, 2007, 07:30:09 PM »
@SamuriCrow

Quote
It's only versions 3.x and earlier that don't work correctly.


Perhaps, but we were talking about 3.x anyway since that is what Mel is learning with. The point was only raised to explain the need for "const type*" and wasn't meant to be an attack on amiga os :-D However, I have a nasty feeling your mentioning OS4 and memory protection in the same sentence will trigger a flame war very soon ;-)
int p; // A
 

Offline mel_zoomTopic starter

  • Full Member
  • ***
  • Join Date: Jan 2007
  • Posts: 231
    • Show only replies by mel_zoom
Re: Learning C with the Amiga
« Reply #61 on: February 04, 2007, 07:35:20 PM »
Guys! Can we save this for later? Im only just looking at functions :lol:
I love my MX5!
Please pay a visit
 

Offline mel_zoomTopic starter

  • Full Member
  • ***
  • Join Date: Jan 2007
  • Posts: 231
    • Show only replies by mel_zoom
Re: Learning C with the Amiga
« Reply #62 on: February 07, 2007, 08:08:58 PM »
Hi!

So Ive spent time looking at functions in C since I last posted here. So far so good in that I understand the purpose of functions and Im not particularly struggling with the syntax.

I do have some basic questions and one not so basic question though (which is getting a bit ahead of myself too).

Question 1

Is there a way that a function can return more than one value simultaneously? Its obvious from the function definition syntax so far that you return a single value or nothing at all (void).

However if I can imagine times when returning multiple values together might be useful Im sure other people can and have found ways.

So far I can only think of returning an array or structure or modifying the parameters if you "pass by reference". An array is presumably only any good if you have to return multiple values that are the same "type", right?

Question 2

Can you actually return an array in this way or is it only by reference too? If that is the case wouldnt the array that the reference represents be destroyed when the function returns?

Ive not really looked at structures yet but I understand that they are basically made by putting together more existing types so you could make one that represents the multiple values you want to return. So, would that be a valid solution?

I looked at the other idea using the "pass by reference" idea and I know that this involves pointers and is therefore a likely place to make errors if Im not careful. I dont really want to do that yet even though I am looking at them but I noticed something weird.

The book I have says that normal variables are "passed by value" so you get a copy of them that you are free to alter. It also says that arrays are always "passed by reference" so you get the actual array and not a copy.

I am aware that the array syntax is basically another way of representing a pointer so that kind of makes sense really. I can imagine that this makes things faster compared to copying an array which might be very large.

What I found odd was that structures can be passed by value as well as reference. Why is that? A structure can contain a lot of variables and I imagine theres no reason you couldnt even have an array inside one so a structure could be as big as any array. So...

Question 3

Is there some important reason that structures can be passed by value to a function? When might you do something like that?
I love my MX5!
Please pay a visit
 

Offline SamuraiCrow

  • Hero Member
  • *****
  • Join Date: Feb 2002
  • Posts: 2281
  • Country: us
  • Gender: Male
    • Show only replies by SamuraiCrow
Re: Learning C with the Amiga
« Reply #63 on: February 07, 2007, 08:38:02 PM »
1.  Returning multiple parameters in C requires passing a structure by pointer.  And yes, an array is only good when passing values of the same type.

2.  AFAIK structures cannot be passed by value and must be passed by reference unless C++ has some feature for creating structures/classes on the stack.  It's not recommended to stuff the stack with lots of parameter data on the Amiga since the Amiga has a fixed stack space for each program.

Arrays are stored in memory as pointers so they are always passed by pointer.  (When using the word "reference" you are referring to a C++/Java term that doesn't strictly apply to C.)

3.  I'm not sure why you would want to waste the stack space in doing so.  Normally structures are dynamically allocated with malloc() and passed by pointer to the appropriate function.

Oh, and by the way, you can embed arrays in structures if you like.
 

Offline Hans_

Re: Learning C with the Amiga
« Reply #64 on: February 07, 2007, 08:45:53 PM »
@mel_zoom

With regard to Q3, the only reason I can think of, for passing structures by value to a function would be if the function required a local copy of the data. That would be the case if the function had to modify the data during processing but wasn't allowed to modify the original copy belonging to whatever code called that function.

I have never had to pass a structure by value, ever. Doing so will just slow the program down, particularly if it's a big structure (e.g., contains a large fixed-size array) or that function gets called really often.

Hans
Join the Kea Campus - upgrade your skills; support my work; enjoy the Amiga corner.
https://keasigmadelta.com/ - see more of my work
 

Offline mel_zoomTopic starter

  • Full Member
  • ***
  • Join Date: Jan 2007
  • Posts: 231
    • Show only replies by mel_zoom
Re: Learning C with the Amiga
« Reply #65 on: February 07, 2007, 08:58:24 PM »
samuraicrow:

"AFAIK structures cannot be passed by value and must be passed by reference"

Well, I was looking at this already and have written a test program that works. Did I compile this wrong?

gcc -Wall testbyval.c -o testbyval


The code is

/* test passing structures by value - why does this work? */

#include

struct coord {
  int x;
  int y;
};

struct coord testbyvalue(struct coord o)
{
  o.x++;
  o.y++;
  return o;
}

int main(void)
{
  struct coord c1 = {1,2};
  struct coord c2 = testbyvalue(c1);
  printf("c1 = {%d,%d}\nc2 = {%d,%d}\n}", c1.x, c1.y, c2.x, c2.y);
  return 0;
}

I love my MX5!
Please pay a visit
 

Offline mel_zoomTopic starter

  • Full Member
  • ***
  • Join Date: Jan 2007
  • Posts: 231
    • Show only replies by mel_zoom
Re: Learning C with the Amiga
« Reply #66 on: February 07, 2007, 09:01:30 PM »
hans:

I understand that and I can see why arrays are "by reference" but why are structures allowed to be by value? Especially as they can contain an array even?
I love my MX5!
Please pay a visit
 

Offline koaftder

  • Hero Member
  • *****
  • Join Date: Apr 2004
  • Posts: 2116
    • Show only replies by koaftder
    • http://koft.net
Re: Learning C with the Amiga
« Reply #67 on: February 07, 2007, 09:15:27 PM »
Quote

mel_zoom wrote:
samuraicrow:

"AFAIK structures cannot be passed by value and must be passed by reference"

Well, I was looking at this already and have written a test program that works. Did I compile this wrong?



You passed the structure on the stack instead of passing a pointer to it, and that is perfectly legal and valid. Most of the time we try to avoid this, especially in tight loops as building up and breaking down the stack behind the scenes is slower than just passing a pointer.

It is refreshing to see somebody express a desire to learn C and actually follow through. Even better is that you are making real effort to actually learn the language. In a year you will be telling everybody else how it's done  :-)

 

Offline Louis Dias

Re: Learning C with the Amiga
« Reply #68 on: February 07, 2007, 09:15:43 PM »
Mel,

Even if a structure contains an array, the value within the structure representing the array is a pointer.

ps,
you answered your own questions in asking them for the most part

but remember, I don't know anything so don't believe anything I tell you
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show only replies by Karlos
Re: Learning C with the Amiga
« Reply #69 on: February 07, 2007, 09:27:28 PM »
@lou_dias

Sorry, but I think you misunderstood what Mel was getting at.

struct Struct1 { int someInts[10]; short foo; };

is _very_ different from

struct Struct2 { int* someInts; short foo; };

-edit-

The difference is that in Struct1, you have 10 ints together as a direct block of data followed by a short. In Struct2, you have a single int* pointing to an unknown number of ints (possibly none at all), followed by a short.

They are only the same in terms of the syntax involved in accessing their members.

Quote
but remember, I don't know anything so don't believe anything I tell you


*whistles innocently*
int p; // A
 

Offline Hans_

Re: Learning C with the Amiga
« Reply #70 on: February 07, 2007, 09:30:02 PM »
Quote

mel_zoom wrote:
hans:

I understand that and I can see why arrays are "by reference" but why are structures allowed to be by value? Especially as they can contain an array even?


Because a structure is seen as a data-type whereas an array is not. An array is a method of addressing a set of data of the same type. It's a quirk of the language.

BTW, I think that lou_dias is wrong about arrays in structures. A fixed-length array in a structure is the data itself, not a pointer to the array. Ah, I see that Karlos has already commented on that as I was writing this.

Hans
 
Join the Kea Campus - upgrade your skills; support my work; enjoy the Amiga corner.
https://keasigmadelta.com/ - see more of my work
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show only replies by Karlos
Re: Learning C with the Amiga
« Reply #71 on: February 07, 2007, 09:39:55 PM »
@Mel

Passing structures by value is perfectly legal, but as you guessed and others have pointed out, it's quite slow.

Generally it's better to pass by reference, using a pointer than by value if all you want to do is read from the structure. To ensure that you can't accidentally "poke" the structure thus passed you can use a "const struct coord*".

One reason for the difference is that syntactically arrays and pointers are synonyms for the same underlying entity. Therefore, how would you actually represent passing an array by value when "int* x" and "int[] x" actually represent the same thing?

There are rare times when passing structures by value can make sense and certainly returning them by value can also be useful in some cases. Generally this is true when the structure is small, like your coordinate. The cycle-cost of allocating memory for a small structure and returning a pointer to it (which you also have to remember to free later if you don't want a memory leak) can easily outweigh the cost of simply returning it (or rather a copy of it, allocated on the stack) by value by an order of magnitude*

*this, of course assumes you don't have an instance of the structure already to hand, waiting to be used/modified, in which case, pass it by reference and let the function alter it.

-edit-

Also, if your structure is no bigger than a pointer (possibilities include bitfield structres and unions containing nothing larger than a pointer), performance wise there's no gain in passing by reference.
int p; // A
 

Offline AJCopland

Re: Learning C with the Amiga
« Reply #72 on: February 07, 2007, 10:21:47 PM »
I'm always so wary about posting my code comments as I do this for work but always screw up when not in front of a compiler! Also I've been coding in C++ for the last couple of years and my C isn't strictly ANSI compliant anymore ... end disclaimer there :-D here goes.

1) A function can only "return" a single item. However that item can be a composite such as "struct", a pointer to other information, a reference to another item that does exist or a value.
This is where I might screw up the C vs C++ syntax btw. You don't need to pass in pointers to a function to change their value instead you can pass by reference.

for example:
// you could package all of your return values up like this.
typedef struct compositeItem{
float theHamster;
int downTheStream;
int unrelatedGubbins;
};

//and then your function would return like this.
compositeItem someDumbFunc()
{
compositeItem bodge;
//do funky things that fill compositeItem here
return bodge;
}


That would be one really bad way of doing it :-D instead you can pass by pointer or by reference.

void SonOfDumbFuncPointer( compositeItem *pCompItem, int *pVal )
{
// dereference the pointer to access the values location
(*pCompItem).theHamster = 0.0f;
(*pCompItem).downTheStream = *pVal;
(*pCompItem).unrelatedGubbins = *pVal;
++(*pVal);
}

void SonOfDumbFuncRef( compositeItem &rCompItem, int &rVal )
{
rCompitem.theHamster = 0.0f;
rCompitem.downTheStream = rVal;
rCompitem.unrelatedGubbins = rVal;
++rVal;
}


2) Arrays and pointers are, well ok they're not something to be shied away from in C or there's no point learning the language. You're correct in that the elements of an arrays can only be of one "type". That type can be made of either the language defined base types or your own.
See here for a reasonable explanation. Actually I could have skipped all of the above if I'd thought of this sooner :idea: Passing Parameters

3) You might pass a structure to erm... I dunno, serialise it for lobbing over a network? No, I dunno. If I pass a structure I usually pass by reference or pointer and make it "const" if I don't want it to be modified. I'm sure that there's some really awesome and intelligent reason for passing a structure by value, that... y'know, someone that knows and will seem obvious once they mention it :-D


Hope that didn't confuse things more.

Andy
Be Positive towards the Amiga community!
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show only replies by Karlos
Re: Learning C with the Amiga
« Reply #73 on: February 07, 2007, 10:31:04 PM »
@AJCopeland

Any reason you prefer (*pCompItem).member over pCompItem->member ?
int p; // A
 

Offline Louis Dias

Re: Learning C with the Amiga
« Reply #74 from previous page: February 07, 2007, 10:40:32 PM »
Hans_ wrote:
Quote

It's a quirk of the language.


It's these quirks that make it not a good language for beginners.  Maybe if she ever learns a second language (C++ doesn't count), then she'll see the light at the end of the tunnel.  C is a language with few rules.  How do you write structured code when the language has no uniform structure within it's design.  C is a language designed for low-memory machines because that's all they had when it was designed.  All these "quirks" are just hacks someone added to the compiler at the time because of memory constraints and over time "became part of the language".  C is a hack to not have to write assembly.

Quote
BTW, I think that lou_dias is wrong about arrays in structures. A fixed-length array in a structure is the data itself, not a pointer to the array. Ah, I see that Karlos has already commented on that as I was writing this.

Hans

So if the "rule" is arrays are passed by reference...why wouldn't an array within a structure not be a reference as well?  Oh, I forgot, we are talking about C...but anyway, Karlos and YOU assumed I was responding to her "code" when I was actually responding to her prior set of several questions.  I guess I should have quoted her.  C`est la vie.  (and no, that doesn't say "C is the life")