编写反序列化函数将字节数组转换为 32 位无符号整数的最佳方法是什么?
typedef unsigned long uint32;
uint32 deserialize_uint32(unsigned char *buffer)
{
uint32 value = 0;
value |= buffer[0] << 24;
value |= buffer[1] << 16;
value |= buffer[2] << 8;
value |= buffer[3];
return value;
}
unsigned char* deserialize_uint32B(unsigned char *buffer, uint32* value)
{
*value = 0;
*value |= buffer[0] << 24;
*value |= buffer[1] << 16;
*value |= buffer[2] << 8;
*value |= buffer[3];
return buffer + 4;
}
Run Code Online (Sandbox Code Playgroud)
谢谢!或者如果有更好的方法请告诉我..谢谢!
我担心我可能会遗漏一些微不足道的东西,但是如果你想保留原始的无符号值,似乎没有实际的安全方式来转换为签名类型.
在reinterpret_cast上,5.2.10没有列出整数到整数的转换,因此没有定义(而static_cast定义没有额外的转换).关于积分转换4.7.3基本上说大型无符号的转换将是实现定义的(因此不可移植).
这似乎是有限的,因为我们知道,例如,uint64_t在任何硬件上,应该可以安全地转换为a int64_t和back而不会改变值.另外,标准布局类型的规则实际上保证了安全转换,如果我们memcpy在两种类型之间而不是分配.
我对么?有没有合理的理由为什么不能reinterpret_cast在整数类型之间有足够的大小?
澄清:肯定无符号的签名版本不保证值,但它只是我考虑的往返(unsigned => signed => unsigned)
更新:仔细查看答案并交叉检查标准,我相信memcpy实际上并没有保证工作,因为它没有说明这两种类型是布局兼容的,也不是char类型.进一步更新,深入研究C-standard这个memcpy应该可以工作,因为目标的大小足够大并且它复制了字节.
答案:似乎没有技术上的理由说明为什么不允许reinterpret_cast执行此转换.对于这些固定大小的整数类型,a memcpy保证可以工作,实际上只要中间可以表示所有的位模式,任何中间类型都可以使用(浮点数可能很危险,因为可能存在陷阱模式).通常,您不能在任何标准布局类型之间进行memcpy,它们必须是兼容的或char类型.这里的注明是特殊的,因为它们有额外的保证.
我试图在我在C++ 11中编写的同一个应用程序中使用两个库LIBSVM和LIBLINEAR.LIBSVM和LIBLINEAR都在基本上是基于行的稀疏矩阵表示中输入它们:存在节点结构
struct svm_node
{
int index;
double value;
};
Run Code Online (Sandbox Code Playgroud)
稀疏矩阵本身就是struct svm_node **,每行都是a struct svm_node *,行终止index = -1.调用此结构的LIBLINEAR版本feature_node并具有相同的定义.虽然LIBSVM和LIBLINEAR由同一作者写的,svm.h和linear.h,因此struct svm_node和struct feature_node是没有丝毫关系.
在某些情况下,我想创建一个内核SVM模型(仅由LIBSVM实现)和一个逻辑回归模型(仅由LIBLINEAR实现)我的数据.数据集传递给它们各自的库---在二进制级别上,相同的---稀疏矩阵表示,可能非常大,我宁愿避免memcpy()全部.一个简单的reinterpret_cast<feature_node **>(svm_node_ptr_ptr_variable)似乎做得很好.
我也在-flto发布版本中使用LLVM的完整程序优化(),因此我希望确保代码不会以不可预测的方式进行优化.
有什么办法型双关语svm_node **为feature_node **避免可能的(当前或未来)编译器优化导致的任何破损?__attribute__((__may_alias__))在这里有帮助,如果有,我应该如何使用它?
如果__attribute__((__may_alias__))只对类型有意义,那么如果我创建了自己的struct和指向结构的指针,它是否有效
struct __attribute__((__may_alias__)) SparseElement {
int index;
double value;
};
typedef SparseRow SparseElement * __attribute__((__may_alias__));
Run Code Online (Sandbox Code Playgroud)
然后将retinterpret_casted 传递SparseRow * …
我正在尝试在C上做OOP(只是为了好玩)而且我想出了一个方法来进行数据抽象,方法是使用公共部分和更大的结构,首先是公共部分,然后是私有部分.这样我在构造函数中创建整个结构并将其返回到小结构.这是正确的还是会失败?
这是一个例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// PUBLIC PART (header)
typedef struct string_public {
void (*print)( struct string_public * );
} *string;
string string_class_constructor( const char *s );
void string_class_destructor( string s );
struct {
string (*new)( const char * );
void (*delete)( string );
} string_class = { string_class_constructor, string_class_destructor };
// TEST PROGRAM ----------------------------------------------------------------
int main() {
string s = string_class.new( "Hello" );
s->print( s );
string_class.delete( s ); s = NULL;
return 0;
}
//------------------------------------------------------------------------------ …Run Code Online (Sandbox Code Playgroud) 我有一个结构数组,我有一个指向其中一个结构的成员的指针.我想知道数组的哪个元素包含该成员.这有两种方法:
#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) 我已经阅读了一段时间的严格别名规则,我开始变得非常困惑.首先,我已经阅读了这些问题和一些答案:
根据它们(据我所知),char使用指向另一种类型的指针访问缓冲区违反了严格的别名规则.但是,glibc实现strlen()有这样的代码(删除了注释和64位实现):
size_t strlen(const char *str)
{
const char *char_ptr;
const unsigned long int *longword_ptr;
unsigned long int longword, magic_bits, himagic, lomagic;
for (char_ptr = str; ((unsigned long int) char_ptr
& (sizeof (longword) - 1)) != 0; ++char_ptr)
if (*char_ptr == '\0')
return char_ptr - str;
longword_ptr = (unsigned long int *) char_ptr;
himagic = 0x80808080L;
lomagic = 0x01010101L;
for (;;)
{
longword = *longword_ptr++;
if (((longword - lomagic) & himagic) …Run Code Online (Sandbox Code Playgroud) 我将内存地址从double转换为整数.即使他们指向相同的地址,为什么值不同?
#include<iostream>
using namespace std;
int main()
{
double d = 2.5;
auto p = (int*)&d;
auto q = &d;
cout<<p<<endl; // prints memory address 0x7fff5fbff660
cout<<q<<endl; // print memory address 0x7fff5fbff660
cout<<*p<<endl; //prints 0
cout<<*q<<endl; // prints 2.5
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但为什么价值不同
0x7fff5fbff660
0x7fff5fbff660
0
2.5
Program ended with exit code: 0
Run Code Online (Sandbox Code Playgroud) 我怎样才能做到这一点:
*(int *)CMSG_DATA(hdr) = fd2pass;
Run Code Online (Sandbox Code Playgroud)
没有GCC提出这个:
error: dereferencing type-punned pointer will break strict-aliasing rules
Run Code Online (Sandbox Code Playgroud)
以与这些选项兼容的方式:
-Wall -Werror -pedantic
Run Code Online (Sandbox Code Playgroud) 对于两个(或更多)structS:Base和Sub具有共同第一(未命名)struct,是安全的转换/从投Base至Sub反之亦然?
struct Base{
struct{
int id;
// ...
};
char data[]; // necessary?
}
struct Sub{
struct{
int id;
// same '...'
};
// actual data
};
Run Code Online (Sandbox Code Playgroud)
这些功能是否保证安全且技术上正确?(另外:零长度char data[]成员是否必要且有用?)
struct Base * subToBase(struct Sub * s){
return (struct Base*)s;
}
struct Sub * baseToSub(struct Base * b){
if(b->id != SUB_ID){
return NULL;
}
return (struct Sub*)b;
}
Run Code Online (Sandbox Code Playgroud)
编辑
我没有计划Base在内部进一步嵌套Sub,而是可以在以后添加其他子类型(直接在下面Base),而无需更改Base …
我正在使用第三方C++库在Julia中做一些繁重的工作.在Julia方面,数据存储在类型的对象中Array{Float64, 2}(这大致类似于2D数组的双精度数).我可以使用指向a的指针将它传递给C++ double.但是,在C++方面,数据存储在一个名为的结构中vector3:
typedef struct _vector3
{
double x, y, z;
} vector3;
Run Code Online (Sandbox Code Playgroud)
我快速而肮脏的方法分为五个步骤:
double*到vector3*vector3*到double*复制大量数据效率非常低.我可以使用一些神秘的技巧来避免复制数据double到struct后面吗?我想以某种方式解释一个1D数组double(大小是3的倍数)作为具有3个double成员的结构的一维数组.