转换为指向运行时确定大小的数组的指针
Posted
技术标签:
【中文标题】转换为指向运行时确定大小的数组的指针【英文标题】:Cast to pointer to array of runtime-determined size 【发布时间】:2018-03-17 05:11:23 【问题描述】:C++ 标准是否允许这种转换?我能够使用 g++ 5.4(在 linux 中运行)编译它,但不能使用 g++ 4.2(在 OSX 中运行)。
char* ptr;
char (*img)[width][3] = (char (*)[width][3])ptr;
'width' 是在运行时确定的整数。 g++ 4.2 抛出:
cannot initialize a variable of type 'char (*)[width][3]'
with an rvalue of type 'char (*)[width][3]'
这对我来说没有任何意义。
(PS:第一次编译时我真的很惊讶)
编辑
g++5.4编译的小代码
#include <iostream>
int main()
char* ptr;
int width;
std::cin >> width;
char (*img)[width][3] = (char (*)[width][3])ptr;
无法用 g++4.2 编译的 Mac 现在不在我身边,所以我无法重现错误。如 @xskxzr 与 Compiler Explorer 的 cmets 所示,it compiles in g++4.1。但是,it doesn't compile in clang,抛出了我之前说的同样的错误:
<source>:9:12: error: cannot initialize a variable of type 'char (*)[width][3]' with an rvalue of type 'char (*)[width][3]'
char (*img)[width][3] = (char (*)[width][3])ptr;
^ ~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
Compiler returned: 1
问题是:
如何解释输出错误?
g++ 版本是否可能与 OSX 完全不同?
【问题讨论】:
它 can compile 即使使用 gcc 4.1.2。 gcc 支持可变长度数组作为扩展功能。我猜您已经使用了一些命令选项来禁用此功能。此外,即使支持变长数组,由于严格的别名规则,转换仍然是未定义的行为。 我们可以有一段代码可以实际编译吗?以上内容当然不在 gcc g++ 7.0 中,在 clang 中也没有 我刚刚编辑并添加了完整的代码。 @xskxzr 我不知道严格的别名规则,我只是读了一点。据我了解,如果您有指向同一内存的不同类型的指针,编译器优化可能会搞砸,对吗? PS:我很确定我在那个 g++4.2 上没有任何特殊的命令选项 【参考方案1】:Mac 上的编译失败可能是由于 Clang 错误(所以 g++
在那里运行 Clang,而不是 GCC)。之前观察过:
可变长度数组是对 C++ 的 GNU 扩展,Clang 也应该支持它。
至少在某些版本的 Clang 中,可以通过为可变长度数组类型引入显式 typedef
来编译它:
typedef int (*vla)[width][3];
vla img = (vla) ptr;
【讨论】:
很好的答案。我不明白你所说的“g++ ran clang”是什么意思。他们不是两个不同的编译器吗? Apple 只发布了一个非常旧的 GCC 版本,它不再很有用了。显然,有一个工具链选择工具xcode-select
控制调用g++
时运行的内容。 (我不是 Mac 用户。)以上是关于转换为指向运行时确定大小的数组的指针的主要内容,如果未能解决你的问题,请参考以下文章