这是我的代码.它适用于C,但它的行为类似于C++中的结构.
#include<iostream>
using namespace std;
int main()
{
union myunion
{
int B;
double PI;
};
union myunion numbers;
numbers.PI = 3.14;
numbers.B = 12;
/* now storage of PI should be over-written */
cout<<numbers.PI<<endl;
cout<<numbers.B<<endl;
/* Output is 3.14 */
/* 12 */
/* Why it is behaving like Structures ? */
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我需要我似乎无法弄清楚的编程实验室作业的帮助。
问题是 :
允许用户输入4个整数值(介于0和15之间)。将这4个值存储到一个名为“ packit”的32位整数中,允许用户从“ packit”中选择要恢复的4个整数中的哪个。输入“ 1”将恢复第一个值输入,输入“ 2”将恢复第二个值,“ 3”将恢复第三个值,等等。仅使用位操作来存储和恢复值。
这是我到目前为止的内容:
#include <iostream>
using namespace std;
int getInput(){
int in;
cout << "Input a number: ";
cin >> in;
return in;
}
int main(){
int input1, input2, input3, input4;
int output1, output2, output3, output4;
unsigned int data = 32; // makes room for the 4 integers
input1 = getInput();
input2 = getInput();
input3 = getInput();
input4 = getInput();
data = data << 2; //makes room for the input
data = data …Run Code Online (Sandbox Code Playgroud) union test{
char a; // 1 byte
int b; // 4 bytes
};
int main(){
test t;
t.a = 5;
return t.b;
}
Run Code Online (Sandbox Code Playgroud)
这个链接说:https : //en.cppreference.com/w/cpp/language/union
从最近未写入的联合成员中读取是未定义的行为。
据此,我上面的示例代码有UB吗?如果是这样,那么联盟的意义何在?我认为重点在于从相同的内存位置读取/写入不同的值类型。
如果我需要访问该most recently written值,那么我将只使用常规变量而不是联合。
以前的类似问题没有回答我的问题:
我需要将 a 保存double到 STM32L476 微控制器上的闪存中。闪存控制器在 64 位块中工作,来自 ST 的 HAL API 使用uint64_t参数来写入数据。为此,我需要将 double 变量中的位转换为一个或多个uint64_ts。
我尝试了以下,这是 UB:
uint64_t flash_write_val = *(uint64_t*)&double_value;
Run Code Online (Sandbox Code Playgroud)
但是,我收到有关违反严格别名规则的编译器警告。如果不调用 UB,我将如何做到这一点?它不需要超级便携。它只能在 Cortex M4F 内核上有效。
我在想这个:
union uint64_double {
uint64_t flash_friendly;
double math_friendly;
};
Run Code Online (Sandbox Code Playgroud)
这是一个好方法,还是我还在用脚射击?
在我看来,缓冲区正在被修改.它是否将6个整数和5个浮点数放入缓冲区?他们将大小设置为44而不是1024*sizeof(char)也很奇怪.也许整个缓冲区传递给write()但write()只将前44个字节写入客户端.
你能逐行解释一下吗?我没有使用c ++的经验.
char buf[1024];
int* pInt = reinterpret_cast<int*>(buf);
*pInt = 5;
*(pInt+1) = 2;
*(pInt+2) = 3;
*(pInt+3) = 4;
*(pInt+4) = 5;
*(pInt+5) = 6;
float* pFloat = reinterpret_cast<float*>(pInt+6);
*pFloat = 111;
*(pFloat+1) = 222;
*(pFloat+2) = 333;
*(pFloat+3) = 444;
*(pFloat+4) = 555;
int n;
int size = (1+2*5)*4;
n = write(buf, size);
Run Code Online (Sandbox Code Playgroud) 出于好奇,我查看了如何std::is_pointer实现并看到了这样的东西(多个重载之一):
template <class _Ty>
_INLINE_VAR constexpr bool is_pointer_v<_Ty*> = true;
Run Code Online (Sandbox Code Playgroud)
如果我复制并粘贴到我的代码中并编译,则表示 constexpr 在这里无效。怎么了?
是否可以像我们一样std::is_pointer实现结构体?std::is_reference(不是我愿意,只是好奇所以请不要来找我)
MRE 与 msvc 2019:
template <class _Ty>
inline constexpr bool is_pointer_v<_Ty*> = true;
int main()
{
}
Run Code Online (Sandbox Code Playgroud)
--
Error: error C7568: argument list missing
after assumed function template 'is_pointer_v'
Run Code Online (Sandbox Code Playgroud) 我正在构建一个将在类中使用的缓冲区,并想知道以下内容根据 C++ 标准是否有效:
#include <iostream>
#include <cstdint>
int main() {
alignas(std::int32_t) char A[sizeof(std::int32_t)] = { 1, 0, 0, 0 };
std::int32_t* pA = new (&A) std::int32_t;
std::cout << *pA << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
缓冲区已初始化为char4 字节数组。在结构顶部进行新的放置是否允许我访问下面的位int32_t?我现在可以在不违反标准的情况下以 4char秒(通过buffer对象)或 1 int32_t(通过)访问那里的内存空间吗?pA如果不行,是否可以采取其他方式?
注意:是的,我知道字节序,但在这种情况下,字节序并不重要。这是一个不同的讨论。