写作绅士,读作丧尸 X岛揭示板
顺猴者昌 逆猴者亡 首页版规 |用户系统 |移动客户端下载 | 丧尸路标 | | 常用图串及路标 | 请关注 官方公众号:【X岛揭示板】 官方微博: 【@X岛极速版】| 人,是会思考的芦苇
常用串:·豆知识·跑团板聊天室·公告汇总串·X岛路标

No.60417043 - 无标题 - 技术宅


回应模式
No.60417043
名 称
E-mail
标题
颜文字
正文
附加图片
•程序语言、压制投稿、视频制作以及各计算机领域的技术问题
•我觉得还是CSDN靠谱一点
•本版发文间隔为15秒。

无标题 无名氏 2023-12-04(一)12:49:09 ID:MYwW17N [举报] [订阅] [只看PO] No.60417043 [回应] 管理
int a0[0,3] = { 1,2,3 };
printf("%d\n", *(*&a + 1)-1));
//output:3
能解释一下这个的逻辑吗?
( ゚ᯅ 。)
无标题 无名氏 2023-12-04(一)16:19:35 ID:B15U5vD [举报] No.60419242 管理
>>No.60419164
现在在忙,待会儿我上ide测试一下
但是直觉上感觉不对劲
无标题 无名氏 2023-12-04(一)19:21:06 ID:c1VkhIS [举报] No.60421484 管理
*&可以抵消
*(a+1)-1
a在这里转换成&a0[0,0],a+1指向第二个元素,解应用变成2,减1变成1
无标题 语法律师 2023-12-04(一)19:37:46 ID:5IJAv3m [举报] No.60421672 管理
>>No.60419164
真要较真的话是UB
简单的总结就是指针的代数运算仅限于nullptr+0以及同一个数组内部不越界的加减法
只是编译器实现上只要你不去解引用这些野指针就不会出问题
refs: http://eel.is/c++draft/expr.add#4
无标题 无名氏 2023-12-04(一)19:52:03 ID:5IJAv3m [举报] No.60421852 管理
>>No.60421672
顺带一提C也一样
http://port70.net/%7Ensz/c/c11/n1570.html#6.5.6p8
无标题 无名氏 2023-12-04(一)20:08:16 ID:5IJAv3m [举报] No.60422041 管理
>>No.60421672
不过C++考虑到这个http://eel.is/c++draft/expr.add#note-1 note大概不是UB...不过仅限+1
无标题 无名氏 2023-12-05(二)00:02:16 ID:wPfGExo [举报] No.60425375 管理
>>No.60421852
cpp姑且不讨论,但你给出的这份关于c语言行为描述清单是基于c11标准的,而主流编译器默认还是以c99为标准的,只能做个参考。
无标题 无名氏 2023-12-05(二)00:11:49 ID:wPfGExo [举报] No.60425515 管理
>>No.60421484
这个说法是不正确的,&a + 1 的地址是基于 &a 的地址 偏移 1个 sizeof(a) ,a + 1 地址是基于a的地址偏移 1个 sizeof(int) 。
运行一下可以验证,修改后输出是 1 ,即第一个元素。
无标题 无名氏 2023-12-05(二)01:38:41 ID:c1VkhIS [举报] No.60426423 管理
>>No.60425515
|∀゚因为上面的那个回复是串首的
无标题 无名氏 2023-12-05(二)08:13:04 ID:B15U5vD [举报] No.60427355 管理
>>No.60425375
?我的编译器(gcc12)默认支持c11和之后的特性呀
你用的什么?
无标题 无名氏 2023-12-05(二)08:31:05 ID:5IJAv3m [举报] No.60427459 管理
>>No.60425375
指针加减行为这事情还是不太可能有改动的,尤其是C这种很保守的语言

C99的标准文本https://busybox.net/~landley/c99-draft.html#6.5.6

我不我发帖的时候看漏了一条,就是两个链接上面的条文
For the purposes of these operators, a pointer to a nonarray object behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.
(C++也有类似的脚注)

也就是说对于C/C++而言,&a+1这个表达式都是良构的

但是,这时候 &a+1 指向的是不存在的对象,这个指针只能减回去/作差/比大小,对它进行解引用是UB

或者按照C的标准文本:
If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated.
按照C++也一样,解引用非指向完整的对象的指针是非法的(只有指向对象或函数头的指针是可以解引用的),于是依然是UB(^o^)ノ

至于为什么这个奇怪的指向不存在对象的指针要允许它是合法的指针大概是为了和迭代器行为一致保证的...这些都是语言设计的破事了

但是总而言之,*(&a+1)构成UB!
无标题 无名氏 2023-12-05(二)12:33:33 ID:wPfGExo [举报] No.60430013 管理
>>No.60427355
这是我的问题,我默认了编译器支持c99,没有查证,我pc上的3个c编译器 gcc,clang,zig0.11 附带编译器 都已经支持了c17 标准了。

UP主: