常量转换未定义的行为 [英] constness cast undefined behaviour

查看:80
本文介绍了常量转换未定义的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

返回的强制转换(==>)是否可以代替未定义的行为?代码的想法非常简单,可以遍历一个侵入式列表(plist)并返回找到的元素.由于代码仅进行迭代,因此不会更改列表,因此我想将其作为const指针传递.

Could the return cast (==>) give place to an undefined behavior? the idea of the code is very simple, iterate through an intrusive list (plist) and return the element if found. Since the code only iterates it doesn't change the list so I want to pass it as a const pointer.

static my_custom_type_t* get_object_by_id(const my_custom_type_t* plist, const char *my_id)
{
   const my_custom_type_t* obj = NULL;

  for (obj = plist; obj && strncmp(obj->id, my_id, MAX_SIZE); obj = obj->next)
  {
     ; //empty body
  }

   ==> return ((my_custom_type_t*) obj);
}

当函数用于获取对象并将其用作const时:

When the function is used to get an object and use it as const:

const my_custom_type_t* obj = get_object_by_id(intrusive_list, some_id);

当函数用于获取对象并将其用作非常量对象时:

When the function is used to get an object and use it as non-const object:

my_custom_type_t* obj = get_object_by_id(intrusive_list, some_id);

推荐答案

C指定了从指针到限定指针的转换,但没有指定相反的方式,C11 6.3.2.3/2:

C specifies conversions from pointers to qualified-pointers, but not the other way around, C11 6.3.2.3/2:

对于任何限定词q,指向非q限定类型的指针可能是 转换为指向该类型的q限定版本的指针;这 存储在原始指针和转换后指针中的值应进行比较 相等.

For any qualifier q, a pointer to a non-q-qualified type may be converted to a pointer to the q-qualified version of the type; the values stored in the original and converted pointers shall compare equal.

但是,C允许以下C11 6.3.2.3/7:

However, C allows the following, C11 6.3.2.3/7:

指向对象类型的指针可能会转换为指向对象类型的指针 不同的对象类型.如果结果指针不正确 如果为引用的类型对齐,则行为是不确定的. 否则,当再次转换回时,结果应等于 指向原始指针.

A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the original pointer.

简而言之,任何指针类型都可以转换为任何其他指针类型并返回.如果指针本身没有对齐问题,则除非指针被转换为非兼容类型然后取消引用,否则此类代码就可以了.合格类型指针始终是兼容类型的指针.

In plain English, any pointer type may be converted to any other pointer type and back. If there are no alignment issues with the pointer itself, such code is fine unless the pointer is converted to a non-compatible type and then de-referenced. A qualified-pointer-to-type is always a compatible type of pointer-to-type.

(请注意,这是指向对象类型的指针-函数指针是一种特殊情况.)

(Note that this refers to pointers to object type - function pointers is a special case.)

因此,这是否是UB确实取决于该指针最初指向的位置.在以下情况下,您将调用UB C11 6.7.3/6:

So whether this is UB or not really depends on where that pointer originally pointed. You invoke UB in the following case, C11 6.7.3/6:

如果尝试修改用 通过使用带有非const限定的左值的const限定类型 类型,行为是不确定的.

If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined.

如果指针最初指向只读位置,则将调用未定义的行为.但是,如果它指向一个非常量分配变量,那就没问题了.例如,此代码很好,并且不会调用未定义的行为:

If the pointer originally pointed at a read-only location, you would invoke undefined behavior. But if it pointed at a non-const, allocated variable, it would be fine. For example, this code is fine and does not invoke undefined behavior:

type t;
type* p = (type*)(const type*)&t1;

否则,正如有人在评论中指出的那样,某些C标准库函数将被根本破坏,例如strstr.

Otherwise, as someone pointed out in comments, several of the C standard library functions would be fundamentally broken, for example strstr.

这篇关于常量转换未定义的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆