Beware, heavy cross-posting. Beware furthermore: "const" has a
*different* meaning in C than in C++. In particular, C "const"
variables are actually variables, not constants:
const int seven = 7;
int i;
...
switch (i) {
case 3: ... code for i==3 ...
case seven: ... /* this line is an error in C, but OK in C++ */
}
In C "const" *always* means "read-only variable", much like
"extern const" in C++.
Summary of issue: Suppose "p" is a pointer to a const-qualified
structure or class variable, i.e., "const struct S *p" rather than
unqualified "struct S *p". What are the implications of an assignment
of the form "p->field[index] = new_value"? The answer depends on
whether the "field" member is a pointer or an array.
"John Carson" <do***********@datafast.net.au> wrote in message
news:40******@usenet.per.paradox.net.au... ... If the struct contains pointers, then that means the
pointers cannot be changed. The data pointed to by the pointers is *not*
part of the struct, so it can be changed.
With arrays, by contrast, the array elements are part of the struct and
hence they cannot be changed.
In article <news:c5********@dispatch.concentric.net>
Howard <al*****@hotmail.com> writes:That still does not make sense to me ...
Think of it as an "ownership issue". If I buy an array and lend it
to you, so that you point to it, *my* rules apply to that array,
even though you have borrowed it.
On the other hand, if *you* buy an array, *your* rules apply to it.
The const-ness of the array members depends on who "owns" them.
If the array is part of "struct S" (as a member named "field"), it
is the "struct S" that owns them; if the member named "field" is
just a pointer, it points to an array owned elsewhere, and the
const-ness of the array elements cannot be determined from the
const-ness of "*p".
and I've tested the idea and found that's not the case at all.
I fear your test merely shows that the effect of undefined behavior
is often "hey, it works for me". :-) Alas, this is the sort of
thing that leads people to think that:
int i = 0;
...
f(i++, i++, i++); /* DANGER */
is well-defined and (depending on their system) always passes {2,
1, 0} or always passes {0, 1, 2} to f(). (Many systems actually
deliver one or the other fairly consistently.)
I snipped the original C++ example code, which was rather fatally
flawed for showing the problem (classes with constructors generally
need to be run-time modifiable even when const-qualified; you have
to stick to PODs *and* use static instances of each object).
Try this example instead (compile-able as both C *and* C++). First
the output:
% ln t.c++ t.c
[same program!]
% gcc -O -o t t.c -ansi -pedantic -Wall
% ./t
this was compiled with a C compiler
before:
P.field[0] = a
A.field[0] = a
modify P
P.field[0] = b
modify A
Segmentation fault (core dumped)
[C version crashes]
% gcc -O -o t t.c++ -Wall
% ./t
this was compiled with a C++ compiler
before:
P.field[0] = a
A.field[0] = a
modify P
P.field[0] = b
modify A
Segmentation fault (core dumped)
[C++ version crashes]
And the code:
#include <stdio.h>
struct ptr {
char *field;
};
struct arr {
char field[1];
};
void wr_ptr(const struct ptr *p) {
p->field[0] = 'b';
}
void wr_arr(struct arr *p) { /* cannot use "const" here */
p->field[0] = 'b';
}
static char buf[1] = { 'a' };
static const struct ptr P = { buf };
static const struct arr A = { { 'a' } };
struct trick2 { char x[1]; };
int main(void)
{
struct scopetrick { struct trick2 { char x[2]; } x; };
printf("this was compiled with a %s compiler\n",
sizeof ((struct trick2 *)0)->x == 2 ? "C" : "C++");
printf("before:\n");
printf(" P.field[0] = %c\n", P.field[0]);
printf(" A.field[0] = %c\n", A.field[0]);
fflush(stdout);
printf("modify P\n");
fflush(stdout);
wr_ptr(&P);
printf(" P.field[0] = %c\n", P.field[0]);
fflush(stdout);
printf("modify A\n");
fflush(stdout);
wr_arr((struct arr *)&A); /* cast required here */
printf(" A.field[0] = %c\n", A.field[0]);
fflush(stdout);
return 0;
}
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it
http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.