检查 GUID 是否为空(在 C 中) [英] Check if GUID is empty (in C)

查看:46
本文介绍了检查 GUID 是否为空(在 C 中)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想检查一个 GUID 结构是否为空/所有字段都是 0.这是我写的代码:

I want to check if a GUID structure is empty/all fields are 0. This is the code I wrote:

#include <windows.h>

static BOOL IsEmptyGuid(const GUID * const pGuid)
{
    return \
    (pGuid->Data1 == 0) &&
    (pGuid->Data2 == 0) &&
    (pGuid->Data3 == 0) &&
#ifdef _WIN64
    (*(DWORD64 *)pGuid->Data4 == 0);
#else
    (*(DWORD *)pGuid->Data4 == 0) && (*(DWORD *)(pGuid->Data4 + 4) == 0);
#endif
}

/* GUID definition from MSDN
typedef struct _GUID {
    DWORD Data1;
    WORD  Data2;
    WORD  Data3;
    BYTE  Data4[8];
} GUID;
*/


int main() {
    GUID guid1;
    guid1.Data1 = 0;
    guid1.Data2 = 0;
    guid1.Data3 = 0;
    memset(guid1.Data4, 0x0, 8);

    printf("Result: %u\n", IsEmptyGuid(&guid1));
}

检查字段 Data4 是否等于 0 的更安全方法是遍历每个字节并检查其值.但是,我发现上面的代码更具表现力.

A safer way to check if field Data4 equals 0 is to iterate over every byte and check for it's value. But, I find the code from above more expressive.

我想知道,对吗?安全吗?

I would like to know, is it correct? Is it safe?

谢谢!

推荐答案

代码不正确.它违反了严格的别名规则(N1570 §6.5 p7),导致未定义的行为.

Code is incorrect. It breaks strict aliasing rule (N1570 §6.5 p7), causing undefined behaviour.

一个对象只能通过左值表达式访问其存储的值,该表达式具有以下之一以下类型:88)

An object shall have its stored value accessed only by an lvalue expression that has one of the following types: 88)

  • 与对象的有效类型兼容的类型,
  • 与对象的有效类型兼容的类型的限定版本,
  • 一个类型,它是对应于有效类型的有符号或无符号类型对象,
  • 一种类型,它是对应于限定版本的有符号或无符号类型对象的有效类型,
  • 一个聚合或联合类型,其中包括上述类型之一成员(包括递归地,子聚合或包含联合的成员),或
  • 一种字符类型.

88) 此列表的目的是指定对象可以或不可以别名的情况.

确切地说,UB 在您使用非匹配类型取消引用指针时发生:

To be exact, UB happens when you dereference pointer using non-matching type:

DWORD64 * temp = (DWORD64 *)pGuid->Data4; // Allowed, but implementation defined
DWORD64 temp2 = *temp;                    // Undefined behaviour

使用循环单独检查每个元素,或与 memcmp 比较到相同大小的零填充数组.

Use loop to check each element individually, or compare with memcmp to zero filled array of the same size.

如评论中所述,某些编译器允许禁用严格别名,但应避免这样做,因为它会降低代码的可移植性,并且您仍然存在潜在的对齐问题.

As noted in the comments, some compilers allow disabling strict aliasing, but that should be avoided as it makes code less portable, and you still have potential alignment issues.

这篇关于检查 GUID 是否为空(在 C 中)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆