Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.std.c > #6570 > unrolled thread
| Started by | Denis Dos Santos Silva <denis@roo.com.br> |
|---|---|
| First post | 2023-09-18 08:49 -0700 |
| Last post | 2023-09-18 20:13 +0100 |
| Articles | 5 — 3 participants |
Back to article view | Back to comp.std.c
why can change element of a const typed struct ? Denis Dos Santos Silva <denis@roo.com.br> - 2023-09-18 08:49 -0700
Re: why can change element of a const typed struct ? David Brown <david.brown@hesbynett.no> - 2023-09-18 20:29 +0200
Re: why can change element of a const typed struct ? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-18 20:58 +0100
Re: why can change element of a const typed struct ? David Brown <david.brown@hesbynett.no> - 2023-09-19 17:15 +0200
Re: why can change element of a const typed struct ? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-18 20:13 +0100
| From | Denis Dos Santos Silva <denis@roo.com.br> |
|---|---|
| Date | 2023-09-18 08:49 -0700 |
| Subject | why can change element of a const typed struct ? |
| Message-ID | <6d826a46-8852-4aa3-9e7d-23fac761e840n@googlegroups.com> |
hi all!
why this works? =)
/// image.c
/// ...
typedef struct {
int w;
int h;
unsigned char channels;
unsigned char *data;
int err;
} image_t;
int image_copy(const image_t* source, const image_t* target, int xoffset, int yoffset) {
register int sindex;
register int tindex = 0;
register int y1, x1;
if (!source || !target)
return -1;
for (int y=0; y<target->h; y++) {
for (int x=0; x<target->w; x++) {
#if 1
y1 = y+yoffset;
x1 = x+xoffset;
sindex = (y1 * source->w + x1) * 3;
if (sindex > (source->w * source->h * 3))
continue;
// change value of element of const struct
source->data[sindex+0] = target->data[tindex++];
source->data[sindex+1] = target->data[tindex++];
source->data[sindex+2] = target->data[tindex++];
#endif
}
}
return 0;
}
/// <eof>
[toc] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2023-09-18 20:29 +0200 |
| Message-ID | <uea4ti$1stu4$1@dont-email.me> |
| In reply to | #6570 |
On 18/09/2023 17:49, Denis Dos Santos Silva wrote:
> hi all!
> why this works? =)
>
Your image_t is const, but it has a non-const pointer "data" - there is
no restriction to accessing the elements pointed to by source->data.
So your function can't change "source->data", but it /can/ change
"source->data[sindex]".
"const" does not pass through layers of pointers, it only applies to the
first pointed-at layer.
Does that help?
>
>
> /// image.c
> /// ...
> typedef struct {
> int w;
> int h;
> unsigned char channels;
> unsigned char *data;
> int err;
> } image_t;
>
> int image_copy(const image_t* source, const image_t* target, int xoffset, int yoffset) {
> register int sindex;
> register int tindex = 0;
> register int y1, x1;
>
> if (!source || !target)
> return -1;
>
> for (int y=0; y<target->h; y++) {
> for (int x=0; x<target->w; x++) {
> #if 1
> y1 = y+yoffset;
> x1 = x+xoffset;
>
> sindex = (y1 * source->w + x1) * 3;
> if (sindex > (source->w * source->h * 3))
> continue;
>
> // change value of element of const struct
>
> source->data[sindex+0] = target->data[tindex++];
> source->data[sindex+1] = target->data[tindex++];
> source->data[sindex+2] = target->data[tindex++];
> #endif
> }
> }
>
> return 0;
> }
> /// <eof>
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2023-09-18 20:58 +0100 |
| Message-ID | <871qevjls3.fsf@bsb.me.uk> |
| In reply to | #6571 |
David Brown <david.brown@hesbynett.no> writes: > On 18/09/2023 17:49, Denis Dos Santos Silva wrote: >> hi all! >> why this works? =) > > Your image_t is const, but it has a non-const pointer "data" - there is no > restriction to accessing the elements pointed to by source->data. I feel I must quibble because it can matter to someone learning C. When accessed via 'const image_t *source', data /is/ (treated as) const. data is a pointer, and the lvalue expression source->data is const qualified. To call it a "non-const pointer" is using a common shorthand, but one I've found is very confusing to beginners. We casually talk about "const pointers" and "non-const pointers" because we all know what we mean, but people learning C can get confused by what is and is not const-qualified. It's a handy shorthand because an actual 'const pointer' is not seen so often: char *const endp = start + strlen(start); But we often see this const char *end = start + strlen(start); described as a const pointer even though changing the pointer is perfectly valid: end -= 1; // permitted because end is pointer that is not const > So your function can't change "source->data", Right, because data is treated as a const pointer. Calling it a non-const pointer is potentially confusing. I know what you meant, but is it clear to everyone? > but it /can/ change "source->data[sindex]". > > "const" does not pass through layers of pointers, it only applies to the > first pointed-at layer. Your remark suggests that there is something special about one level of indirection, but there isn't. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2023-09-19 17:15 +0200 |
| Message-ID | <uecduj$2dcj7$1@dont-email.me> |
| In reply to | #6573 |
On 18/09/2023 21:58, Ben Bacarisse wrote: > David Brown <david.brown@hesbynett.no> writes: > >> On 18/09/2023 17:49, Denis Dos Santos Silva wrote: >>> hi all! >>> why this works? =) >> >> Your image_t is const, but it has a non-const pointer "data" - there is no >> restriction to accessing the elements pointed to by source->data. > > I feel I must quibble because it can matter to someone learning C. > > When accessed via 'const image_t *source', data /is/ (treated as) const. > data is a pointer, and the lvalue expression source->data is const > qualified. To call it a "non-const pointer" is using a common > shorthand, but one I've found is very confusing to beginners. > > We casually talk about "const pointers" and "non-const pointers" because > we all know what we mean, but people learning C can get confused by what > is and is not const-qualified. It's a handy shorthand because an actual > 'const pointer' is not seen so often: > Those are very good points, and I am glad you gave a better and more accurate explanation than I did.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2023-09-18 20:13 +0100 |
| Message-ID | <87cyyfjnvl.fsf@bsb.me.uk> |
| In reply to | #6570 |
Denis Dos Santos Silva <denis@roo.com.br> writes:
> hi all!
This would probably be better sent to comp.lang.c so I am setting the
followup-to header accordingly. This group is mainly about the ISO C
standard, though it's possible you are asking why the standard permits
this.
> why this works? =)
(from subject) why can change element of a const typed struct ?
Short answer: you are not changing any member of the struct. The
constness of the target of the pointer does transfer to other pointers
in the struct. data is const, but data[x] is not.
A detail... the struct is not const (well, it might be, but we can't
tell from this code). The struct is being accessed via pointer whose
target type is const. Now that would indeed require a diagnostic if the
code tried to change any of the members, but it does not.
> /// image.c
> /// ...
> typedef struct {
> int w;
> int h;
> unsigned char channels;
> unsigned char *data;
> int err;
> } image_t;
>
> int image_copy(const image_t* source, const image_t* target, int
> xoffset, int yoffset) {
...
> source->data[sindex+0] = target->data[tindex++];
> source->data[sindex+1] = target->data[tindex++];
> source->data[sindex+2] = target->data[tindex++];
...
> }
> /// <eof>
--
Ben.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.std.c
csiph-web