问题标签 [pointer-conversion]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
2025 浏览

c++ - 从派生**转换为基础**

我正在阅读这篇文章,不幸的是无法深入理解为什么编译器不允许从 Derived** 转换为 Base**。我也看到了这个,它提供的信息不比 parashift.com 的链接更多。

编辑:

让我们逐行分析这段代码:

0 投票
1 回答
313 浏览

c++ - 指针到指针到常量的转换

我正在阅读一本名为C++ Gotchas的书,它解释了 const 指针之间的转换,但我在理解以下规则时遇到了一些麻烦:

如果存在类型 T 且整数 n > 0,则两个指针类型 T1 和 T2 相似,使得:

T1 是cv 1 ,0 指向cv 1,1 指向 . . . cv 1,n−1 指向cv 1,n T的指针

和,

T2 是cv 2,0 指向cv 2,1 的指针。. . cv 2,n−1 指向cv 2,n T的指针

其中每个 cvi,j 是 const、volatile、const volatile 或什么都没有。

有人能指出我可以得到解释的正确方向吗,或者有人熟悉cv 1,0cv 1,1在上述每个序列中的含义吗?这本书没有帮助我足够理解它。但我确信这与 C++ 语言有关。

0 投票
1 回答
14725 浏览

c++ - 通过引用传递 const 指针

我很困惑为什么以下代码无法编译

编译器给出错误为:

错误:从“float*”类型的表达式中对“const float*&”类型的引用进行无效初始化

但是当我尝试在 foo 中不通过引用传递时,它编译得很好。

我认为无论我是否通过引用,它都应该表现出相同的行为。

谢谢,

0 投票
1 回答
1031 浏览

c++ - C++ 中的 reinterpret_cast

当我尝试运行此代码时,行出现分段错误

uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);

事实上,在某个地方运行正常。在另一个地方,它给出了段错误。

0 投票
1 回答
123 浏览

c++ - C++转换:有指向对象成员的指针,计算指向对象的指针

C++ 必须static_cast转换base_class_pointerderived_class_pointer.

object_data_member_pointer转换为 的操作非常相似object_pointer

ConvertDataMemberPtrToObjectPtr我使用不安全的 C 类型转换编写了该函数。

  • 如何以安全的方式做到这一点?成员的链接必须指定为模板参数member_ptr
  • 如果您使用这样的实现,是否会出现任何问题?

资源:

使用父母而不是成员和static_cast

0 投票
1 回答
1083 浏览

c - uchar数组到uint8类型指针的转换

我想将一个 uchar 数组转换为 uint8 指针。由于两者都是 8 位,值范围从 0 到 255,所以我认为它不应该引起和问题。

我必须将上面的列表传递给一个接受指向 uint8t 的指针的函数。我可以这样通过吗:

这样当我将其读取为 uint8 时它不会影响该值。

0 投票
2 回答
276 浏览

c - 使用指针进行类型转换

我不知道类型转换如何与指针一起工作

*(byte )&x发生了什么?&x 表示变量x的地址。那么类型转换地址是什么意思呢?现在 ptr 也可以引用 x 吗?如果是,那么我们不会丢失数据吗?

另外ptr的大小是多少?

0 投票
1 回答
430 浏览

c++ - 指针/整数算术(未)定义的行为

我有以下功能模板:

目的是复制特定类型的对象并将其返回为与输入相同的子对象“持有”。请注意,原则上,HeldAs可以是 的模棱两可或不可访问的基类MostDerived,因此在这里没有强制转换可以提供帮助。

这是我的代码,但它可以用于我无法控制的类型(即我不能修改MostDerivedor HeldAs)。该函数具有以下前提条件:

  • *original是动态类型的MostDerived
  • HeldAsMostDerived或直接或间接的基类MostDerived(忽略 cv 限定)
  • *held*original或其基类子对象之一。

让我们假设先决条件得到满足。在这种情况下是否duplicate有定义的行为?

C++11 [expr.reinterpret.cast] 说(我的粗体强调):

4 指针可以显式转换为任何大到足以容纳它的整数类型。映射函数是实现定义的。[注意:对于那些知道底层机器的寻址结构的人来说,这并不奇怪。——尾注] ...

5 整数类型或枚举类型的值可以显式转换为指针。转换为足够大小的整数(如果实现中存在这样的整数)并返回相同指针类型的指针将具有其原始值;指针和整数之间的映射是由实现定义的。[注意:除 3.7.4.3 中描述的情况外,这种转换的结果不会是安全派生的指针值。——尾注]

好的,假设我的编译器是 GCC(或 Clang,因为它使用 GCC 对实现定义的行为的定义)。引用GCC 文档第 5 章关于 C++ 实现定义的行为:

... 一些选择记录在 C 语言的相应文档中。请参阅C 实现。...

第 4.7 章(C 实现、数组和指针):

将指针转换为整数或反之亦然的结果(C90 6.3.4、C99 和 C11 6.3.2.3)。

如果指针表示大于整数类型,则从指针到整数的强制转换丢弃最高有效位,如果指针表示小于整数类型,则符号扩展,否则位不变。

如果指针表示小于整数类型,则从整数到指针的强制转换丢弃最高有效位,如果指针表示大于整数类型,则根据整数类型的符号进行扩展,否则位不变。

到目前为止,一切都很好。似乎因为我使用std::uintptr_twhich 保证对于任何指针都足够大,并且因为我正在处理相同的类型,所以copyHeld应该指向as的相同HeldAs子对象。*copyheld*original

不幸的是,GCC 文档中还有一段:

当从指针转换为整数并再次转换时,结果指针必须引用与原始指针相同的对象,否则行为未定义。也就是说,不能使用整数算术来避免指针算术的未定义行为,如 C99 和 C11 6.5.6/8 中所禁止的。

威猛。所以现在看来​​,即使copyHeld是按照前两段的规则计算的值,第三段仍然将其发送到 Undefined-Behaviour 领域。

我基本上有三个问题:

  1. 我的阅读是否正确以及duplicate未定义的行为?

  2. 这是哪种未定义行为?“正式未定义,但无论如何都会做你想做的事”的那种,还是“预期随机崩溃和/或自发自焚”的那种?

  3. 如果它真的是未定义的,有没有办法以明确定义(可能依赖于编译器)的方式来做这样的事情?

虽然就编译器而言,我的问题仅限于 GCC(和 Clang)行为,但我欢迎一个考虑各种硬件平台的答案,从常见的桌面到异国情调的桌面。

0 投票
1 回答
114 浏览

c++ - 为什么不允许将 Derived T::* 转换为 Base T::*?

背景:许多函数式语言支持代数数据类型,在一定程度上可以用虚函数和继承来模拟。

最明显的解决方案涉及堆分配,因为派生类型具有不同的大小。但是,我们应该能够使用联合来保存堆栈上最大的类型,而无需任何额外分配。这需要一个额外的指向基址的指针与联合一起存储,同时使复制和赋值复杂化。

通过将成员选择器存储为从指向活动联合成员的联合开始的偏移量来解决后一个问题是令人信服的。C++ 的成员指针似乎几乎适合此目的,除了指向每个成员的指针将具有不同的类型。

问题:为什么不允许将 Derived T::* 转换为 Base T::*?

这是一个与上述无关的玩具示例,它遇到了相同的限制:

生成的编译错误:

0 投票
1 回答
1130 浏览

c - C 函数指针类型兼容性

编写一个与函数回调一起使用的库,我经常将函数指针类型转换(和调用)指向具有相同调用约定和相同签名的类型,但有一个例外:它们具有指向不同类型(所有数据)的参数,或空指针。

最近,我发现它可能不是那么安全,根据这个:https ://stackoverflow.com/a/14044244/3079266

基本上,据我了解,如果参数的类型兼容,则意味着函数指针类型也兼容,应该没有问题。

现在,我有 3 个问题。

第一:这是否意味着,由于指向不同类型的指针在技术上是不兼容的,所以我正在做的事情会导致未定义的行为?

第二:我可以在哪里(在什么架构上)摆脱它?其中是 Windows x86 还是 x64 版本?

第三:我在哪里不能逃脱它?