c - 已知大小的未指定类型的指针算法
问题描述
void * ptr = NULL; // array of unspecified 13-byte type
for (int i = 0; i < 10; i++) {
printf("%i ", ((char (*) [13]) ptr) + i);
}
putchar('\n');
输出:
0 13 26 39 52 65 78 91 104 117
所以这有效(至少在 GCC 上),但是我如何声明一个类型的变量,(char (*) [13]
这样我就不必每次想对该指针执行指针算术时都进行强制转换?
这种行为甚至是可移植的吗?
解决方案
已知大小的未指定类型的指针算法
这种行为甚至是可移植的吗?
严格地说:也许:
需要深入了解C17 6.3.2.3 Pointers
像下面这样的东西依赖于&fred[0]
能够ptr
毫无困难地转换的价值。许多实现将毫无问题地处理这个问题,但ptr
它是指向数组的指针,而不是指向char
. 一直ptr
是指针char
,没问题。
我认为因为ptr
两者fred
都有相同的对齐要求 - 代码是可以的。
typedef something unspecified_13_byte_type;
assert(sizeof(unspecified_13_byte_type) == 13);
#define N
unspecified_13_byte_type fred[N];
char (*ptr)[13] = (void *) fred;
for (int i = 0; i < N; i++) {
// printf("%i ", ((char (*) [13]) ptr) + i);
printf("%p ", (void *) (((char (*) [13]) ptr) + i));
}
puts("");
更深一点: if something
is some struct
, then ptr
and&fred[0]
不必是相同的编码甚至相同的大小 - 即使它们很好地相互转换并相互等同。 struct
指针,并且char *
可能与通常预期的不同 - 即使这种差异在今天非常罕见。
推荐阅读
- elasticsearch - Elasticsearch 集群故障后 Filebeat 无法发送日志
- apache-spark - 无法使用 Airflow 创建我的 pyspark 脚本的 cron 作业
- arrays - 为什么 PowerShell 将“Where”的谓词应用于空列表
- java - 当 spring.jpa.generate-ddl=false 时仍然生成 H2 模式
- java - 如何在 vertx webclient 中设置请求超时
- sql - 在 where 子句中使用多个聚合函数
- c# - 处理服务结构中的异常
- python - 在 Python 中导入相关子模块的特定部分
- php - 如何在php中将错误消息更改为自定义消息
- python - 回文中作为输出的意外真实值