Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to access non-const object through const lvalue?

The 6.5(p7) states this:

An object shall have its stored value accessed only by an lvalue expression that has one of the following types:88)

— a type compatible the effective type of the object,

— a qualified version of a type compatible with the effective type of the object,

— a type that is the signed or unsigned type corresponding to the effective type of the object,

— a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,

Taking a look at 6.7.3(p10):

For two qualified types to be compatible, both shall have the identically qualified version of a compatible type;

So double and const double are not compatible because their type qualifiers are not the same.

Now I assumed that signed or unsigned type mean signed or unsigned integer type as defined it 6.2.5(p4) and 6.2.5(p6) correspondingly since 6.2.5 does not define signed type by itself.

Now consider the following code:

void print_double(const double d){
    printf("d = %lf\n", d);
}

int main(int args, const char *argv[]){
    double d = 10.2;
    print_double(d);
}

Now I try to apply 6.5 (p7):

I. a type compatible the effective type of the object

No, const double and double are not compatible.

II. a qualified version of a type compatible with the effective type of the object

No, qualified version of const double will make it even more qualified then const double

III/IV.

No, double is not a signed or unsigned integer type.

This judgement seems faulty because it should be ok to access non-const object via const-qualified lvalue. But I cannot derive that from 6.5(p7).

like image 999
Some Name Avatar asked Jan 01 '26 07:01

Some Name


1 Answers

Now consider the following code:

void print_double(const double d){
    printf("d = %lf\n", d);
}

int main(int args, const char *argv[]){
    double d = 10.2;
    print_double(d);
}

Your code doesn't do any aliasing. The d in main and the d in print_double are distinct objects, since arguments are always passed by value. But if we were to "fix" the example:

void print_double(const double *pd){
    printf("d = %lf\n", *pd);
}

int main(int args, const char *argv[]){
    double d = 10.2;
    print_double(&d);
}

It's still well-defined. *pd is an lvalue of type const double. const double is a qualified version of double. All types are compatible with themselves (trivially). So the second bullet holds and this aliasing is valid.

like image 135
StoryTeller - Unslander Monica Avatar answered Jan 03 '26 10:01

StoryTeller - Unslander Monica