473,659 Members | 3,592 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 12984


Alexei A. Frounze wrote:

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 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?


Try removing the const keyword.
Example:

#include <stdio.h>

void print2 (int (*p)[5])
{
size_t i;

for(i = 0; i < 5; i++)
printf ("%d\n", (*p)[i]);
return;
}

int main(void)
{
int p[5] = {1,2,3,4,5};
print2(&p);
return 0;
}
--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapi dsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 15 '05 #11
"Al Bowers" <ab*****@myrapi dsys.com> wrote in message
news:3j******** ****@individual .net...
....
Try removing the const keyword.

....

But I want to keep it. :)

Alex
Nov 15 '05 #12
Alexei A. Frounze wrote:
"Alexei A. Frounze" <al*****@chat.r u> wrote in message
news:3j******** ****@individual .net...
"Joe Wright" <jo********@com cast.net> wrote in message
news:0u****** **************@ comcast.com...
daniele_atho me wrote:

Alexei A. Frounze wrote:
>void print2 (const int (*p)[5])
arg1 of print2 seems a pointer to a function... isn't it?

No. p is a pointer to array 5 of const int. Alexei gets this wrong too.


Excuse me, but what did I get wrong? Isn't what you're trying to say the
same as in my original post (excerpt): "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()."?

Alex

To clarify further, "... and ensure that *the array (not the pointer)* it's
not modified in anyway inside print2()."
Alex


Sorry Alex, I jumped on you in error. It would seem to be a 'const'
issue. If I remove the const qualifier from the print2 parameter it
works. Or if I add const to the array definition..

const int aInt3[5] = {0, 1, 2, 4, 9};

it works too. Go figure. I don't have a good handle on 'const'.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 15 '05 #13
Alexei A. Frounze wrote:
Yes, this would work fine if aInt3[] were declared as const array... But the
problem is that the compiler allows pointers to consts to non-const data but
warns on pointers to const array to non-const data. That's why I presented
both things in the test program. Kinda odd, don't you think so? I mean, I
can put there a type cast to get rid of the warning, but this warning in its
very core is stupid. Why "const int*" should be better than or in any other
way differ from "const (*int)[]"? Where's the rationale? I don't see it. Any
idea?
i think, it's because types differs from each other...
in print1 you declare `p` as an pointer to const qualified int.
-->> pointed value is const qualified
and
in print2 you declare `p` as an pointer to const qualified array of ints
-->> pointed value is array which elements are const qualified.

i see `const int **p` more like `const int (*p)[5]` than `const int *p`
in this case, because array decays to pointer in most cases.

- jt


"Tommi Johnsson" <TE*@Merlin.Mir rorland> wrote in message
news:dM******** *********@reade r1.news.jippii. net...
print2 expects pointer to constant array so
how about declaring aInt3 to constant or modify print2 parameter list...
- jt


Alexei A. Frounze wrote:
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 #14
"Joe Wright" <jo********@com cast.net> wrote in message
news:H7******** ************@co mcast.com...
Alexei A. Frounze wrote:
"Alexei A. Frounze" <al*****@chat.r u> wrote in message
news:3j******** ****@individual .net...
"Joe Wright" <jo********@com cast.net> wrote in message
news:0u****** **************@ comcast.com...

daniele_atho me wrote:

>Alexei A. Frounze wrote:
>
>
>>void print2 (const int (*p)[5])
>
>
>arg1 of print2 seems a pointer to a function... isn't it?

No. p is a pointer to array 5 of const int. Alexei gets this wrong too.

Excuse me, but what did I get wrong? Isn't what you're trying to say the
same as in my original post (excerpt): "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()."?

Alex

To clarify further, "... and ensure that *the array (not the pointer)* it's not modified in anyway inside print2()."
Alex


Sorry Alex, I jumped on you in error. It would seem to be a 'const'
issue. If I remove the const qualifier from the print2 parameter it
works. Or if I add const to the array definition..

const int aInt3[5] = {0, 1, 2, 4, 9};

it works too. Go figure. I don't have a good handle on 'const'.


That's what I'm trying to find explanation for. I mean, not the const,
rather the odd warning.
Anyway, const prohibits modification of data. Putting it in different
positions near * results in treatment of different object as
constant/unalterable. For instance:

int *p - modifiable pointer to modifiable int
const int *p - modifiable pointer to constant int
int* const p = initvalue; - constant pointer to modifiable int
const int* const p = initvalue; - constant pointer to constant int

int** pp - modifiable pointer to modifiable pointer to modifiable int
const int** pp - modifiable pointer to modifiable pointer to constant int
int* const* pp - modifiable pointer to constant pointer to modifiable int
int** const pp = initvalue; - constant pointer to modifiable pointer to
modifiable int
etc etc...

Maybe I should look into c99 or better ask gcc guys what's going on.
I can also try the thing with other compilers. By now I know that Borland's
old Turbo C/C++ 16-bit compiler for DOS handles the pointer to const array
w/o the warning. There're other Borland's, Open Watcom and VC++ to try...
Though, VC++ is known to emit even more stupid warnings (like a=b=0; where a
and b are for e.g. short and int, and 0 says nothing to the compiler).

Best regards,
Alex
Nov 15 '05 #15
"Tommi Johnsson" <TE*@Merlin.Mir rorland> wrote in message
news:4L******** ********@reader 1.news.jippii.n et...
Alexei A. Frounze wrote:
Yes, this would work fine if aInt3[] were declared as const array... But the problem is that the compiler allows pointers to consts to non-const data but warns on pointers to const array to non-const data. That's why I presented both things in the test program. Kinda odd, don't you think so? I mean, I can put there a type cast to get rid of the warning, but this warning in its very core is stupid. Why "const int*" should be better than or in any other way differ from "const (*int)[]"? Where's the rationale? I don't see it. Any idea?


i think, it's because types differs from each other...
in print1 you declare `p` as an pointer to const qualified int.
-->> pointed value is const qualified
and
in print2 you declare `p` as an pointer to const qualified array of ints
-->> pointed value is array which elements are const qualified.

i see `const int **p` more like `const int (*p)[5]` than `const int *p`
in this case, because array decays to pointer in most cases.

- jt


There were no "const int **p" in the code. Besides, "const int **p" declares
a modifiable pointer to a modifiable pointer to a constant int. There's no
double indirection anywhere in the code.

Anyway, can you suggest a declaration of the function's argument that would
simultaneously satisfy:
- being a pointer to an array of a fixed number of elements, say, 5 integers
- this array is to be constant, in other words, its elements can't be
altered by using the pointer

Can it be declared like that provided the compiler does not emit any warning
if as argument I use an array (its address) that isn't constant?

Why can I do it with one value, e.g. pass a pointer to modifiable int or
modifiable array of ints to a function whose argument is of type "const
int*", but I can not do the same with an array of fixed number of ints?

Alex
Nov 15 '05 #16


Alexei A. Frounze wrote:
"Al Bowers" <ab*****@myrapi dsys.com> wrote in message
news:3j******** ****@individual .net...
...
Try removing the const keyword.


...

But I want to keep it. :)


If castration of const is out, do not pout.
Casting, a pollution, is one solution.

(const int (*)[5])

--
Al Bowers
Tampa, Fl USA
mailto: xab*****@myrapi dsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 15 '05 #17
"Al Bowers" <ab*****@myrapi dsys.com> wrote in message
news:3j******** ****@individual .net...


Alexei A. Frounze wrote:
"Al Bowers" <ab*****@myrapi dsys.com> wrote in message
news:3j******** ****@individual .net...
...
Try removing the const keyword.
...

But I want to keep it. :)


If castration of const is out, do not pout.
Casting, a pollution, is one solution.

Very smart :)
(const int (*)[5])


This is even smarter. :)

So, I presume nobody knows what's wrong. I haven't found anything on this
particular thing in C99. Maybe it's just gcc's way to do things... I need
more statistics.
Alex
Nov 15 '05 #18
On Sun, 10 Jul 2005 19:48:00 +0400, "Maxim S. Shatskih"
<ma***@storagec raft.com> wrote:
Surely.

"&alnt3" is the same as "alnt3", since alnt3 is an array.
The original post defined an array as int aInt3[5]. Ignoring your
typo in the name:

&aInt3 has type pointer to array of 5 int.

aInt3 in most contexts, including the question raised in the
original post, will be converted to the address of the first element
with type pointer to element type. In this case, it is pointer to
int.

The two types are not compatible.

So, you pass int* to print2, and it expects an array of int* - i.e. int**.


The original post passed &aInt3 to print2, so it did not pass an int*.
print2 was defined in the original post as
void print2 (const int (*p)[5])

The argument is declared as type pointer to constant array of 5 int,
not as an array of pointer to int. While an array of int* would be
passed to a function as an int**, the two are not synonymous at all.
<<Remove the del for email>>
Nov 15 '05 #19
On Mon, 11 Jul 2005 00:53:27 +0400, Alexei A. Frounze wrote:
"Tommi Johnsson" <TE*@Merlin.Mir rorland> wrote in message
news:4L******** ********@reader 1.news.jippii.n et...
Alexei A. Frounze wrote:
> Yes, this would work fine if aInt3[] were declared as const array...
> But the > problem is that the compiler allows pointers to consts to non-const
> data but > warns on pointers to const array to non-const data. That's why I presented > both things in the test program. Kinda odd, don't you think so? I
> mean, I > can put there a type cast to get rid of the warning, but this warning
> in its > very core is stupid. Why "const int*" should be better than or in any other > way differ from "const (*int)[]"? Where's the rationale? I don't see
> it. Any > idea?

Yes, see below.

i think, it's because types differs from each other... in print1 you
declare `p` as an pointer to const qualified int. -->> pointed value is
const qualified and
in print2 you declare `p` as an pointer to const qualified array of ints
-->> pointed value is array which elements are const qualified.

i see `const int **p` more like `const int (*p)[5]` than `const int *p`
in this case, because array decays to pointer in most cases.

Yes, the double indirection is the cause of the warning.
There were no "const int **p" in the code.
I don't think jt was saying there was. He was saying that you should be
comparing print2 function's parameter with "const int **p" rather than
with print1's "const int *p" as you have been doing. This is the source
of your confusion.
Besides, "const int **p"
declares a modifiable pointer to a modifiable pointer to a constant int.
There's no double indirection anywhere in the code.
A pointer to an array *is* double indirection. So print2's first
parameter is doubly indirected.
Anyway, can you suggest a declaration of the function's argument that
would simultaneously satisfy:
- being a pointer to an array of a fixed number of elements, say, 5
integers - this array is to be constant, in other words, its elements
can't be altered by using the pointer
No. To the best of my understanding it is not possible according to the
standard.
Can it be declared like that
Like what?
provided the compiler does not emit any
warning if as argument I use an array (its address) that isn't constant?

Why can I do it with one value, e.g. pass a pointer to modifiable int or
modifiable array of ints to a function whose argument is of type "const
int*", but I can not do the same with an array of fixed number of ints?


This question was answered recently in another thread. See
message id <87************ @hardknott.home .whinlatter.ukf sn.org>
dated Wed, 6 Jul 2005 22:54:41 +0000 (UTC)
on comp.lang.c
subject Implicit addition of const qualifiers

Hint, try adding a function:

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

and in your main code:
int *pInt = aInt2;
print3 (&pInt, sizeof(aInt2)/sizeof(aInt2[0]));

You'll get the same warning.

The problem is the double indirection - the standard won't allow the
non-const to be automatically converted to const in such cases.

Wouldn't you know it - you'll have to go with the poet. A cast is
required.

Nov 15 '05 #20

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

Similar topics

8
4432
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
3623
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
2138
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
8428
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8337
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
8748
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
7359
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
6181
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
5650
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4175
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...
2
1978
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1739
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.