相关疑难解决方法(0)

C和C++中联合的目的

我早先使用过工会; 今天,当我读到这篇文章并开始知道这段代码时,我感到震惊

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)

实际上是未定义的行为即从工会成员读取而不是最近编写的那个导致未定义的行为.如果这不是工会的预期用途,那是什么?有人可以详细解释一下吗?

更新:

事后我想澄清一些事情.

  • 这个问题的答案与C和C++不一样; 我无知的年轻自我将其标记为C和C++.
  • 在仔细研究了C++ 11的标准后,我无法确切地说它调用了访问/检查非活动的union成员是未定义/未指定/实现定义的.我能找到的只是§9.5/ 1:

    如果标准布局联合包含多个共享公共初始序列的标准布局结构,并且如果此标准布局联合类型的对象包含其中一个标准布局结构,则允许检查任何标准布局结构的公共初始序列.标准布局结构成员.§9.2/ 19:如果相应的成员具有布局兼容类型且两个成员都不是位字段,或者两者都是具有相同宽度的位字段,则一个或多个初始序列的两个标准布局结构共享一个公共初始序列成员.

  • 在C中,(C99 TC3 - DR 283以后)这样做是合法的(感谢Pascal Cuoq提出这个问题).但是,如果读取的值对于读取的类型无效(所谓的"陷阱表示"),尝试执行此操作仍会导致未定义的行为.否则,读取的值是实现定义的.
  • C89/90在未指明的行为(附件J)中称之为,而K&R的书称其实施已定义.来自K&R的报价:

    这是联合的目的 - 一个可以合法地保存几种类型中的任何一种的变量.[...]只要用法一致:检索到的类型必须是最近存储的类型.程序员有责任跟踪当前存储在联合中的类型; 如果将某些内容存储为一种类型并将其提取为另一种类型,则结果将依赖于实现. …

c c++ unions type-punning

237
推荐指数
9
解决办法
10万
查看次数

大括号初始化继承的pod

#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是正确的.

c++ pod c++11

11
推荐指数
2
解决办法
2327
查看次数

如何在C++中将unsigned long(DWORD)重新解释为带符号的long?

我想重新解释一个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++ reinterpret-cast unsigned-integer

4
推荐指数
2
解决办法
5279
查看次数

reinterpret_cast <unsigned long>无效的强制转换

我正在使用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>

c++ stl c++11

0
推荐指数
1
解决办法
1138
查看次数

标签 统计

c++ ×4

c++11 ×2

c ×1

pod ×1

reinterpret-cast ×1

stl ×1

type-punning ×1

unions ×1

unsigned-integer ×1