473,738 Members | 11,192 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 13052
Ben Pfaff wrote:
"Maxim S. Shatskih" <ma***@storagec raft.com> writes:
With "const", all is clear. The "const" attribute of the lvalue cannot be
removed without the explicit cast - neither in C nor on C++.


Sure it can--try calling a function like strchr().


Or just...

char *foo();

void bah(const char *x)
{
char *y = foo(x);
...
}

char *foo(char *x)
{
return x;
}

--
Peter

Nov 15 '05 #71
On Wed, 13 Jul 2005 23:17:57 -0700, Peter Nilsson wrote:
Ben Pfaff wrote:
"Maxim S. Shatskih" <ma***@storagec raft.com> writes:
> With "const", all is clear. The "const" attribute of the lvalue cannot
> be removed without the explicit cast - neither in C nor on C++.


Sure it can--try calling a function like strchr().


Or just...

char *foo();

void bah(const char *x)
{
char *y = foo(x);
...
}
}
char *foo(char *x)
{
return x;
}


Neither of these examples removes a const attribute from an lvalue, which
is impossible by definition. An lvalue can be assigned to. If it had a
const attribute that was to be removed, you couldn't assign to it and it
wouldn't be an lvalue in the first place.

I believe though that you've correctly interpreted what Maxim meant as
opposed to what actually said.

Nov 15 '05 #72
> > char *foo();

Oh, sorry. The only language for which I've read the formal description was C++
(old one - circa 1993) and not C. In C++, such things are impossible.

--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
ma***@storagecr aft.com
http://www.storagecraft.com
Nov 15 '05 #73
Andrey Tarasevich wrote:
It is not "indexed in a different way". All arrays, single- or
multi-dimensional, are indexed in exactly the same way.


Nope, they're not. The equivalence stops at one-dimensional arrays.
Multidimensiona l arrays aren't addressed the same way as
multi-indirectioned (sp?) pointers.

That is to say, int foo[10][20] doesn't decay to int **.

Multi-dimensional arrays store all of their elements consecutively, the
single elements are accessed by means of pointer math on the dimensions
and size of the elements, whilst multi-indirectioned pointers are simply
pointers (to pointers... to pointers) to the elements:
int foo[3][3] :

+--+--+--+
| | | |
+--+--+--+
| | | |
+--+--+--+
| | | |
+--+--+--+

int **baz :

+--+--+--+ ...
| | | | ...
+--+--+--+ ...
|| || ||
\/ \/ \/
+--+--+--+
| + + |
+--+--+--+
| + + |
+--+--+--+
| + + |
+--+--+--+
...........
...........
...........
--
Fabio Alemagna
Nov 15 '05 #74
On Thu, 14 Jul 2005 10:40:50 +0400, Maxim S. Shatskih wrote:
> char *foo();


Oh, sorry. The only language for which I've read the formal description
was C++ (old one - circa 1993) and not C. In C++, such things are
impossible.


Actually assuming you that by "lvalue" you meant "expression " what you
said was correct anyway. You said that the const attribute cannot be
removed from an expression without an explicit cast, which is true.

Looking again at the examples given by Ben Pfaff and Peter Nilsson,
they're showing the const attribute being added, rather than removed,
without an explicit cast.
Nov 15 '05 #75
Fabio Alemagna wrote:
It is not "indexed in a different way". All arrays, single- or
multi-dimensional, are indexed in exactly the same way.
Nope, they're not.


Yes, they are.
The equivalence stops at one-dimensional arrays.
Multidimensiona l arrays aren't addressed the same way as
multi-indirectioned (sp?) pointers.
That's true. But in my message I'm talking about the difference between
the way single- and multi-dimensional arrays are addressed. No pointers
involved (multi-indirectioned or not). You for some reason start talking
about pointers. Why?
That is to say, int foo[10][20] doesn't decay to int **.
That's true. But, once again, how is this relevant?
[skipped]


Once again, true. But I still don't see how all this applies to what I
said in my message.

--
Best regards,
Andrey Tarasevich

Nov 15 '05 #76
Netocrat wrote:
...
Neither of these examples removes a const attribute from an lvalue, which
is impossible by definition. An lvalue can be assigned to.
Huh? No. By definition, lvalue is something that has address in storage. In
general case lvalue cannot be assigned to. Only _modifyable_ lvalue can be
assigned to, but there are also non-modifyable lvalues.
If it had a
const attribute that was to be removed, you couldn't assign to it and it
wouldn't be an lvalue in the first place.


Not true. You seem to assume that assignability is a defining property of
"lvalueness ". That's simply not true.

--
Best regards,
Andrey Tarasevich
Nov 15 '05 #77
On Thu, 14 Jul 2005 02:47:13 -0700, Andrey Tarasevich wrote:
Netocrat wrote:
...
Neither of these examples removes a const attribute from an lvalue, which
is impossible by definition. An lvalue can be assigned to.
Huh? No. By definition, lvalue is something that has address in storage. In
general case lvalue cannot be assigned to. Only _modifyable_ lvalue can be
assigned to, but there are also non-modifyable lvalues.


Right, my concept of lvalue was slightly out. Non-modifiable being for
example arrays and structs.

Maxim's original statement then is accurate:
With "const", all is clear. The "const" attribute of the lvalue cannot
be removed without the explicit cast - neither in C nor on C++.

If it had a
const attribute that was to be removed, you couldn't assign to it and it
wouldn't be an lvalue in the first place.


Not true. You seem to assume that assignability is a defining property of
"lvalueness ". That's simply not true.


On reading the standard I see that you are correct.

Nov 15 '05 #78
Fabio Alemagna wrote:
Andrey Tarasevich wrote:
It is not "indexed in a different way". All arrays, single- or
multi-dimensional, are indexed in exactly the same way.


Nope, they're not. The equivalence stops at one-dimensional arrays.
Multidimensiona l arrays aren't addressed the same way as
multi-indirectioned (sp?) pointers.

That is to say, int foo[10][20] doesn't decay to int **.


Which is because there are no multi-dimensioned arrays in C, there
are just arrays of arrays. An array of pointers is not a
multidimensione d array, or even a fake of one linearized.

--
"If you want to post a followup via groups.google.c om, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson

Nov 15 '05 #79
In comp.lang.c Peter Nilsson <ai***@acay.com .au> wrote:
char *foo();

void bah(const char *x)
{
char *y = foo(x);
You raise UB here: (const char*) and (char*) types are
not compatible - you cannot pass incompatible arguments
to a function call (cf. 6.5.2.2#6).
...
}

char *foo(char *x)
{
return x;
}


--
Stan Tobias
mailx `echo si***@FamOuS.Be dBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 15 '05 #80

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

Similar topics

8
4443
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
3631
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
2149
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
8788
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
9476
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
9335
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...
0
8210
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6751
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4825
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3279
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
2745
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2193
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.