Re: [问题] 求问一题指标题输出

楼主: poyenc (发箍)   2021-07-23 01:50:40
※ 引述《ericerix (我的帅,在于脸)》之铭言:
: int main(){
: int a[5] = {1, 2, 3, 4, 5};
: int *p = (int *)(&a + 1);
: printf("%d, %d",*(a+1), (*p-1));
: return 0;
: }
在说明以前, 先定义以下宏 (macro) 来让编译器告诉我们叙述的
型别是什么:
#define TYPENAME_OF(var) _Generic((var), \
int(*)[5]: "int(*)[5]", \
int* : "int*", \
int : "int", \
default : "unknown" \
)
然后我们就可以试着印出以下几个叙述的型别:
printf("TYPENAME_OF(&a): %s\n", TYPENAME_OF(&a));
printf("TYPENAME_OF(&a + 1): %s\n", TYPENAME_OF(&a + 1));
printf("TYPENAME_OF(p): %s\n", TYPENAME_OF(p));
// output:
// TYPENAME_OF(&a): int(*)[5]
// TYPENAME_OF(&a + 1): int(*)[5]
// TYPENAME_OF(p): int*
从这可以看到其实 (&a + 1) 的型别和 p 是不相容的, 所以在不加
转型时编译器会报 warning. 不是说不能做这样的转型, 但你要清
楚知道对阵列或是变量 var 来说, 能够取值的位址范围落在
[&var, &var + 1) 之间 (6.5.6/9), 除此之外都是 undefined be-
havior.
printf("valid address range: [%p, %p)\n", &a, &a + 1);
printf("a + 1: %p\n", a + 1);
printf("p : %p\n", p);
// (possible) output:
// valid address range: [0x7fffffb2ede0, 0x7fffffb2edf4)
// a + 1: 0x7fffffb2ede4
// p : 0x7fffffb2edf4
因为 p 指到界外, 所以原本程式里的 *p 是不合法的; 如果改成
p - 1 虽然指标值刚好和最后一个元素的位址相同, 但因为 p 的语
意已经和 (&a + 1) 不一样 (one past the last element), 原则
上拿 p 往前减再取值依然是 undefined behavior. 不管对哪个阵
列而言, p 都是外部指标, 不能透过外部指标直接或间接存取阵列
元素.
如果想避免 undefined behavior, 那记得当你想存取 int 元素时,
从任意 int 元素的位址 (内部指标) 开始做计算:
int *p = a + (sizeof a / sizeof a[0]);
printf("*(p - 1): %d\n", *(p - 1));
指向 one past the last element 的指标虽然无法用来取值, 但它
仍属于阵列的内部指标.
-
References
ISO/IEC 9899:202x (E) (N2596)
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf
Pointers are more abstract than you might expect in C
https://pvs-studio.com/en/blog/posts/cpp/0576/
作者: ericerix (Ponwar)   2021-07-23 09:49:00
太详细了,谢谢大大替我解答。那个宏的写法我没读到过,请问有关键字能够查询吗?
作者: LPH66 (-6.2598534e+18f)   2021-07-23 09:56:00
https://en.cppreference.com/w/c/language/genericC11 的新东西, 让编译器用式子的形态选式子执行
作者: Jockey66666 (往事已成追忆)   2021-07-23 10:48:00
又偷学一招,棒
作者: ericerix (Ponwar)   2021-07-23 11:22:00
谢谢你!
作者: sarafciel (Cattuz)   2021-07-23 11:39:00
作者: F04E (Fujitsu)   2021-07-23 15:40:00
板主怎么都没m
作者: DLHZ ( )   2021-07-26 19:05:00
推用心

Links booklink

Contact Us: admin [ a t ] ucptt.com