在gcc-strict-aliasing-and-casting-through-a-union中,我问是否有人遇到过通过指针进行联合惩罚的问题.到目前为止,答案似乎是否定的.
这个问题是广泛的:你有任何关于gcc和严格走样恐怖故事?
背景:引用AndreyT在c99-strict-aliasing-rules-in-c-gcc中的答案:
"严格的别名规则植根于自[标准化]时代开始以来C和C++中存在的标准部分.禁止通过另一种类型的左值访问一种类型的对象的条款存在于C89/90中(6.3 )以及C++ 98(3.10/15)......并非所有编译器都希望(或敢于)强制执行或依赖它.
好吧,gcc现在敢于用它的-fstrict-aliasing开关来做到这一点.这引起了一些问题.例如,请参阅有关Mysql错误的优秀文章 http://davmac.wordpress.com/2009/10/,以及http://cellperformance.beyond3d.com/articles/2006/06/understanding中同样出色的讨论.-strict-aliasing.html.
其他一些不太相关的链接:
重复一遍,你有自己的恐怖故事吗?当然,没有表示的问题-Wstrict-aliasing是优选的.其他C编译器也很受欢迎.
6月2日补充:迈克尔伯尔的答案中的第一个链接,确实有资格作为恐怖故事,可能有点过时(从2003年开始).我做了一个快速测试,但问题显然已经消失了.
资源:
#include <string.h>
struct iw_event { /* dummy! */
int len;
};
char *iwe_stream_add_event(
char *stream, /* Stream of events */
char *ends, /* End of stream */
struct iw_event *iwe, /* Payload */
int event_len) /* Real size of payload …Run Code Online (Sandbox Code Playgroud) 我正在努力实现共享内存缓冲区而不破坏C99的严格别名规则.
假设我有一些处理一些数据的代码,需要有一些'临时'内存来运行.我可以把它写成:
void foo(... some arguments here ...) {
int* scratchMem = new int[1000]; // Allocate.
// Do stuff...
delete[] scratchMem; // Free.
}
Run Code Online (Sandbox Code Playgroud)
然后我有另一个功能,做一些其他需要一个临时缓冲区的东西:
void bar(...arguments...) {
float* scratchMem = new float[1000]; // Allocate.
// Do other stuff...
delete[] scratchMem; // Free.
}
Run Code Online (Sandbox Code Playgroud)
问题是在操作期间可能会多次调用foo()和bar(),并且在性能和内存碎片方面,整个地方的堆分配可能非常糟糕.一个明显的解决方案是分配一个适当大小的公共共享内存缓冲区,然后将其作为参数传递给foo()和bar(),BYOB样式:
void foo(void* scratchMem);
void bar(void* scratchMem);
int main() {
const int iAmBigEnough = 5000;
int* scratchMem = new int[iAmBigEnough];
foo(scratchMem);
bar(scratchMem);
delete[] scratchMem;
return 0;
}
void foo(void* scratchMem) {
int* smem = (int*)scratchMem;
// …Run Code Online (Sandbox Code Playgroud) 是否可以std::vector<unsigned char>通过其数据指针操作 an ,就好像它是 的容器一样float?
这是一个编译和(似乎?)按需要运行的示例(GCC 4.8,C++11):
#include <iostream>
#include <vector>
int main()
{
std::vector<unsigned char> bytes(2 * sizeof(float));
auto ptr = reinterpret_cast<float *>(bytes.data());
ptr[0] = 1.1;
ptr[1] = 1.2;
std::cout << ptr[0] << ", " << ptr[1] << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此代码段成功地从字节缓冲区写入/读取数据,就好像它是一个float. 从阅读有关 reinterpret_cast我担心这可能是未定义的行为。我对理解类型别名细节的信心太小,无法确定。
代码片段是否如上文所述的未定义行为?如果是这样,是否有另一种方法来实现这种字节操作?