我早先使用过工会; 今天,当我读到这篇文章并开始知道这段代码时,我感到震惊
union ARGB
{
uint32_t colour;
struct componentsTag
{
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a;
} components;
} pixel;
pixel.colour = 0xff040201; // ARGB::colour is the active member from now on
// somewhere down the line, without any edit to pixel
if(pixel.components.a) // accessing the non-active member ARGB::components
Run Code Online (Sandbox Code Playgroud)
实际上是未定义的行为即从工会成员读取而不是最近编写的那个导致未定义的行为.如果这不是工会的预期用途,那是什么?有人可以详细解释一下吗?
更新:
事后我想澄清一些事情.
如果标准布局联合包含多个共享公共初始序列的标准布局结构,并且如果此标准布局联合类型的对象包含其中一个标准布局结构,则允许检查任何标准布局结构的公共初始序列.标准布局结构成员.§9.2/ 19:如果相应的成员具有布局兼容类型且两个成员都不是位字段,或者两者都是具有相同宽度的位字段,则一个或多个初始序列的两个标准布局结构共享一个公共初始序列成员.
C89/90在未指明的行为(附件J)中称之为,而K&R的书称其实施已定义.来自K&R的报价:
这是联合的目的 - 一个可以合法地保存几种类型中的任何一种的变量.[...]只要用法一致:检索到的类型必须是最近存储的类型.程序员有责任跟踪当前存储在联合中的类型; 如果将某些内容存储为一种类型并将其提取为另一种类型,则结果将依赖于实现. …
#include <iostream>
#include <type_traits>
struct base_pod_t {
unsigned x;
};
struct der_pod_t : public base_pod_t { };
int main()
{
std::cout << "base_pod_t is POD: " << std::is_pod<base_pod_t>::value << std::endl;
std::cout << "der_pod_t is POD: " << std::is_pod<der_pod_t>::value << std::endl;
base_pod_t b1 = {}; // OK
base_pod_t b2 = {3}; // OK
der_pod_t p1 = {}; // OK
// der_pod_t p2 = {4}; // ERROR!
}
Run Code Online (Sandbox Code Playgroud)
最后一行导致错误.如何der_pod_t用值来初始化?
似乎即使它是一个POD它试图使用构造函数?
编辑:
由于@Praetorian和@dyb建议它是POD因此结果std::is_pod<der_pod_t>::value是正确的.
我想重新解释一个unsigned long(实际上,a DWORD)作为一个signed long.我试过了:
DWORD x;
long y = reinterpret_cast<signed long>(x);
Run Code Online (Sandbox Code Playgroud)
但是,VC++ 2010 intellisense告诉我"无效的类型转换".为什么?我如何解决它?
我正在使用C++中的Hashtable.哈希函数:
// Default hash function class
template <typename K>
struct KeyHash {
unsigned long operator()(const K& key) const {
return reinterpret_cast<unsigned long>(key) % TABLE_SIZE;
}
};
Run Code Online (Sandbox Code Playgroud)
然后,当我声明哈希表为:
HashTable<int, std::string> hmap;
Run Code Online (Sandbox Code Playgroud)
它显示:
从'int'类型到'unsigned_long_int'的无效转换
这是什么问题reinterpret_cast<unsigned long>?