type of &array

H

hpsoar

int array[] = {1, 2, 3};
then what is the type of &array? Is it int**, or some other type?
 
W

WANG Cong

hpsoar said:
int array[] = {1, 2, 3};
then what is the type of &array? Is it int**, or some other type?

It should be int* instead of int **, because an array name is _not_
a pointer.
 
K

Kai-Uwe Bux

WANG said:
hpsoar said:
int array[] = {1, 2, 3};
then what is the type of &array? Is it int**, or some other type?

It should be int* instead of int **, because an array name is _not_
a pointer.

You might want to test that hypothesis:

#include <iostream>

void func ( ) {
std::cout << "void\n";
}

void func ( int** ) {
std::cout << "int**\n";
}

void func ( int* ) {
std::cout << "int**\n";
}

void func ( int(*)[3] ) {
std::cout << "int(*)[3]\n";
}

int main ( void ) {
int array [] = {1,2,3};
func( &array );
}


Best

Kai-Uwe Bux
 
S

Stefan Ram

Kai-Uwe Bux said:
You might want to test that hypothesis:

The term »pointer« is not explicitly defined by ISO/IEC 14882:2003(E).

I would suggest the natural definition:

»A pointer is a value of a pointer type.«

It seems also safe to assume that

»an array name is a name.«

A name is not a value, these two entities even belong to different models:

A name is an entity of the source-code model.

A value (a pointer) is an entity of the run-time model.

So an array name cannot be a pointer.

This assertion can not be tested by running code on programs
that claim to be implementations of ISO/IEC 14882:2003(E), it
needs to be deduced from ISO/IEC 14882:2003(E) and reasonable
assumptions.
 
S

Stefan Ram

The term »pointer« is not explicitly defined by ISO/IEC 14882:2003(E).

I found this:

»pointer - an object holding an address or 0.«

http://www.research.att.com/~bs/glossary.html

I have heard such a claim several times, but object to it,
because by this, for example, »&i« for an int variable »i«
would not be a pointer, because »&i« is not an object. But
I believe everyone wants »&i« to be a pointer.
 
K

Kai-Uwe Bux

Stefan said:
The term »pointer« is not explicitly defined by ISO/IEC 14882:2003(E).

I would suggest the natural definition:

»A pointer is a value of a pointer type.«

It seems also safe to assume that

»an array name is a name.«

A name is not a value, these two entities even belong to different
models:

A name is an entity of the source-code model.

A value (a pointer) is an entity of the run-time model.

So an array name cannot be a pointer.

This assertion can not be tested by running code on programs
that claim to be implementations of ISO/IEC 14882:2003(E), it
needs to be deduced from ISO/IEC 14882:2003(E) and reasonable
assumptions.

You snipped too much. Restoring context:
int array[] = {1, 2, 3};
then what is the type of &array? Is it int**, or some other type?

It should be int* instead of int **, because ...

Clearly, the initial "It" refers to the type of &array, and the claim is
that this expression has type int*. Whether it is int* or int** or some
other type can be tested. Since that claim turns out to be false, any
discussion on the merrit or meaningfullness of the because clause is moot.


Best

Kai-Uwe Bux
 
W

WANG Cong

Kai-Uwe Bux said:
WANG said:
hpsoar said:
int array[] = {1, 2, 3};
then what is the type of &array? Is it int**, or some other type?

It should be int* instead of int **, because an array name is _not_
a pointer.

You might want to test that hypothesis:

<snip>

Hmm, I made a mistake. Well, array name is an odd thing, it can be
a type of an array type, like here, when you apply address operator
to it; it can also be a pointer of the same type as the elements within
that array, e.g. when it is passed as argument to a function.
 
W

WANG Cong

Stefan said:
I found this:

»pointer - an object holding an address or 0.«

http://www.research.att.com/~bs/glossary.html

I have heard such a claim several times, but object to it,
because by this, for example, »&i« for an int variable »i«
would not be a pointer, because »&i« is not an object. But
I believe everyone wants »&i« to be a pointer.

Mo, that is an expression, neither a variable nor an object.
 
J

James Kanze

int array[] = {1, 2, 3};
then what is the type of &array? Is it int**, or some other type?

Exactly what you would expect it to have: int (*)[3] (pointer to
array[3] of int).
 
B

Bo Persson

Stefan said:
I found this:

»pointer - an object holding an address or 0.«

http://www.research.att.com/~bs/glossary.html

I have heard such a claim several times, but object to it,
because by this, for example, »&i« for an int variable »i«
would not be a pointer, because »&i« is not an object. But
I believe everyone wants »&i« to be a pointer.

It's the address of i, and can be assigned to a pointer.


Bo Persson
 
J

James Kanze

Kai-Uwe Bux said:
WANG Cong wrote:
hpsoar wrote:
int array[] = {1, 2, 3};
then what is the type of &array? Is it int**, or some
other type?
It should be int* instead of int **, because an array name
is _not_ a pointer.
You might want to test that hypothesis:

Hmm, I made a mistake. Well, array name is an odd thing, it
can be a type of an array type, like here, when you apply
address operator to it; it can also be a pointer of the same
type as the elements within that array, e.g. when it is passed
as argument to a function.

An array name is the name of an array. Always. When used in an
expression, it has the type of the array. Always.

You're getting confused by the fact that there is an implicit
conversion of array to pointer in a lot of contexts. Most, in
fact: sizeof, typeof, unary &, and binding to a reference are
the most obvious exceptions (obvious, in the sense that they
occur immediately to me); there could be others.

Just for fun, you might want to try:

#include <iostream>
#include <typeinfo>

template< typename T >
void f( T x )
{
std::cout << typeid( x ).name() << std::endl ;
}

template< typename T >
void g( T& x )
{
std::cout << typeid( x ).name() << std::endl ;
}

int
main()
{
int array[ 3 ] ;
f( array ) ;
g( array ) ;
return 0 ;
}

With any decent compiler, you'll get something like:
int *
int [3]
Such is the consistency of C++. (The problem, of course, is C
compatibility. Arrays in C are broken, and C++ can't fix them
without loosing compatibility completely.)
 
H

hpsoar

WANG said:
hpsoar wrote:
int array[] = {1, 2, 3};
then what is the type of &array? Is it int**, or some other type?
It should be int* instead of int **, because an array name is _not_
a pointer.

You might want to test that hypothesis:

#include <iostream>

void func ( ) {
std::cout << "void\n";

}

void func ( int** ) {
std::cout << "int**\n";

}

void func ( int* ) {
std::cout << "int**\n";

}

void func ( int(*)[3] ) {
std::cout << "int(*)[3]\n";

}

int main ( void ) {
int array [] = {1,2,3};
func( &array );

}

Best

Kai-Uwe Bux

thank you for this excellent method
 
W

WANG Cong

James said:
Kai-Uwe Bux said:
WANG Cong wrote:
hpsoar wrote:
int array[] = {1, 2, 3};
then what is the type of &array? Is it int**, or some
other type?
It should be int* instead of int **, because an array name
is _not_ a pointer.
You might want to test that hypothesis:

Hmm, I made a mistake. Well, array name is an odd thing, it
can be a type of an array type, like here, when you apply
address operator to it; it can also be a pointer of the same
type as the elements within that array, e.g. when it is passed
as argument to a function.

An array name is the name of an array. Always. When used in an
expression, it has the type of the array. Always.

Hmmm, how about the expression array? It will be, at least in C,
translated into *(array+i), of course, it doesn't have an array type
here.
You're getting confused by the fact that there is an implicit
conversion of array to pointer in a lot of contexts. Most, in
fact: sizeof, typeof, unary &, and binding to a reference are
the most obvious exceptions (obvious, in the sense that they
occur immediately to me); there could be others.

No, sizeof(array) is the size of an array, it is the array type,
of course, except when you apply sizeof inside a function to
an array passed as an argument.

Just for fun, you might want to try:
<snip>


Such is the consistency of C++. (The problem, of course, is C
compatibility. Arrays in C are broken, and C++ can't fix them
without loosing compatibility completely.)

Yes, agreed.
 
J

Joe Smith

WANG Cong said:
James Kanze wrote:
An array name is the name of an array. Always. When used in an
expression, it has the type of the array. Always.

Hmmm, how about the expression array? It will be, at least in C,
translated into *(array+i), of course, it doesn't have an array type
here.

Sure it does. But it immediately decays into a pointer such that pointer
arithmatic can be applied.

The pointer decay rules are both terribly useful yet a major pain in some
cases.
Now pointers to an array can be even more unintuitive.

All of this is why, whenever possible C-style arrays should be avoided in
C++. Thankfully in C++0x, there will be at least 3 reasonable replacements,
depending on requirements. (Vectors, valarrays, and arrays (the array array
templent from <array>)).
 
S

Stefan Ram

WANG Cong said:
Mo, that is an expression, neither a variable nor an object.

You are right, albeit very strict.

Let me try to rephrase my wording:

I believe everyone wants to be able to call
/the value of the expression/ »&i« »a pointer«
(assuming an int-variable »i«).

I believe everyone wants to be able to call
/the value of/ the expression »"abc" + 1« a pointer.

(An object holding a pointer would be a »pointer object«
(if it is named, a »pointer variable«) to me.)

An example why:

ISO/IEC 14882:2003(E) uses (in 3.7.3.1p2):

»The allocation function attempts to allocate (...)
The pointer returned shall be suitably aligned (...)«

Inserting the definition of Bjarne Stroustrup »pointer - an
object holding an address or 0.« into »The pointer returned
shall be suitably aligned (...)« gives:

»The object holding an address or 0 returned shall be
suitably aligned (...)«

But this makes no sense, because the intend of the sentence,
is that the /address/ is aligned not an object holding it.
Also, an allocation function is supposed to return an
address, not a object holding an address.

I believe, I could find many other examples, where a pointer
is a value, but not an object.

Just another example (5.7p5):

»When an expression that has integral type is added to or
subtracted from a pointer, the result has the type of the
pointer operand«¯¯¯¯¯¯¯¯¯

By the definition »pointer - an object holding an address or 0.«,
after »char const * p = "abc";« this would apply to »p + 1«,
because p is »an object holding an address or 0«, but it would
not apply to »( p + 1 )« in »( p + 1 )+ 1«, since
»( p + 1 )« is not an object. So we would need an additional
rule for this case, which is not given.

Therefore, one wants »( p + 1 )« also to be »a pointer« in
5.7p5

~~

Let me try to summarize where ISO/IEC 14882:2003(E) gets
close to defining the word »pointer«, but still misses:

»3 Basic concepts 3.9.2 Compound types

Compound types can be constructed in the following ways:
(...) pointers to void or objects or functions
(...) of a given type, 8.3.1;«

Simplified and in my words:

»There are three kinds of pointers:

- pointers to void
- pointers to objects
- pointers to functions«

This is a trisection of pointers, but no definition. The word
pointer is written in italics in ISO/IEC 14882:2003(E), which
is supposed to signal a definition. But it is not a definition.
Just using italics does not make a definition.

We can also have a look at:

»8.3.1 Pointers

1 In a declaration T D where D has the form

* cv-qualifier-seq opt D1

and the type of the identifier in the declaration T D1 is
"derived-declarator-type-list T," then the type of the
identifier of D is "derived-declarator-type-list
cv-qualifier-seq pointer to T."«

Simplified and in my words:

»After the declaration "T * name",
"name" has type "pointer to T".«

This specifies, when a name has a /pointer type/, but not
what »a pointer« is.

Nowhere in ISO/IEC 14882:2003(E) can a sentence of the kind
»a pointer is ...« be found.

~~

Sometimes, ISO/IEC 14882:2003(E) indeed tries to carefully
avoid using the term »pointer« for a non-object (an r-value),
but uses »an expression of pointer type«. But I believe this
is not done everywhere, where it would be needed.
 
J

James Kanze

James said:
Kai-Uwe Bux wrote:
WANG Cong wrote:
hpsoar wrote:
int array[] = {1, 2, 3};
then what is the type of &array? Is it int**, or some
other type?
It should be int* instead of int **, because an array
name is _not_ a pointer.
You might want to test that hypothesis:
Hmm, I made a mistake. Well, array name is an odd thing, it
can be a type of an array type, like here, when you apply
address operator to it; it can also be a pointer of the
same type as the elements within that array, e.g. when it
is passed as argument to a function.
An array name is the name of an array. Always. When used
in an expression, it has the type of the array. Always.
Hmmm, how about the expression array? It will be, at least
in C, translated into *(array+i), of course, it doesn't have
an array type here.


The sub-expression `array' has the type `int[3]'. Always,
regardless of where it is used. There is an implicit convertion
of `int[3]' to `int*' which will occur in contexts where an
`int*' would be legal, and an `int[3]' wouldn't be. A []
operator (the built-in one, at least), requires two arguments,
one of which must be a pointer, and the other which must be
size_t. In the expression `array', you have two arguments,
one of which is `int[3]', and the other `int'. Since `int'
doesn't convert implicitly to any pointer type, and `int[3]'
doesn't convert implicitly to size_t, the compiler converts the
`int' to `size_t' (for which there is an implicit conversion),
and the `int[3]' to `int*' (for which there is also an implicit
conversion). The fact that both operands are subject to
implicit conversions doesn't change the types of their
expressions: `array' is an `int[3]', and `i' is an `int'.
No, sizeof(array) is the size of an array, it is the array
type, of course, except when you apply sizeof inside a
function to an array passed as an argument.

C++ doesn't support passing arrays as arguments, so there's no
way to apply sizeof (or any other operator) to an array passed
as an argument. In the expression `sizeof( array )', there is
no implicit conversion of array to pointer (otherwise, sizeof
wouldn't make sense).

You're getting confused by the fact that in C++, there are two
ways of declaring a function parameter to have pointer type (and
no way of declaring it to have array type): `int *array' and
`int pointer[42]' (although what you put in the `[]' in the
second form is irrelevant, and is ignored by the compiler, as
long as it parses correctly).
 

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
474,164
Messages
2,570,901
Members
47,439
Latest member
elif2sghost

Latest Threads

Top