相关疑难解决方法(0)

移位算子与-O2和不带的不同行为

没有-O2这个代码打印84 84,输出为O2标志84 42.代码是gcc 4.4.3.在64位Linux平台上编译的.为什么以下代码的输出不同?

请注意,使用-Os编译时输出为 0 42

#include <iostream>
using namespace std;

int main() {
    long long n = 42;
    int *p = (int *)&n;
    *p <<= 1;
    cout << *p << " " << n << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ 64-bit gcc strict-aliasing compiler-optimization

8
推荐指数
2
解决办法
386
查看次数

如何告诉C或C++编译器指针没有别名

我有一个接收指针数组的函数,如下所示:

void foo(int *ptrs[], int num, int size)
{ 
  /* The body is an example only  */
     for (int i = 0; i < size; ++i) { 
       for (int j = 0; j < num-1; ++j)
         ptrs[num-1][i] += ptrs[j][i];
     }
}
Run Code Online (Sandbox Code Playgroud)

我想传达给编译器的是指针ptrs[i]不是彼此的别名,并且数组ptrs[i]不重叠.我该怎么办?我别有用心的是鼓励自动矢量化.

另外,有没有办法获得与__restrict__a的迭代器相同的效果std::vector

c c++ pointers pointer-aliasing restrict-qualifier

8
推荐指数
3
解决办法
954
查看次数

使用指向结构的别名数组,而不违反标准

阅读本文我理解你可以使用别名结构(不违反标准),如果它们具有兼容的成员,即给定以下结构:

typedef struct {
    uint32_t a;
    uint32_t b;
} Frizzly;
Run Code Online (Sandbox Code Playgroud)

以下将破坏别名规则:

uint32_t foo(uint16_t *i) {
    Frizzly *f = (Frizzly *)i;
    return f->a;
}
Run Code Online (Sandbox Code Playgroud)

但以下不会:

uint32_t foo(uint32_t *i) {
    Frizzly *f = (Frizzly *)i;
    return f->b;
}
Run Code Online (Sandbox Code Playgroud)

因为所讨论的"聚合类型"包含与我们投入其中的指针兼容的类型,即指向类型的指针uint32_t可以被转换为包含类型成员(或成员)的结构,uint32_t而不会破坏别名规则.

首先,我是否理解正确?

其次,结构中(其他)变量的排序和类型是否重要?比如说,如果Frizzly定义如下:

typedef struct {
    uint16_t b[2];
    uint32_t a;
}
Run Code Online (Sandbox Code Playgroud)

在第二个示例中进行强制转换后,b现在由不兼容(uint32_t)类型的内存支持.转换是否仍然有效(或者更确切地说,通过转换指针访问值)?是否会更改任何元素a更改第一个元素的值i(以及相反的方式),就像禁用严格别名一样?

另外,如果以上内容有效,如果我有这样的结构怎么办:

typedef struct {
    void *m;
    uint16_t hooah[4];
} Bar;
Run Code Online (Sandbox Code Playgroud)

如果我是正确的话,以下演员会破坏别名规则:

void test(char *boo, size_t dee) …
Run Code Online (Sandbox Code Playgroud)

c alias strict-aliasing

8
推荐指数
1
解决办法
1105
查看次数

C中的严格别名

关于类型双关语的问题:为什么这段代码会破坏严格的别名规则:

int main()
{
    int a = 1;
    short j;

    printf("%i\n", j = *((short*)&a));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这不是:

int main()
{
    int a = 1;
    short j;
    int *p; 

    p=&a;
    printf("%i\n", j = *((short*)p));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

建设者gcc -fstrict-aliasing.

谢谢!

c gcc strict-aliasing

8
推荐指数
1
解决办法
586
查看次数

是否可以将int**和const int**替换为别名?

我的理解是这样的事情是可以的:

const int ci = 42;
const int *cip = &ci;
int *ip = (int *)cip;
int j = *ip;
Run Code Online (Sandbox Code Playgroud)

那这个呢?

const int ci = 42;
const int *cip = &ci;
const int **cipp = &cip;
int **ipp = (int **)cipp;
int j = **ipp;
Run Code Online (Sandbox Code Playgroud)

c const strict-aliasing undefined-behavior language-lawyer

8
推荐指数
1
解决办法
172
查看次数

reinterpret_cast vs严格别名

我正在阅读有关严格别名的内容,但它仍然有点模糊,我无法确定定义/未定义行为的界限.我发现最详细的帖子集中在C.所以如果你能告诉我这是否允许以及自C++ 98/11以来发生了什么变化,那将是很好的...

#include <iostream>
#include <cstring>

template <typename T> T transform(T t);

struct my_buffer {
    char data[128];
    unsigned pos;
    my_buffer() : pos(0) {}
    void rewind() { pos = 0; }    
    template <typename T> void push_via_pointer_cast(const T& t) {
        *reinterpret_cast<T*>(&data[pos]) = transform(t);
        pos += sizeof(T);
    }
    template <typename T> void pop_via_pointer_cast(T& t) {
        t = transform( *reinterpret_cast<T*>(&data[pos]) );
        pos += sizeof(T);
    }            
};    
// actually do some real transformation here (and actually also needs an inverse)
// ie this …
Run Code Online (Sandbox Code Playgroud)

c++ strict-aliasing language-lawyer reinterpret-cast

8
推荐指数
2
解决办法
974
查看次数

如何在堆栈上分配具有灵活数组成员的结构

假设我们有一个以灵活数组成员结尾的结构:

struct foo {
    size_t len;
    uint8_t data[];
};
Run Code Online (Sandbox Code Playgroud)

如何在堆栈上分配这个结构(即内存在作用域结束时自动释放)?另外,如果len能包含字段的大小就更好了data

目前,我做的事情如下:

uint8_t buf[256];
struct foo *foo = (struct foo *)buf;
foo->len = sizeof(buf) - sizeof(struct foo);
Run Code Online (Sandbox Code Playgroud)

然而,它很容易出错。使用alloca()可能会稍微好一点:

struct foo *foo = alloca(256 + sizeof(struct foo));
foo->len = 256;
Run Code Online (Sandbox Code Playgroud)

从那里,我可以定义一个像这样的宏:

#define STACK_ALLOC_FOO(SIZE) ({                          \
    struct foo *_tmp = alloca(SIZE + sizeof(struct foo)); \
    _tmp->len = SIZE;                                     \
    _tmp;                                                 \
})
Run Code Online (Sandbox Code Playgroud)

并声明它:

struct foo *foo = STACK_ALLOC_FOO(256);
Run Code Online (Sandbox Code Playgroud)

但是,我不确定分配的内存的生命周期alloca()。是内部作用域还是函数?

另外,分配全局变量不起作用(即使这不是我主要关心的问题)。

有人有在堆栈上分配具有灵活数组成员的结构的良好实践吗?

c flexible-array-member

8
推荐指数
2
解决办法
1050
查看次数

将 NumPy 数组重新解释为不同的数据类型

假设我有一个很大的 NumPy 数组dtype int32

import numpy as np
N = 1000  # (large) number of elements
a = np.random.randint(0, 100, N, dtype=np.int32)
Run Code Online (Sandbox Code Playgroud)

但现在我希望数据是uint32. 我可以

import numpy as np
N = 1000  # (large) number of elements
a = np.random.randint(0, 100, N, dtype=np.int32)
Run Code Online (Sandbox Code Playgroud)

甚至

b = a.astype(np.uint32)
Run Code Online (Sandbox Code Playgroud)

但在这两种情况下b都是 的副本a,而我想简单地将 中的数据重新解释auint32,以免复制内存。同样,使用np.asarray()也没有帮助。

起作用的是

b = a.astype(np.uint32, copy=False)
Run Code Online (Sandbox Code Playgroud)

它只是改变了dtype而不改变数据。这是一个引人注目的例子:

import numpy as np
a = np.array([-1, 0, 1, …
Run Code Online (Sandbox Code Playgroud)

python arrays types numpy python-3.x

8
推荐指数
1
解决办法
1001
查看次数

我可以将结构视为数组吗?

我有一个用于保存4D向量的结构

struct {
    float x;
    float y;
    float z;
    float w;
} vector4f
Run Code Online (Sandbox Code Playgroud)

我正在使用一个库,它有一些函数可以在向量上运行,但是以浮点指针作为参数.

打电话是否合法doSomethingWithVectors( (float *) &myVector)

c pointers vector

7
推荐指数
3
解决办法
3939
查看次数

使用强制转换为"错误"类型的指针算法

我有一个结构数组,我有一个指向其中一个结构的成员的指针.我想知道数组的哪个元素包含该成员.这有两种方法:

#include <array>
#include <string>

struct xyz
{
    float x, y;
    std::string name;
};

typedef std::array<xyz, 3> triangle;

// return which vertex the given coordinate is part of
int vertex_a(const triangle& tri, const float* coord)
{
    return reinterpret_cast<const xyz*>(coord) - tri.data();
}

int vertex_b(const triangle& tri, const float* coord)
{
    std::ptrdiff_t offset = reinterpret_cast<const char*>(coord) - reinterpret_cast<const char*>(tri.data());
    return offset / sizeof(xyz);
}
Run Code Online (Sandbox Code Playgroud)

这是一个测试驱动程序:

#include <iostream>

int main()
{
    triangle tri{{{12.3, 45.6}, {7.89, 0.12}, {34.5, 6.78}}};
    for (const …
Run Code Online (Sandbox Code Playgroud)

c++ pointer-arithmetic undefined-behavior language-lawyer

7
推荐指数
1
解决办法
476
查看次数