如何确保两种类型具有相同的大小?

发布于 2024-12-08 09:28:16 字数 541 浏览 0 评论 0原文

在我的代码中,我想确保 sizeof(a) == sizeof(b)

第一种方法是让预处理器进行检查:

#if (sizeof(a) != sizeof(b))
#  error sizes don't match
#endif

由于致命错误 C1017:无效的整数常量表达式而无法编译。好的。理解。

下一步尝试:

if(sizeof(a) != sizeof(b)){
  printf("sizes don't match\n");
  return -1;
}

这会导致警告:警告 C4127:条件表达式为常量

现在,我被困住了。是否有一种无警告和错误的方法来确保两个结构体 ab 具有相同的大小?


编辑: 编译器是Visual Studio 2005,警告级别设置为4。

In my code, I want to ensure that sizeof(a) == sizeof(b).

First approach was to let the preprocessor do the checking:

#if (sizeof(a) != sizeof(b))
#  error sizes don't match
#endif

which doesn't compile because of fatal error C1017: invalid integer constant expression. Okay. Understand.

Next try:

if(sizeof(a) != sizeof(b)){
  printf("sizes don't match\n");
  return -1;
}

Which results in a warning: warning C4127: conditional expression is constant.

Now, I'm stuck. Is there a warning-and-error-free way to make sure that the two structs a and b have the same size?


Edit:
Compiler is Visual Studio 2005, Warning level is set to 4.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

蓝咒 2024-12-15 09:28:16

错误的数组大小

// make sure sizeof(a) == sizeof(b):
int size_must_match[sizeof(a) == sizeof(b)];
// will fail if sizeof(a) == sizeof(b) evaluates to 0
// might produce warning: 'size_must_match' is not used 

// to suppress "'size_must_match' is not used", try:
size_must_match[0]; // might produce warning: "statement has no effect"

typedef int size_must_match[sizeof(a) == sizeof(b)];

错误的编译时算术

在 C++ 中可以保证编译器在编译时计算这些常量表达式,我相信 C:

// make sure sizeof(a) == sizeof(b):
1 / (sizeof(a) == sizeof(b));
// might produce warning: "statement has no effect"

int size_must_match = 1 / (sizeof(a) == sizeof(b));
// might produce warning: 'size_must_match' is unused

assert (1 / (sizeof(a) == sizeof(b)));
// very silly way to use assert!

Switch 中也同样如此(只是为了好玩)

switch (0) { // compiler might complain that the 
             // controlling expression is constant
case 0:       
case sizeof(a) == sizeof(b):
    ; // nothing to do
}

你明白了。尝试一下这个,直到编译器 100% 满意为止。

Bad array size

// make sure sizeof(a) == sizeof(b):
int size_must_match[sizeof(a) == sizeof(b)];
// will fail if sizeof(a) == sizeof(b) evaluates to 0
// might produce warning: 'size_must_match' is not used 

// to suppress "'size_must_match' is not used", try:
size_must_match[0]; // might produce warning: "statement has no effect"

or

typedef int size_must_match[sizeof(a) == sizeof(b)];

Bad compile-time arithmetic

In C++ is guaranteed that these constant expressions are evaluated by the compiler at compile-time, and I believe the same holds in C:

// make sure sizeof(a) == sizeof(b):
1 / (sizeof(a) == sizeof(b));
// might produce warning: "statement has no effect"

int size_must_match = 1 / (sizeof(a) == sizeof(b));
// might produce warning: 'size_must_match' is unused

assert (1 / (sizeof(a) == sizeof(b)));
// very silly way to use assert!

Switch (just for fun)

switch (0) { // compiler might complain that the 
             // controlling expression is constant
case 0:       
case sizeof(a) == sizeof(b):
    ; // nothing to do
}

You get the idea. Just play around with this until the compiler is 100 % happy.

゛时过境迁 2024-12-15 09:28:16

根据 #if 文档明确禁止第一种情况:

表达式不能使用 sizeof 或类型转换运算符。

至于警告,您可以忽略它(因为您知道您的代码没问题),使用 #pragma 禁用它,或者只是从 if 中取出条件:

bool sizeMatch = (sizeof(a) == sizeof(b));
if (!sizeMatch){
    printf("sizes don't match\n");
    return -1;
}

编辑:由于禁用错误似乎引起了一些注意,这里有几种使用 #pragma warning

#pragma warning (push) 
#pragma warning (disable: 4127)
    if(sizeof(a) != sizeof(b)){
#pragma warning (pop) 
          // ...

弹出显然可以在代码中进一步完成。另一种选择可能是:

#pragma warning (disable: 4127)
    if(sizeof(a) != sizeof(b)){
#pragma warning (default: 4127) 

这将在不推送和弹出的情况下重新打开警告。

不管怎样,这段代码看起来确实很难看。 IMO,仅使用 bool 来获取 sizeof 比较的结果(如我的第一个代码片段所示)将是最干净的解决方案。

The first case is explicitly forbidden according to #if documentation:

The expression cannot use sizeof or a type-cast operator.

As for the warning, you can either ignore it (because you know your code is ok), disable it using a #pragma, or just take the condition out of the if:

bool sizeMatch = (sizeof(a) == sizeof(b));
if (!sizeMatch){
    printf("sizes don't match\n");
    return -1;
}

Edit: since disabling the error seems to have drawn some attention, here are a couple of ways to achieve that using #pragma warning:

#pragma warning (push) 
#pragma warning (disable: 4127)
    if(sizeof(a) != sizeof(b)){
#pragma warning (pop) 
          // ...

The pop could obviously be done further down the code. Another option could be:

#pragma warning (disable: 4127)
    if(sizeof(a) != sizeof(b)){
#pragma warning (default: 4127) 

Which will turn the warning back on without pushing and popping.

Either way, this code does look ugly. IMO, just using a bool to get the result of the sizeof comparison (as my first snippet shows) would be the cleanest solution.

や莫失莫忘 2024-12-15 09:28:16
#include <stdio.h>

struct tag {
int a;
};
main() {
    struct tag a,b;
        if(sizeof(a) != sizeof(b))
        printf("not");
    else
        printf("same");

}

这个程序运行良好,没有任何警告......!!!

#include <stdio.h>

struct tag {
int a;
};
main() {
    struct tag a,b;
        if(sizeof(a) != sizeof(b))
        printf("not");
    else
        printf("same");

}

this programs works fine without any warning...!!!

ゞ花落谁相伴 2024-12-15 09:28:16

虽然可以与编译器玩捉迷藏,并将常量条件隐藏在编译器看不到的地方,但这并不是抑制警告的最佳方法。它只会让代码对于下一个要维护它的人来说显得不必要的晦涩。

如果您需要抑制编译器警告,请明确说明。在 Visual Studio 2005 中,最好使用编译指示:

http://msdn.microsoft.com/en-us/library/2c8f766e(v=vs.80).aspx

While it is possible to play hide and seek with the compiler and hide the constant conditional in places the compiler cannot see it, it's not the best way to suppress warnings. It will only make the code seem unnecessarily obscure for the next person who is going to maintain it.

If you need to suppress compiler warnings, please be explicit about it. In Visual Studio 2005, you are best off using pragmas:

http://msdn.microsoft.com/en-us/library/2c8f766e(v=vs.80).aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文