Passing an array of chars to a function

K

Kevin Goodsell

Jumbo said:
Yes we know this is true from the compilers point of view.
But from the programmers point of view your passing the array not a pointer
to an array.

If that were true, then applying sizeof to the function argument would
give the number of bytes used by the array. This would be quite handy,
and beginners often try to use this technique. They quickly find out
that it doesn't work.

The fact that the argument is actually a pointer is very relevant to the
programmer. If the programmer's point of view is that it is an array,
then the programmer is bound to run into trouble.
The thing is that arrays are passed by ref as opposed to most other data
types, I wouldn't consider this as not passing an array.

That's not true. A pointer to an array is passed by value. There is no
pass-by-reference occurring in this case. Passing a reference to an
array requires different syntax.
Your still passing an array it's just that the behavior is different.
It's to do with your understanding of how arrays work under the hood.

Anyway putting our disagreements aside, what is going on here if arrays are
never passed by val:
#include <iostream>

void foo(const char p1[],const char p2[]){
p1="STUV";
p2="WXYZ";

Pointer assignment that doesn't affect anything in main(). What is this
example supposed to show?
std::cout<< "In foo():\t" << p1 << '\t' << p2 << std::endl;
}

int main(){
const char pch1[]= "ABCD";
const char* pch2= "EFGH";
foo(pch1,pch2);

std::cout<< "In main():\t" << pch1 << '\t' << pch2 << std::endl;
return 0;
}

-Kevin
 
D

Default User

"Jumbo
Consider this:
#include <iostream>

void foo(const char arr1[]){
arr1="ZZZZ";
std::cout<< "In foo():\t"
<<"sizeof array: "<< sizeof arr1
<< "\tvalue\t" << arr1 << std::endl;
}
int main(){
const char arr1[]= "ABCD";
foo(arr1);
std::cout<< "In main():\t"
<<"sizeof array: "<< sizeof arr1
<< "\tvalue\t" << arr1 << std::endl;
return 0;
}

On my system this outputs
In foo(): sizeof array: 4 value: ZZZZ
In main(): sizeof array: 5 value: ABCD

So what's going on here then, Is this non compliant code?

You realize that you just disproved your own point. If arr1 in foo() was
an array, the assignment would have been illegal, requiring a
diagnostic.

Because arr1 is a pointer, you were able to assign a new value to it.
Note that you did not copy the new value "ZZZZ" to arr1 in main(), all
you did was reset the pointer in foo() to point to the string literal
"ZZZZ" instead of the first element of arr1 in main().

I think you'd better learn some more about pointers and arrays before
you attempt to lecture experienced users on the subject. You are
embarrassing yourself.




Brian Rodenborn
 
R

Rolf Magnus

Jumbo said:
Rolf Magnus said:
Jumbo said:
jr wrote:

Sorry for this very dumb question, but I've clearly got a long
way to go! Can someone please help me pass an array into a
function.

You cannot pass arrays into functions. Usually, a pointer to the
array's first element is passed instead.

Of course you pass arrays into functions:
#include <iostream>

void foo(char arr[]){

arr is not an array, but a pointer to its first element.
But that's just what an array is.

Then you didn't understand arrays and pointers, and especially their
difference. Try this:

#include <iostream>
#include <ostream>

void tellsize(char arr[])
{
std::cout << "size of arr in tellsize " << sizeof(arr) << '\n';
}

int main()
{
char arr[] = "Hello world\n";
std::cout << "size of arr in main " << sizeof(arr) << '\n';
tellsize(arr);
}

An array _is_ not a pointer to its first element, but it is _converted_
to one in many, but not all situations. Passing to a function is one of
those situations, using sizeof is one of the other situations.
You can see
that it's not an array, because it doesn't have a size between its
[], and arrays _always_ have a size. The only place where this is
allowed is if you define an array and initialize it, so the size can
be determined from the initializer, like:

You could go into the guts of the computer and say everydata is the
same as it simply a picice of memory.

And a pointer is a totally different piece of memory than an array.
This is like the argument that a char is really an integer etc.

I don't get you here. The C++ standard defines char as an integer type,
so what else would it be? It just happens to be the type that is often
used to store characters, though that probably will change in the
future, with wide characters and multi-language programs that need
unicode support.
Just because an array happens to be turned into a pointer by the
compiler when you pass it to a function deoesn't mean to say that
we're not passing an array to a function.

Yes it is. You can determine the size of an array, but if you pass a
pointer to its first element to a function, you will only get the size
of a pointer, not of the array, since a pointer was passed to the
function, not an array. Another difference is that passing a value to a
funciton means that this value is copied, and the function works on a
copy. This is not the case for arrays, since arrays are not copyable.
The funciton can access the original array through a pointer, not a
local copy.
We're still passing an array to a function and it's not a copy.

That's my point. Passing something means making a copy of it, unless you
pass a reference.
So as we are passing the actually array and not a copy it even more
true to say we ARE passsing an array to a function.

No, it makes it actually wrong.
You seem to be meaning that passing an array to a function is only
passing the array if it passes a copy.

Yes, because that's what passing a value means in C++.
 
R

Rolf Magnus

Jumbo said:
But you're still wrong. The language specifically says that the
function parameter types of type array are explicitly changed to
pointer.

void foo(int []);
and
void foo(int*)

mean exactly the same thing.

Passing an array to such a function invokes an array-to-pointer
conversion before the function isn't called. What is passed is the
pointer.
Yes we know this is true from the compilers point of view.
But from the programmers point of view your passing the array not a
pointer to an array.

The C++ standard says what is done from the programmer's view, and it
says that the array is converted to a pointer, and that pointer is
passed as parameter.
The thing is that arrays are passed by ref as opposed to most other
data types, I wouldn't consider this as not passing an array.
Your still passing an array it's just that the behavior is different.
It's to do with your understanding of how arrays work under the hood.

You don't have to understand what goes on under the hood. Just
understand how the terms are defined in C++.
Anyway putting our disagreements aside, what is going on here if
arrays are never passed by val:
#include <iostream>

void foo(const char p1[],const char p2[]){
p1="STUV";
p2="WXYZ";
std::cout<< "In foo():\t" << p1 << '\t' << p2 << std::endl;
}

int main(){
const char pch1[]= "ABCD";

Ok, we have an array.
const char* pch2= "EFGH";

and a pointer.
foo(pch1,pch2);

A pointer to the first element of pch1 is passed to foo, as well as the
pointer pch2. In foo, the local copies of those pointers get the
addresses of new string literals assigned. After the function returns,
those pointers don't exist anymore. The original pointer pch2 wasn't
changed, and neither the temporary pointer that was made from the array
pch1 or any character in that array.
 
J

Jumbo

Rolf Magnus said:
Jumbo said:
Rolf Magnus said:
Jumbo wrote:


jr wrote:

Sorry for this very dumb question, but I've clearly got a long
way to go! Can someone please help me pass an array into a
function.

You cannot pass arrays into functions. Usually, a pointer to the
array's first element is passed instead.

Of course you pass arrays into functions:
#include <iostream>

void foo(char arr[]){

arr is not an array, but a pointer to its first element.
But that's just what an array is.

Then you didn't understand arrays and pointers, and especially their
difference. Try this:

#include <iostream>
#include <ostream>

void tellsize(char arr[])
{
std::cout << "size of arr in tellsize " << sizeof(arr) << '\n';
}

int main()
{
char arr[] = "Hello world\n";
std::cout << "size of arr in main " << sizeof(arr) << '\n';
tellsize(arr);
}

An array _is_ not a pointer to its first element, but it is _converted_
to one in many, but not all situations. Passing to a function is one of
those situations, using sizeof is one of the other situations.
You can see
that it's not an array, because it doesn't have a size between its
[], and arrays _always_ have a size. The only place where this is
allowed is if you define an array and initialize it, so the size can
be determined from the initializer, like:

You could go into the guts of the computer and say everydata is the
same as it simply a picice of memory.

And a pointer is a totally different piece of memory than an array.
This is like the argument that a char is really an integer etc.

I don't get you here. The C++ standard defines char as an integer type,
so what else would it be? It just happens to be the type that is often
used to store characters, though that probably will change in the
future, with wide characters and multi-language programs that need
unicode support.

Well that is very confusing.
On my system a char is 1 byte and an integer is 4 bytes.
So how is a char type an integer type?
Yes it is. You can determine the size of an array, but if you pass a
pointer to its first element to a function, you will only get the size
of a pointer, not of the array, since a pointer was passed to the
function, not an array. Another difference is that passing a value to a
funciton means that this value is copied, and the function works on a
copy. This is not the case for arrays, since arrays are not copyable.
The funciton can access the original array through a pointer, not a
local copy.

Consider the following array:

int* Array = new int[128];

Do you suggest this is not an array since you cannot determine the size of
it?
According to your idea there is no array here it's simply a pointer.
The pointer is the identifier for the array.


This is the same when you pass an array to a function, the pointer to the
first index is passed as this is the identifier for the array.
You may prefer to call it a pointer and that's fine but your saying that
it's not an array and it is an array.
It can still be indexed like an array so how do you explain that if it's not
an array?

That's my point. Passing something means making a copy of it, unless you
pass a reference.
No there are two ways to pass
by ref (not meaning the reference type)
by val

Where is it defined that passing to a function means *making a copy of it* ?
No, it makes it actually wrong.


Yes, because that's what passing a value means in C++.
Yeah well passing by value is a different thing from simply passing.
If I say I can't pass an object to a function...
I'm not saying I can't pass it by value but I can pass it by reference am I?
Not being able to pass an object is different from not being able to make a
copy of an object.
 
J

Jumbo

Rolf Magnus said:
Jumbo said:
But you're still wrong. The language specifically says that the
function parameter types of type array are explicitly changed to
pointer.

void foo(int []);
and
void foo(int*)

mean exactly the same thing.

Passing an array to such a function invokes an array-to-pointer
conversion before the function isn't called. What is passed is the
pointer.
Yes we know this is true from the compilers point of view.
But from the programmers point of view your passing the array not a
pointer to an array.

The C++ standard says what is done from the programmer's view, and it
says that the array is converted to a pointer, and that pointer is
passed as parameter.

No the array is not converted into a pointer.
Think of an array as a series of cubby holes in memory.
Think of a pointer as a variable that holds a memory address.

If your array is an array of 500 integers how can you convert this to a
single variable ?
You don't have to understand what goes on under the hood. Just
understand how the terms are defined in C++.

It's better to have a little understanding of what goes on under the hood.
Anyway putting our disagreements aside, what is going on here if
arrays are never passed by val:
#include <iostream>

void foo(const char p1[],const char p2[]){
p1="STUV";
p2="WXYZ";
std::cout<< "In foo():\t" << p1 << '\t' << p2 << std::endl;
}

int main(){
const char pch1[]= "ABCD";

Ok, we have an array.
const char* pch2= "EFGH";

and a pointer.
foo(pch1,pch2);

A pointer to the first element of pch1 is passed to foo, as well as the
pointer pch2. In foo, the local copies of those pointers get the
addresses of new string literals assigned. After the function returns,
those pointers don't exist anymore. The original pointer pch2 wasn't
changed, and neither the temporary pointer that was made from the array
pch1 or any character in that array.
std::cout<< "In main():\t" << pch1 << '\t' << pch2 << std::endl;
return 0;
}

So we are passing pch1 which is an array to a function. What's so difficult
to understand about that?
How can the compile convert it to a pointer?
Assume an integer is 4 bytes and we have an array of 500 integers that takes
up 2000 bytes right?
How can we put 2000 bytes into a pointer that's only 4 bytes?

The compiler does not convert an array to a pointer.

Here's another example:
int* array = new int[500];

Do you suggest the identifier 'array' is not an array?
Are arrays on the heap not real arrays or something?

Am I missing something blatently obvious , is there a way to squeeze a large
array into a single pointer that I don't know about?

HTH
Jumbo.
 
J

Jumbo

Default User said:
"Jumbo
Consider this:
#include <iostream>

void foo(const char arr1[]){
arr1="ZZZZ";
std::cout<< "In foo():\t"
<<"sizeof array: "<< sizeof arr1
<< "\tvalue\t" << arr1 << std::endl;
}
int main(){
const char arr1[]= "ABCD";
foo(arr1);
std::cout<< "In main():\t"
<<"sizeof array: "<< sizeof arr1
<< "\tvalue\t" << arr1 << std::endl;
return 0;
}

On my system this outputs
In foo(): sizeof array: 4 value: ZZZZ
In main(): sizeof array: 5 value: ABCD

So what's going on here then, Is this non compliant code?

You realize that you just disproved your own point. If arr1 in foo() was
an array, the assignment would have been illegal, requiring a
diagnostic.

No I have just proved that arrays can be passed to functions.
Why would the assignment have been illegal , what's wrong with assigning a
character array to a character array?
It seems the only thing needing diagnosed is your condition. :)
Because arr1 is a pointer, you were able to assign a new value to it.
So you can't assign new values to an array?
Note that you did not copy the new value "ZZZZ" to arr1 in main(), all
you did was reset the pointer in foo() to point to the string literal
"ZZZZ" instead of the first element of arr1 in main().

I didn't want to copy the value "ZZZZ" in main,
I was demonstrating how to pass an array to a function, something you seem
to think of as an impossibility.
I think you'd better learn some more about pointers and arrays before
you attempt to lecture experienced users on the subject. You are
embarrassing yourself.
Ha Ha
The only person embarrassing themselves around here is you ya half-wit.

HTH :)
 
K

Kevin Goodsell

Jumbo said:
No the array is not converted into a pointer.

Yes it is.
Think of an array as a series of cubby holes in memory.
Think of a pointer as a variable that holds a memory address.

If your array is an array of 500 integers how can you convert this to a
single variable ?

It's the address of the first one. This *is* the way the language works,
regardless of how much you deny it.
It's better to have a little understanding of what goes on under the hood.

I think what Rolf is getting at is that you can't really know what's
going on "under the hood" because an implementation isn't necessarily
constrained in how it implements things - optimized code, for example,
may bear very little resemblance to the original code. The Standard
allows the implementation to mutilate the code however it wants, so long
as the observable result is the same.
So we are passing pch1 which is an array to a function. What's so difficult
to understand about that?

Regardless of how you simplify it, you are passing a copy of a pointer
to the function. Arrays and pointers are different, so this is an
important distinction.
How can the compile convert it to a pointer?

I doubt I'm the only one who's getting a little tired of explaining
this. The compiler interprets the array's name as a pointer to the first
element of the array. There's even a section of the standard that
specifically talks about this:

4.2 Array-to-pointer conversion [conv.array]

1 An lvalue or rvalue of type "array of N T" or "array of unknown bound
of T" can be converted to an rvalue of type "pointer to T." The
result is a pointer to the first element of the array.
Assume an integer is 4 bytes and we have an array of 500 integers that takes
up 2000 bytes right?
How can we put 2000 bytes into a pointer that's only 4 bytes?

Why would we need to?
The compiler does not convert an array to a pointer.

The implementation does.
Here's another example:
int* array = new int[500];

Do you suggest the identifier 'array' is not an array?

That's correct. 'array' is a pointer.
Are arrays on the heap not real arrays or something?

They are, but they are unnamed. They can only be referred to by a pointer.
Am I missing something blatently obvious ,

Yes, you are. Well, it's not obvious, but it's also not difficult to
grasp once it's been explained.
is there a way to squeeze a large
array into a single pointer that I don't know about?

There's no reason to do that.

-Kevin
 
E

E. Robert Tisdale

jr said:
Sorry for this very dumb question, but I've clearly got a long way to go!
Can someone please help me pass an array into a function.
Here's a starting point.

void DoStuff(TCHAR theArray[]) {
// ...
}

void TheMainFunc(void) {

// Body of code...

TCHAR myArray[512];
DoStuff(myArray);
}


I can't quite get my head around what the variable "myArray" is.
Is it a pointer to a memory address that would hold a TCHAR
(a wide char if UNICODE)?

You need to define

void DoStuff(TCHAR theArray[512]);

or


void DoStuff(TCHAR theArray[]);

or

void DoStuff(TCHAR* theArray);
 
K

Kevin Goodsell

Jumbo said:
No I have just proved that arrays can be passed to functions.

You can't prove what isn't true, and your code didn't even approach
proving what you claim.
Why would the assignment have been illegal , what's wrong with assigning a
character array to a character array?

Assignment to an array is forbidden.

8.3.4 Arrays [dcl.array]

5 [Note: conversions affecting lvalues of array type are described in
_conv.array_. Objects of array types cannot be modified, see
_basic.lval_. ]
It seems the only thing needing diagnosed is your condition. :)

....

No comment.
So you can't assign new values to an array?

No, you cannot.
I didn't want to copy the value "ZZZZ" in main,
I was demonstrating how to pass an array to a function, something you seem
to think of as an impossibility.

He's correct. The standard agrees with him.
Ha Ha
The only person embarrassing themselves around here is you ya half-wit.

If you aren't embarrassed, then you should be. In any case, your
cluelessness coupled with your abusiveness makes you no longer worth my
time.

*PLONK*

-Kevin
 
E

E. Robert Tisdale

David said:
jr is alleged to have written:
TCHAR myArray[512];
DoStuff(myArray);
}

void DoStuff(TCHAR theArray) {

void DoStuff(TCHAR* theArray) {
I can't quite get my head around what the variable "myArray" is.
Is it a pointer to a memory address that would hold a TCHAR?
(a wide char if UNICODE)?

No, it's not a pointer,
it's the actual storage for 256 instances of TCHAR.

Actually, myArray is the *name* of the array.
It is *not* a pointer and cannot be reseated.

The formal argument theArray *is* a pointer and *can* be reseated
even if you declare

void DoStuff(TCHAR theArray[]);

or even

void DoStuff(TCHAR theArray[512]);

When you invoke

DoStuff(myArray);

the compiler implicitly converts myArray
into a pointer to its first element.
But you often may refer to it as if it was a pointer
and C is very ambivalent about that, converting
the array variable name to a pointer with little provocation
where non-array types would require operator& to get the pointer.
C++ would probably prefer to consistently require the operator&

I don't think so.
But maybe an example would help clarify what you meant.
 
J

Jumbo

Kevin Goodsell said:
Yes it is. No its not. :)


It's the address of the first one. This *is* the way the language works,
regardless of how much you deny it.

Oh so now your not actually converting the array, your converting the array
identifier into a pointer to the first element?
hood.

I think what Rolf is getting at is that you can't really know what's
going on "under the hood" because an implementation isn't necessarily
constrained in how it implements things - optimized code, for example,
may bear very little resemblance to the original code. The Standard
allows the implementation to mutilate the code however it wants, so long
as the observable result is the same.
So if the implementation can do what it likes then it can pass arrays to
functions if it likes no?
Regardless of how you simplify it, you are passing a copy of a pointer
to the function. Arrays and pointers are different, so this is an
important distinction.
Yes an array is a concept of memory allocation and a pointer is a different
type of memory that holds an address( it points to another location in
memory) , hence the name pointer.
How can the compile convert it to a pointer?

I doubt I'm the only one who's getting a little tired of explaining
this. The compiler interprets the array's name as a pointer to the first
element of the array. There's even a section of the standard that
specifically talks about this:

4.2 Array-to-pointer conversion [conv.array]

1 An lvalue or rvalue of type "array of N T" or "array of unknown bound
of T" can be converted to an rvalue of type "pointer to T." The
result is a pointer to the first element of the array.

It says an array *can* be blah blah ......
This doesn't prove anything you've said yourself the implementation can
basically do what it likes.
Why would we need to?
Well how else would you convert the array to a pointer?
The implementation does.
You've said yourself that the implementation is free to do what it wants
right?
So how can you state what any implementation does?
Here's another example:
int* array = new int[500];

Do you suggest the identifier 'array' is not an array?

That's correct. 'array' is a pointer.
Are arrays on the heap not real arrays or something?

They are, but they are unnamed. They can only be referred to by a pointer.
So it's a real array but it's unnamed. hmmm
But what about the identifier 'array', isn't that it's name?

So what if I did:
#include <iostream>

#define ARRAY128(a)(a=new char[128])
typedef char* ARRAYT;

int main()
{
ARRAYT arrayidentifier;
ARRAY128(arrayidentifier);
for(int i=0; i<128; ++i){
arrayidentifier = i;
std::cout<< i <<": "<< arrayidentifier<<" \t";
}
}

Is this an unnamed array of does this array have a name?
Can this array be passed to a function?

You seem to foget that almost every variable is stored someplace in memory ,
therefore almost every variable is essentially a memory address.
If you say that an array is not an array because it's simply a pointer to an
area in memory then you'd be aswell saying that for every type.
Yes, you are. Well, it's not obvious, but it's also not difficult to
grasp once it's been explained.

What exactly are you trying to explain?
There's no reason to do that.
Then there's no need to convert anything.

Jumbo.
 
J

Jumbo

Kevin Goodsell said:
Jumbo said:
No I have just proved that arrays can be passed to functions.

You can't prove what isn't true, and your code didn't even approach
proving what you claim.
Why would the assignment have been illegal , what's wrong with assigning a
character array to a character array?

Assignment to an array is forbidden.

8.3.4 Arrays [dcl.array]

5 [Note: conversions affecting lvalues of array type are described in
_conv.array_. Objects of array types cannot be modified, see
_basic.lval_. ]
It seems the only thing needing diagnosed is your condition. :)
So all array are constant now?
...

No comment. ditto.

No, you cannot.

Well if you really think this your obviously a bit of a crackpot.
He's correct. The standard agrees with him.

THe standards don't agree with anyone.
If you aren't embarrassed, then you should be. In any case, your
cluelessness coupled with your abusiveness makes you no longer worth my
time. LOL :).

*PLONK*
Glad to see the back of you.
Good riddens.
:)
 
K

Karl Heinz Buchegger

"Jumbo
So if the implementation can do what it likes then it can pass arrays to
functions if it likes no?

No it can not.
If it does, it is no longer a C++ compiler.

Plain and simple.
How can the compile convert it to a pointer?

I doubt I'm the only one who's getting a little tired of explaining
this. The compiler interprets the array's name as a pointer to the first
element of the array. There's even a section of the standard that
specifically talks about this:

4.2 Array-to-pointer conversion [conv.array]

1 An lvalue or rvalue of type "array of N T" or "array of unknown bound
of T" can be converted to an rvalue of type "pointer to T." The
result is a pointer to the first element of the array.

It says an array *can* be blah blah ......
This doesn't prove anything you've said yourself the implementation can
basically do what it likes.

and somewhere else in the standard it is explicitely written down, that
an array undergoes this Array-to-pointer conversion, if the name of
an array shows up in an argument list of a function call.
Well how else would you convert the array to a pointer?

By taking the address of the first element of the array and use this
address as pointer value. (See above: 4.2 Array-to-pointer
conversion).
Here's another example:
int* array = new int[500];

Do you suggest the identifier 'array' is not an array?

That's correct. 'array' is a pointer.
Are arrays on the heap not real arrays or something?

They are, but they are unnamed. They can only be referred to by a pointer.
So it's a real array but it's unnamed. hmmm
But what about the identifier 'array', isn't that it's name?

Yes. But 'array' in the above is a pointer. You wrote it to
be a pointer

int* array

Remeber?

This pointer is assigned the starting address of an array. (How can this
be done? Same thing: 4.2 - by taking the address of the first array alement
und using that address as the address of the array).
So what if I did:
#include <iostream>

#define ARRAY128(a)(a=new char[128])
typedef char* ARRAYT;

int main()
{
ARRAYT arrayidentifier;
ARRAY128(arrayidentifier);
for(int i=0; i<128; ++i){
arrayidentifier = i;
std::cout<< i <<": "<< arrayidentifier<<" \t";
}
}

Is this an unnamed array of does this array have a name?


The array still doesn't have a name.
But the pointer pointing to it has: arrayidentifier
Can this array be passed to a function?

Arrays are never passed to functions. Only pointers to them are.
When will you stop claiming silly things.
You seem to foget that almost every variable is stored someplace in memory ,

And you seem to forget what pointers really are.
There is a difference between:

int m[3];

and

int* n = new int [3];

the former looks like this:

m
+------+
| |
+------+
| |
+------+
| |
+------+

while the later looks like this:


n
+------+ +-----+
| o--------------->| |
+------+ +-----+
| |
+-----+
| |
+-----+
 
K

Karl Heinz Buchegger

"Jumbo
Well if you really think this your obviously a bit of a crackpot.

Learn the language.
You cannot assign arrays. That's how it is since at least 20 years in C
and C++ didn't change it.
 
R

Rolf Magnus

Jumbo said:
Oh so now your not actually converting the array, your converting the
array identifier into a pointer to the first element?

You should first get an understanding of what "convert" means in C++. It
means that you take an existing object and create from it a new object
that is another type. This doesn't neccesarily mean putting all the
data into the new object.
So if the implementation can do what it likes then it can pass arrays
to functions if it likes no?

Yes, as long as it behaves as if the array was not passed.
Regardless of how you simplify it, you are passing a copy of a
pointer to the function. Arrays and pointers are different, so this
is an important distinction.
Yes an array is a concept of memory allocation and a pointer is a
different type of memory that holds an address( it points to another
location in memory) , hence the name pointer.
How can the compile convert it to a pointer?

I doubt I'm the only one who's getting a little tired of explaining
this. The compiler interprets the array's name as a pointer to the
first element of the array. There's even a section of the standard
that specifically talks about this:

4.2 Array-to-pointer conversion
[conv.array]

1 An lvalue or rvalue of type "array of N T" or "array of unknown
bound
of T" can be converted to an rvalue of type "pointer to T."
The result is a pointer to the first element of the array.

It says an array *can* be blah blah ......

Right, and that's what you doubt above (and below, too).
This doesn't prove anything you've said yourself the implementation
can basically do what it likes.

No. He said that under the hood, it can do what it likes, as long as the
behaviour is like the standard says. This is called the as-if rule.
Well how else would you convert the array to a pointer?

You are under the false assumption that "conversion" means putting all
the bytes of an object into another. The iostreams have a conversion
operator to void*. So how is a whole stream object pressed into a
void*?
You've said yourself that the implementation is free to do what it
wants right?
So how can you state what any implementation does?

See above.
Here's another example:
int* array = new int[500];

Do you suggest the identifier 'array' is not an array?

That's correct. 'array' is a pointer.
Are arrays on the heap not real arrays or something?

They are, but they are unnamed. They can only be referred to by a
pointer.
So it's a real array but it's unnamed.

Yes, just like any other dynamically allocated object.
hmmm
But what about the identifier 'array', isn't that it's name?

No. It's the name of a pointer that points to its first element. If you
lose that pointer, the array is still there, but can't be accessed,
because it doen't have a name and there is no pointer to it.
So what if I did:
#include <iostream>

#define ARRAY128(a)(a=new char[128])
typedef char* ARRAYT;

int main()
{
ARRAYT arrayidentifier;
ARRAY128(arrayidentifier);
for(int i=0; i<128; ++i){
arrayidentifier = i;
std::cout<< i <<": "<< arrayidentifier<<" \t";
}
}

Is this an unnamed array of does this array have a name?


It is unnamed.
Can this array be passed to a function?

No, it can't. Using the preprocessor to hide the fact that ARRAYT is a
pointer won't change that.
You seem to foget that almost every variable is stored someplace in
memory , therefore almost every variable is essentially a memory
address.

No. It _has_ a memory address that you can put into a pointer.
If you say that an array is not an array because it's simply
a pointer to an area in memory

_You_ are saying that, not Kevin. I quote from another posting from you:
But that's just what an array is.
then you'd be aswell saying that for every type.

_You_ were claiming that an array is a pointer and passing a pointer to
a function means passing the array and when you were told that this
 
R

Rolf Magnus

Jumbo said:
Well that is very confusing.
On my system a char is 1 byte and an integer is 4 bytes.
So how is a char type an integer type?

Ok, I have to admit that char is not an integer type, but it is an
integral type. And signed char and unsigned char still are integer
types. Some quotes from the chapter 3.9.1 "Fundamental types" of the
C++ standard:

2 There are four signed integer types: "signed char", "short int",
"int", and "long int". ...

3 For each of the signed integer types, there exists a corresponding
(but different) unsigned integer type: "unsigned char", "unsigned
short int", "unsigned int", and "unsigned long int"...

...

7 Types bool, char, wchar_t, and the signed and unsigned integer
types are collectively called integral types. ...
Yes it is. You can determine the size of an array, but if you pass a
pointer to its first element to a function, you will only get the
size of a pointer, not of the array, since a pointer was passed to
the function, not an array. Another difference is that passing a
value to a funciton means that this value is copied, and the function
works on a copy. This is not the case for arrays, since arrays are
not copyable. The funciton can access the original array through a
pointer, not a local copy.

Consider the following array:

int* Array = new int[128];

Do you suggest this is not an array since you cannot determine the
size of it?

Depends on what you refer to as 'this'. 'Array' is a pointer, and you
can determine its size. It would be 4 on my machine. The array that it
points to doesn't have a name, and therefore, its size cannot be
determined, since sizeof either needs a type or the name of a variable.
Have you ever tried to determine the size of that array, I mean by
experimenting with a real compiler? I would love to see how you can
find out that size.
According to your idea there is no array here it's simply a pointer.
The pointer is the identifier for the array.

No. The array doesn't have an identifier.
This is the same when you pass an array to a function, the pointer to
the first index is passed as this is the identifier for the array.
You may prefer to call it a pointer and that's fine but your saying
that it's not an array and it is an array.

Again: A pointer is _not_ an array. Therefore, what you pass cannot be a
pointer and an array at the same time. It can only be _one_.
It can still be indexed like an array so how do you explain that if
it's not an array?

The indexing is a pointer operation. Writing:

ptr[4] = 5;

is just a more convenient way of writing:

*(ptr + 4) = 5;

i.e. writing 5 into the address that is 4 beyond the pointer 'ptr'. And
since you can write it the other way round, too:

*(4 + ptr) = 5;

You can do the same with the index operator:

4[ptr] = 5;

Still, 4 is not an array, and ptr not an index into it. When you use the
index operator on an array, this array is first converted into a
pointer to its first element, so that the index operator actually works
on a pointer.
No there are two ways to pass
by ref (not meaning the reference type)

Passing by reference means passing a reference. If you pass a pointer,
you pass a pointer. Nothing else.
by val

Where is it defined that passing to a function means *making a copy of
it* ?

Passing by value does. Passing an array by reference is possible, and
that indeed doesn't copy it. That would look e.g. like:

#include <iostream>

void myfunc(int (&arr)[100])
{
std::cout << sizeof(arr) // prints the size of the array
<< std::endl;
}

int main()
{
int arr[100];
myfunc(arr);
}
Yeah well passing by value is a different thing from simply passing.

Passing by value _is_ "simply passing". If you want to simply pass an
int, you do:

void myfunc(int i) // pass an int - by value
{
}

If you instead want to pass by reference, you have to explicitly say so:

void myfunc(int& i) // by reference, not "simply" by value
{
}
If I say I can't pass an object to a function...
I'm not saying I can't pass it by value but I can pass it by reference
am I?

Yes, and I showed above what passing an arary by reference looks like.
It's of limited use though, because the size is hard-coded in the
function.
Not being able to pass an object is different from not being
able to make a copy of an object.

Yes.
 
J

Jumbo

Rolf Magnus said:
You should first get an understanding of what "convert" means in C++. It
means that you take an existing object and create from it a new object
that is another type. This doesn't neccesarily mean putting all the
data into the new object.

ok here's the array:
int* array = new int[128];

So what do you want to convert?

You mean something like this:
array = (int*) array;
????

I don't understand what you need to convert , I don't need to covnert
anything when I use arrays.
What are you talking about converting?
Yes, as long as it behaves as if the array was not passed.
Well I got somebody else arguing this point.
Seen as it wasn't my point in the first place and nothing to do with me.
perhapss you and Karl should take this up.
So we are passing pch1 which is an array to a function. What's so
difficult to understand about that?

Regardless of how you simplify it, you are passing a copy of a
pointer to the function. Arrays and pointers are different, so this
is an important distinction.
Yes an array is a concept of memory allocation and a pointer is a
different type of memory that holds an address( it points to another
location in memory) , hence the name pointer.
How can the compile convert it to a pointer?

I doubt I'm the only one who's getting a little tired of explaining
this. The compiler interprets the array's name as a pointer to the
first element of the array. There's even a section of the standard
that specifically talks about this:

4.2 Array-to-pointer conversion
[conv.array]

1 An lvalue or rvalue of type "array of N T" or "array of unknown
bound
of T" can be converted to an rvalue of type "pointer to T."
The result is a pointer to the first element of the array.

It says an array *can* be blah blah ......

Right, and that's what you doubt above (and below, too).

No I don't doubt anything I *know* I can pass an array to a function.
No. He said that under the hood, it can do what it likes, as long as the
behaviour is like the standard says. This is called the as-if rule.

oh right so it can't do what it likes at all then.
That's a condraction in terms.
It can do what it likes as long as what it likes is not one of the things
that's not allowed (condradiction in terms, doesn't make sense to me)
You are under the false assumption that "conversion" means putting all
the bytes of an object into another. The iostreams have a conversion
operator to void*. So how is a whole stream object pressed into a
void*?
Well it's not I never said it was. :)
You've said yourself that the implementation is free to do what it
wants right?
So how can you state what any implementation does?

See above.
Here's another example:
int* array = new int[500];

Do you suggest the identifier 'array' is not an array?

That's correct. 'array' is a pointer.

Are arrays on the heap not real arrays or something?

They are, but they are unnamed. They can only be referred to by a
pointer.
So it's a real array but it's unnamed.

Yes, just like any other dynamically allocated object.

So does this mean we can't pass any dynamically created objects to
functions?
No. It's the name of a pointer that points to its first element. If you
lose that pointer, the array is still there, but can't be accessed,
because it doen't have a name and there is no pointer to it.

But what if I copied the memory address in another variable or even in a
file or something.
Then you could destroy the whole program and I could still access the array.
if nothing had overwritten that area of memory it could still contain the
same values too. So we could have cross program arrays passing the address
via files.
Then what if I encoded the memory address into a character string then it
could be classified as the name of the array then no?
So what if I did:
#include <iostream>

#define ARRAY128(a)(a=new char[128])
typedef char* ARRAYT;

int main()
{
ARRAYT arrayidentifier;
ARRAY128(arrayidentifier);
for(int i=0; i<128; ++i){
arrayidentifier = i;
std::cout<< i <<": "<< arrayidentifier<<" \t";
}
}

Is this an unnamed array of does this array have a name?


It is unnamed.

Then what shall we name it?
Do you have one of then books for expecting parents?
No, it can't. Using the preprocessor to hide the fact that ARRAYT is a
pointer won't change that.

What if I did this:
template<class ARRAY>
void foo(ARRAY arrayidentifier){
}

then passed arrayidentifier to this function. Am I not passing the array to
this function?
No. It _has_ a memory address that you can put into a pointer.
Then surely the pointer is the name or identifier for that particular area
of memory.
Otherwise we'de be going around calling everything that area of memory with
no name at offset blah blah blah.
_You_ are saying that, not Kevin. I quote from another posting from you:

It's you's who are saying array identifiers are pointers and not arrays,
don't try and turn the tables at this stage.
Were you going to quote something?
 
J

Jumbo

Karl Heinz Buchegger said:
"Jumbo

No it can not.
If it does, it is no longer a C++ compiler.
Oh well it's not me who's saying that you better take it up with them are.
You know me well enough by now to know I don't do silly things like quote
from the standards about how compilers have to behave.
Plain and simple.
You certainly seem to be clear about that .
How can the compile convert it to a pointer?

I doubt I'm the only one who's getting a little tired of explaining
this. The compiler interprets the array's name as a pointer to the first
element of the array. There's even a section of the standard that
specifically talks about this:

4.2 Array-to-pointer conversion [conv.array]

1 An lvalue or rvalue of type "array of N T" or "array of unknown bound
of T" can be converted to an rvalue of type "pointer to T." The
result is a pointer to the first element of the array.

It says an array *can* be blah blah ......
This doesn't prove anything you've said yourself the implementation can
basically do what it likes.

and somewhere else in the standard it is explicitely written down, that
an array undergoes this Array-to-pointer conversion, if the name of
an array shows up in an argument list of a function call.

And we still pass an array to the function.
What the compiler does with it does not alter the fact that we have passed
an array to a function.
By taking the address of the first element of the array and use this
address as pointer value. (See above: 4.2 Array-to-pointer
conversion).

But the value of an array is exactly this so why would you need to convert
anything.
Have you ever dereferenced an array?
I don't see where the conversion comes in. What are you converting?

int* anArray = new int[128]

Why do you need to convert this to pass it to a function?

I don't see why they're making a big fuss about passing arrays to functions.
There's no need to convert anything.

Here's another example:
int* array = new int[500];

Do you suggest the identifier 'array' is not an array?

That's correct. 'array' is a pointer.

Are arrays on the heap not real arrays or something?

They are, but they are unnamed. They can only be referred to by a pointer.
So it's a real array but it's unnamed. hmmm
But what about the identifier 'array', isn't that it's name?

Yes. But 'array' in the above is a pointer. You wrote it to
be a pointer

No I wrote it to be an array. It's an array
I cannot treat this array identifier as if it were a pointer to an int.
This identifier is an array identifier and it MUST be treated as such.

I don't see where you get off on calling arrays pointers. We all know that
under the hood it points to the first element.
Once it has been allocated storage for an array it becomes an array
identifier.
int* array

Remeber?

This pointer is assigned the starting address of an array. (How can this
be done? Same thing: 4.2 - by taking the address of the first array alement
und using that address as the address of the array).

Yes we don't need a lecture on array indexing.
So what if I did:
#include <iostream>

#define ARRAY128(a)(a=new char[128])
typedef char* ARRAYT;

int main()
{
ARRAYT arrayidentifier;
ARRAY128(arrayidentifier);
for(int i=0; i<128; ++i){
arrayidentifier = i;
std::cout<< i <<": "<< arrayidentifier<<" \t";
}
}

Is this an unnamed array of does this array have a name?


The array still doesn't have a name.
But the pointer pointing to it has: arrayidentifier


So what if I took the value of that pointer( the address) would that be the
name of the array?
Arrays are never passed to functions. Only pointers to them are.
When will you stop claiming silly things.
But then I could say no variables are ever passed to functions, only either
copies of varaibles or pointers to varaibles are passed.
The actual memory location is not actually passed as that would be silly.
You can't move the physical memory location into a function.
You seem to foget that almost every variable is stored someplace in
memory ,

And you seem to forget what pointers really are.
There is a difference between:

int m[3];

and

int* n = new int [3];

the former looks like this:

m
+------+
| |
+------+
| |
+------+
| |
+------+

while the later looks like this:


n
+------+ +-----+
| o--------------->| |
+------+ +-----+
| |
+-----+
| |
+-----+
Is that your attempt at explaining the difference between program memory
area and free store memory areas? :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top