以下C++ 11程序:
int x = 42;
void f()
{
int y = 43;
static_assert(&x < &y, "foo");
}
int main()
{
f();
}
Run Code Online (Sandbox Code Playgroud)
不抱怨使用gcc 4.7进行编译:
error: ‘&y’ is not a constant expression
Run Code Online (Sandbox Code Playgroud)
这符合我的直觉.y每次调用时可能会发生变化的地址f,因此在翻译过程中无法计算.
然而,5.19 [expr.const]中没有一个子弹点似乎排除了它作为一个常量表达式.
我看到的唯一两个竞争者是:
左值到左值的转换......
但除非我弄错了(?),否则程序中没有左值到右值的转换.
和
一个
id-expression引用变量[snip]的除非:
- 它用一个常量表达式初始化
这y是 - 它用常量表达式初始化43.
那么这是标准中的错误,还是我错过了什么?
更新:
令人困惑的是地狱,但我认为我处于最重要的位置,所以让我展示一个展示正在发生的事情的例子:
int x = 42;
void f()
{
int y = 43;
// address constant expressions:
constexpr int* px = &x; // OK
constexpr …Run Code Online (Sandbox Code Playgroud) 如果我这样做*ptr[x],那相当于*(ptr[x]),还是(*ptr)[x]?
根据C ++草案expr.add,当您减去相同类型但不属于同一数组的指针时,其行为是不确定的(强调是我的):
当两个指针表达式P和Q相减时,结果的类型为实现定义的有符号整数类型;此类型应与在标头([support.types])中定义为std :: ptrdiff_t的类型相同。
- 如果P和Q都得出空指针值,则结果为0。(5.2)
否则,如果P和Q分别指向同一数组对象x的元素x [i]和x [j],则表达式P-Q具有值i?j。
否则,行为是不确定的。 [?注意:如果值i?j不在std :: ptrdiff_t类型的可表示值的范围内,则行为是不确定的。-?尾注?]
将此类行为设为未定义(而不是由实现定义)的原理是什么?
我正在为一个数组分配内存,但我正在移动指针向前指向一点点.访问元素工作正常.它开始产生释放已分配内存的问题.Malloc抱怨从未分配被释放的指针.这个简化的代码可以重现这个问题:
int *pointer = malloc(sizeof(int)) + 1;
free(pointer - 1);
Run Code Online (Sandbox Code Playgroud)
我开始尝试,发现代码的这种轻微变化可以工作.
int *pointer = malloc(sizeof(int));
pointer += 1;
free(pointer - 1);
Run Code Online (Sandbox Code Playgroud)
什么是+ =做不同只是添加1指针malloc返回一行?
我假设当我们写:(arr[i]相当于*(arr+i))时会发生内部强制转换.因为i例如可以是一个short,int或long或任何这些三个无符号的变体.
所以我的问题很简单:哪种类型应该i不会发生内部转换?这样代码可以最有效地运行?
粗猜:size_t?
我一直在阅读K&R关于C的书,发现C中的指针算法允许访问超出数组末尾的一个元素.我知道C允许用记忆做几乎任何事情,但我只是不明白,这种特性的目的是什么?
鉴于此代码:
int *p, *q;
p = (int *) 1000;
q = (int *) 2000;
Run Code Online (Sandbox Code Playgroud)
是什么q - p以及如何?
给定一个包含一个double和三个int变量的结构定义(总共4个变量),如果p是指向此结构的指针,其值为0x1000,那么p ++有什么值?
这不是作业问题,所以不要担心.我只是想为测试做准备,我无法弄清楚这个练习题.谢谢
这是在C.是的,我希望增加后的p值.这是一台32位机器
我正在编写和读取内存映射中的寄存器,如下所示:
//READ
return *((volatile uint32_t *) ( map + offset ));
//WRITE
*((volatile uint32_t *) ( map + offset )) = value;
Run Code Online (Sandbox Code Playgroud)
但是编译器给了我这样的警告:
warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
Run Code Online (Sandbox Code Playgroud)
如何更改我的代码以删除警告?我正在使用C++和Linux.
请考虑以下代码片段:
int (*p)[3];
int (*q)[3];
q = p;
q++;
printf("%d, %d\n", q, p);
printf("%d\n", q-p);
Run Code Online (Sandbox Code Playgroud)
我知道指针算法是智能的,这意味着操作q++前进q足够的字节指向下一个3整数数组,所以第一次打印是' 12, 0' 并不意味着递增q使它在12中更大.
但第二次印刷确实令我惊讶.它打印1!
那么为什么它会打印1而不是12?它只是困惑我.