任何人都可以提供与 static_assert 兼容的 MISRA C++ 兼容 'offsetof' macro/template/function 吗?

Can anybody provide a MISRA C++ compliant 'offsetof' macro/template/function that works with static_assert?

我正在尝试编写防御代码并放置 static_assert<> 以确保结构的成员具有特定的偏移量以满足某些硬件要求

MISRA C++ 规则 18-2-1 规定“不得使用宏 offsetof”,因此我们“取消定义”offsetof。

我们提供了一些模板的东西,但是在static_assert<>

中使用它们都失败了

我一直无法找到适用于 C++11 static_assert<> 跨编译器的东西。

struct Commands
{
    uint32_t command[4];
};

struct DMA_Bundle
{
    struct header_
    {
        uint32_t num_of_elems;
        uint8_t reserved[60];
    } header;
    Commands array[16];
};

我试图确保 array 从头开始​​是 64 个字节。

static_assert(offsetof(DMA_Bundle,array)==64,"zoinks");

确实有效,但 MISRA 说我不能使用它。 (我无法与我们的功能安全人员争论 :/)

我尝试了以下方法,但通常它们不起作用:

static_assert(offsetofarray()==64,"bar");
static_assert(myoffsetof(DMA_Bundle::array)==64,"double_zoinks");

显式 offsetofarray() constexpr 函数在 GCC 7.5.0 下确实有效,但在更高版本的 GCC 和 Clang(我们的嵌入式处理器工具使用的是它)下会失败。它因 'non constant condition for static_assert'.

而失败

另一个似乎抱怨“无效使用非静态数据成员'DMA_Bundle::array'”

而且,无论其价值如何,我仅限于 C++11。

一些背景:

And, for what it's worth, I'm limited to C++11

这是你的第一个问题...

MISRA C++:2008 只允许使用 C++:2003 - 之后的任何内容都超出范围。

MISRA C++ Rule 18-2-1 says "The macro offsetof shall not be used", so we've 'undef'd offsetof.

使用 #undef 违反了 要求的 规则 16-0-3(没有必要 #undef offsetof


现在进入正题:

规则 18-2-1 是一个必需 规则,旨在防止在操作数类型不兼容时发生未定义行为 .

Does works, but MISRA says but I can't use that. (and I can't argue with our functional safety people :/)

许多 clip-board 监视器的问题是他们可以勾选方框,但在不理解 MISRA 实际说什么的情况下采取“MISRA 拒绝”的态度...

我的建议,特别是如果仅在与 static_assert() 相关联时使用,是提出偏差(请参阅第 4.3.2 节和 MISRA 合规性中的扩展指南)。

偏差是一种完全合法的方法,规则可能会造成不便,但未定义的行为不适用。


ETA(注意到与 Lundin 关于 C 的讨论):在 MISRA C:2004 中,有一个等效的指南(规则 20.6)同样对 offsetof - 在 MISRA C:2012 这一笼统的限制被删除,未定义的行为 被通用规则 1.3

捕获

在许多方面,这使得 MISRA C++ 偏差的理由更容易 - 因为基本原理与 MISRA C 决策相匹配。

查看个人资料了解从属关系