473,698 Members | 2,602 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

gcc: pointer to array

Hi all,

I have a question regarding the gcc behavior (gcc version 3.3.4).

On the following test program it emits a warning:
#include <stdio.h>

int aInt2[6] = {0,1,2,4,9,16};
int aInt3[5] = {0,1,2,4,9};

void print1 (const int* p, size_t cnt)
{
while (cnt--)
printf ("%d\n", *p++);
}

void print2 (const int (*p)[5])
{
size_t cnt;
#if 0
// prohibited:
(*p)[0]=0;
#endif
for (cnt=0; cnt<5; cnt++)
printf ("%d\n", (*p)[cnt]);
}

int main()
{
printf ("test begin\n");

print1 (aInt2, sizeof(aInt2)/sizeof(aInt2[0]));
print2 (&aInt3); // <-- warns here

printf ("test end\n");
return 0;
}

The warning is:
MOD.c: In function `main':
MOD.c:: warning: passing arg 1 of `print2' from incompatible pointer type

Why is that? How is this different from using print1 (aInt2, ...)? All I
want to do is to explicitly show that the pointer is to an array of 5
entries and ensure that it's not modified in anyway inside print2(). However
the #if 0'd assignment operator inside print2() is correctly handled by
gcc -- an error is generated:
MOD.c: In function `print2':
MOD.c:: error: assignment of read-only location
What's wrong with gcc?

There's another thing about the pointer to the array is... The compiler
doesn't generate a warning if I change in print2()
for (cnt=0; cnt<5; cnt++)
to
for (cnt=0; cnt<6; cnt++)
and lets me access (*p)[5], though I think at least a warning should be
generated here.
It doesn't warn me if I put
aInt3[6] = 0;
into main(). But in both cases the compiler "knows" the real size of the
array, still no warning...
Is this OK???

Thanks,
Alex
P.S. I compile it as gcc MOD.c -Wall -oMOD.exe
Nov 15 '05
204 13015
On Wed, 13 Jul 2005 05:44:20 +1000, Netocrat wrote:
On Mon, 11 Jul 2005 21:33:32 +0400, Maxim S. Shatskih wrote:
An array is one layer of indirection. Given its similarity to a
pointer I don't see much controversy in that statement. A pointer to
an array is therefore a second layer of indirection. What do you find
disagreeable about this reasoning?
The C notion of the array is another.


You are just repeating my first statement, because by "array" of course I
meant "the C notion of the array" - we are talking in a C newsgroup after
all. You seem to be implying that there is a third layer of indirection
different from the two I described... I just don't understand your point.
Array is the same as pointer to its
first element (in all operations except sizeof(), and so ( p + a )
offset operations).


True, but of what relevance is that statement? You are supposedly, after
all, disagreeing with my statement that "A pointer to an array *is* double
indirection." How does this support your case?
What is "the pointer" to which you are referring?


MyArray and &(MyArray[0]) is the same in all contexts except sizeof().


As Chris Torek pointed out in another part of this thread, that statement
is not actually correct. They are different types. But yes, we all
seem to agree that the values will be the same for sensible conversions.


Ack, having just responded to Chris' post I was quick to misread your
statement as comparing MyArray with &MyArray which it obviously isn't. So
they are compatible types after all. They aren't identical types though
because assuming that MyArray is declared something like char MyArray[10],
then MyArray is of type "array 10 of char" whereas &(MyArray[0]) is of
type "pointer to char". Not the same but interchangeable in most
expressions, with some exceptions such as the one you gave - sizeof().
That statement does not, however, answer my question, which was which
pointer you are referring to.
I'll cut you some slack here because after re-reading I see that you
intended "the pointer" to refer to the pointer to the array's first
element. But your meaning is still unclear because as I originally
explained, a pointer to an array can itself be indexed and treated as
though it were an array. So now rather than being unclear about what you
mean by "the pointer" I am confused about which "array" you are talking
about - the "pointer to array" array or the array that that "pointer to
array" points to?

I'll add that whilst you haven't specified the type of your variable
MyArray, its name suggests that it is intended to be an array, whereas
what you actually objected to was my characterisatio n of a type that was
a pointer to an array. So why don't you use such a type in your
explanation?
absurd - a pointer to an array is much more than just an address.


In C and C++, it is the same.


No, it is not the same. A pointer is not an address. It is a type
whose value represents an address.
doubt that you mean that. Generally a pointer is a variable...


Pointer is a value. Value != variable.


I want to add that I wasn't contending that a pointer is always a
variable, just that generally it is. It is a type, and obviously it
occurs in contexts other than variables, such as taking the address of an
object, and casting.
A pointer is a type containing a value. Container of value != value.
This is a clearer and more accurate wording:

A pointer is a type, not a value.

A pointer is a type whose value represents the address of an object.

Your statement that a pointer is a value is as wrong as saying that an int
is a value. An int has a value, but it is a type, not a value. In the
same way, a pointer has a value, but it is a type, not a value.
You still haven't explained why you disagree with my statement that a
pointer to an array is double indirection.


Nov 15 '05 #51
Maxim S. Shatskih wrote:
An array is one layer of indirection. Given its similarity to a pointer I
don't see much controversy in that statement. A pointer to an array is
therefore a second layer of indirection. What do you find disagreeable
about this reasoning?

The C notion of the array is another. Array is the same as pointer to its first
element (in all operations except sizeof(), and so ( p + a ) offset
operations).

What is "the pointer" to which you are referring?

MyArray and &(MyArray[0]) is the same in all contexts except sizeof().

absurd - a pointer to an array is much more than just an address.

In C and C++, it is the same.

doubt that you mean that. Generally a pointer is a variable...

Pointer is a value. Value != variable.


No. A pointer is a variable which can hold the address of another
variable. You know that, right? It's in every C book you've ever read.
Really! Some people refer to the value of an address and call that value
a 'pointer' but they misuse the term.

int *p; /* p is a variable of type pointer to int */
int a = 1; /* a is a variable with type int and value 1 */
p = &a; /* the address of a is assigned to variable p */

But p is the only pointer here. &a is an address.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 15 '05 #52
> > Pointer is a value. Value != variable.


No. A pointer is a variable which can hold the address of another
variable. You know that, right? It's in every C book you've ever read.


Well, great discussion about what "value" is. :)

For me, "value" is a thing like ( a + 1 ) or a[10]. It is not a variable, and
it is not necessary "lvalue" - a[10] is lvalue, while ( a + 1 ) or ((long)a) is
not.

Value has a strictly defined type known at compile time.

--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
ma***@storagecr aft.com
http://www.storagecraft.com
Nov 15 '05 #53
On Tue, 12 Jul 2005 18:52:56 -0400, Joe Wright wrote:
Maxim S. Shatskih wrote:
An array is one layer of indirection. Given its similarity to a pointer
I don't see much controversy in that statement. A pointer to an array
is therefore a second layer of indirection. What do you find
disagreeab le about this reasoning?

The C notion of the array is another. Array is the same as pointer to
its first element (in all operations except sizeof(), and so ( p + a )
offset operations).

What is "the pointer" to which you are referring?

MyArray and &(MyArray[0]) is the same in all contexts except sizeof().

absurd - a pointer to an array is much more than just an address.

In C and C++, it is the same.

doubt that you mean that. Generally a pointer is a variable...

Pointer is a value. Value != variable.

No. A pointer is a variable which can hold the address of another
variable. You know that, right? It's in every C book you've ever read.
Really! Some people refer to the value of an address and call that value a
'pointer' but they misuse the term.


Actually a pointer is neither a value nor a variable but a type; the word
is commonly used to refer to a variable with pointer type though, and this
is reasonable usage.

Consider these usages:

"the dereferencing of variable x yields a pointer" - what you mean is
that dereferencing x yields a value of pointer type.

"x is a pointer" - what you mean is that x is a variable with pointer
type. This is the restricted sense in which the word pointer can be used
to refer to a variable. A pedant might require this to be written as "x
is a pointer variable", but there aren't any pedants on this newsgroup.

"cast it to a pointer" - what you mean is to change the compiler's view of
the expression so that it sees a pointer type. This could be any
expression - it doesn't have to be a variable.

"take the pointer and add one to it" - again this usage could apply to
any expression which evaluates to a pointer type; the expression could be
a value or a variable or some other expression, showing clearly that a
pointer is limited neither to being solely a value nor a variable.
int *p; /* p is a variable of type pointer to int */
int a = 1; /* a is a variable with type int and value 1 */
p = &a; /* the address of a is assigned to variable p */

But p is the only pointer here. &a is an address.


p is the only pointer variable, true, but &a is more than just an address;
it has a type, and that type is pointer to int. Can we categorically
call it a pointer as we can for a variable that has pointer type? It's
probably not unreasonable, but it isn't commonly done. In certain contexts
though it can indisputably be referred to as a pointer, as in "add one to
the pointer that we get when we dereference a".

Nov 15 '05 #54
On Wed, 13 Jul 2005 04:04:50 +0400, Maxim S. Shatskih wrote:
> Pointer is a value. Value != variable.
>
> No. A pointer is a variable which can hold the address of another
variable. You know that, right? It's in every C book you've ever read.


Well, great discussion about what "value" is. :)


Yes it's an interesting discussion, but I wouldn't have said it was about
value... it seems to me that it's more about what a pointer is.
For me, "value" is a thing like ( a + 1 ) or a[10]. It is not a variable,
and it is not necessary "lvalue" - a[10] is lvalue, while ( a + 1 ) or
((long)a) is not. Value has a strictly defined type known at compile
time.


Replace "value" with "expression " in the above quote. And of course an
expression evaluates to a value, so you ultimately get to keep your value.

So after interpreting your usage of the word "value", what you are really
saying is that a pointer is an expression. I take your point(er) - it's
true that a pointer _is_ an expression, but I do think that it is better
(because more broadly) defined as a type.

Nov 15 '05 #55
> Actually a pointer is neither a value nor a variable but a type; the word
is commonly used to refer to a variable with pointer type though, and this


Yes, and the value of the pointer type is also called "pointer" usually.

BTW - arrays and pointers are different for multu-dimension arrays. Imagine:

int Array[10][5];

- and please tell me what will be the type of

Array[1]

expression? Yes, the type will be "array of 5 integers", which is different
from "int *" - it is indexed in a different way.

--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
ma***@storagecr aft.com
http://www.storagecraft.com
Nov 15 '05 #56
On Wed, 13 Jul 2005 05:22:06 +0400, Maxim S. Shatskih wrote:
Actually a pointer is neither a value nor a variable but a type; the
word is commonly used to refer to a variable with pointer type though,
and this
Yes, and the value of the pointer type is also called "pointer" usually.


Well I'd be more inclined to refer to the value of a pointer type as an
address, but from your other post I know that you use "value" to mean
"expression ", so perhaps by the above statement you mean "...express ions
of pointer type are usually also called pointer". So you would mean that
if we have a variable "a" then we can say that &a is a pointer. I suppose
that that usage is OK - it's probably down to personal preference.
BTW - arrays and pointers are different for multu-dimension arrays.
Imagine:

int Array[10][5];

- and please tell me what will be the type of

Array[1]

expression? Yes, the type will be "array of 5 integers", which is
different from "int *" - it is indexed in a different way.


What do you mean by this? I don't know of any situation where an array of
5 integers and a pointer to int would be indexed differently.

Nov 15 '05 #57
Joe Wright wrote:
Pointer is a value. Value != variable.


No. A pointer is a variable which can hold the address of another
variable. You know that, right? It's in every C book you've ever read.
Really! Some people refer to the value of an address and call that value
a 'pointer' but they misuse the term.


These people must have written the Standard, then. In the definition of the
address operator, it says:
"[T]he result is a pointer to the object or function designated by its
operand".
Now what?
Christian

Nov 15 '05 #58
On Mon, 11 Jul 2005 23:33:05 +0300, Tommi Johnsson wrote:
Lawrence Kirby wrote:


....

But this is an important example of where that is not the case. In
const int (*p)[5] p is already a pointer, it cannot "decay" further.


in declaration like const int (*p)[5] it declares only type for p it
really doesnt decay anything


Right, any "decay" happens in usage not declaration. For example

int a[10];
int *pa;

pa = a;
Here a is an array which is concerted to a pointer to its first element
for the assignment (the "decay"). There is nothing equivalent for p since
it is already a pointer, i.e. nothing that converts int (*)[5] to int **,
which would make no sense anyway.

Lawrence
Nov 15 '05 #59
On Mon, 11 Jul 2005 19:37:33 +0100, Chris Croughton wrote:
On 11 Jul 2005 17:35:54 GMT, Chris Torek
<no****@torek.n et> wrote:
[Given "int arr[N];" and considering "&arr" vs "&arr[0]")
It is important to be clear that &arr and &arr[0] are fundamentally
different things. The only sense in which they are equal is that they
point to (different) objects that share the same starting byte, i.e.
(char *)&arr == (char *)&arr[0]. One points at an int, another points at
an array, so saying they are the same makes as much sense as given:

struct {
int a;
long b;
double c;
} s;

saying that &s is the same as &s.a. And before you say anything, it isn't.
:-) One is a pointer to an int, the other is a pointer to a struct. That
makes them very different.
I think the real question boils down to whether &arr and &arr[0]
will compare equal under *all* "well-defined" conversions
The point is that they can't be compared directly. Pointer conversions are
a nasty business, once you've converted to a different pointer type you
can't really say that you're comparing the original value.
-- which
may even be only those to "char *" and "void *" -- and then I think
the answer is "yes", so that we can in fact say that the converted
values are always identical as long as we do a sensible conversion.

If you want to say that they point to objects sharing the same starting
byte address then say that, don't say that the pointers are the same. One
property of a pointer doesn't define the whole thing.
Is that actually defined by the standard? I remember that in some
pre-standard C compilers arrays were actually implemented as pointers,
so int arr[5]; would actually expand to the equivalent in
pseudo-assember:

arr: dw &_arr
_arr: dw ?[5]

(The array pointer itself might be declared in a read-only segment.)

Is this sort of expansion actually banned by the standard, or is it
"just not the done thing"?
The compiler can do whatever magic it likes so long as the program behaves
correctly. In standard C a array doesn't define a separate pointer object
so they must behave as if they don't. That goes for dynamically allocated
arrays and arrays of arrays too.
In those compilers the effect would be the same as happens with "array
parameters", taking &arr would get you the address of the pointer.


There is no such pointer object in standard C so that is not a valid
implementation. &arr gives a result of type pointer to array, not pointer
to pointer.

Lawrence
Nov 15 '05 #60

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
4439
by: pemo | last post by:
I've just been trying out the Watcom compiler from http://www.openwatcom.org, and almost immediately compiled some working source that errored. The code is char buffer; ...
34
3625
by: thibault.langlois | last post by:
Hello, I get a warning when I compile: #include <string.h> int main (int argc, char ** argv) { char * s; s = strdup("a string"); return 0; }
7
2147
by: vippstar | last post by:
Today I got a confusing message from gcc (I'm aware, those don't break conformance ;-) In function 'main': 7: warning: format '%d' expects type 'int', but argument 2 has type 'char (*)' The code is #include <stdio.h>
0
8609
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9169
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9030
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8899
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
4371
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4622
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3052
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2335
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2007
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.