这是在dev c ++ windows中编译的代码:
#include <stdio.h>
int main() {
int x = 5;
printf("%d and ", sizeof(x++)); // note 1
printf("%d\n", x); // note 2
return 0;
}
Run Code Online (Sandbox Code Playgroud)
x执行注释1后,我希望是6 .但是,输出是:
4 and 5
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么x在注1后没有增加?
我们都知道解除引用空指针或指向未分配内存的指针会调用未定义的行为.
但是在传递给表达式时使用的规则是什么sizeof?
例如:
int *ptr = 0;
int size = sizeof(*ptr);
Run Code Online (Sandbox Code Playgroud)
这也未定义吗?
有一个众所周知的模式来计算数组长度:
int arr[10];
size_t len = sizeof(arr) / sizeof(arr[0]);
assert(len == 10);
Run Code Online (Sandbox Code Playgroud)
此模式适用于静态数组和常量大小的自动数组.它也适用于C99中的可变长度数组.
我想应用类似的想法来计算动态数组大小(以字节为单位):
size_t known_len = 10;
int *ptr = malloc(known_len * sizeof(int));
size_t size = known_len * sizeof(ptr[0]);
assert(size == known_len * sizeof(int));
Run Code Online (Sandbox Code Playgroud)
这比known_len * sizeof(int)因为sizeof(ptr[0])没有引用实际的数组元素类型更好.因此,它不需要代码的读者知道类型.
然而,我不清楚表达是否sizeof(ptr[0])会导致不确定的行为.随着它扩大:
sizeof(ptr[0]) -> sizeof(*((ptr) + (0))) -> sizeof(*ptr)
Run Code Online (Sandbox Code Playgroud)
如果ptr是,结果表达式是有问题的0:
sizeof(*((int*) 0))
Run Code Online (Sandbox Code Playgroud)
根据C99标准:
(C99,6.3.2.3p3):"带有值的整型常量表达式
0,或者这种表达式转换为类型void *,称为空指针常量." 取消引用空指针是未定义的行为.(C99,6.5.3.2.p4)"如果为指针分配了无效值,则一元运算
*符的行为未定义.87)"87):"一元运算
*符解除引用指针的无效值中有一个空指针,一个与指向的对象类型不一致的地址,以及一个对象在其生命周期结束后的地址."
但是从未指明这种表达式的sizeof是否会导致未定义的行为.实际上,应该在编译时评估这样的sizeof.
我的问题是:
sizeof(ptr[0])当类型ptr已知并且值ptr …最近我遇到了一个结构定义,
struct arr {
int cnt;
struct {
int size;
int *name;
} list[0];
};
Run Code Online (Sandbox Code Playgroud)
现在我不知道list[0]被宣布的原因.我感兴趣的是为什么使用它.它有什么优势吗?如果是,那是什么?