“错误”的编译器错误大小的类型 [英] Compiler error for "wrong" sized type

查看:70
本文介绍了“错误”的编译器错误大小的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

结构的大小可能受编译器打包的影响。假设由于某种原因(例如,在固件中),您需要将其作为特定值的b $ b。如何让编译器生成错误大小的错误而不是在运行时断言?
生成错误。这是一种方式,

但我不知道它是否可以保证在任何编译器上工作:

1 /(sizeof(struct my_struct)== correct_size);


对我来说,上面会产生错误大小的编译时被零除错误。

有更好的方法吗?


DW

解决方案

David White说:

结构的大小可能会受到编译器打包的影响。假设您出于某种原因需要将其作为特定值(例如,在固件中)。你怎么能让编译器生成错误大小的错误而不是在运行时断言呢?这是一种方法,但我不知道它是否可以保证在任何编译器上工作:1 /(sizeof(struct my_struct)==
correct_size);
<对我来说,上面的错误大小会产生编译时被零除错误。有更好的方法吗?




嗯,我不知道更好,但我喜欢这样:


char DetectWrongSize [(sizeof(struct my_struct)== correct_size)* 2 - 1];


如果结构的大小错误,这将产生一个负大小的数组,

这是非法的。


-

Richard Heathfield

Usenet是一个奇怪的放置" - dmr 29/7/1999
http://www.cpax.org.uk

电子邮件:rjh在上面的域名(但显然放弃了www)


David White发布:
< blockquote class =post_quotes>结构的大小可能受编译器打包的影响。假设您出于某种原因(例如,在固件中)将其视为特定值。你怎么能让编译器生成错误大小的错误而不是在运行时断言呢?这是一种方法,但我不知道它是否可以保证在任何编译器上工作:1 /(sizeof(struct my_struct)==
correct_size);
<对我来说,上面的错误大小会产生编译时被零除错误。有更好的方法吗?

DW



为了消除填充(即将每个成员准确存储在你想要的位置),

你可以使用指针技巧。


例如,而不是:


typedef struct Monkey {

int i;

char b;

int j;

};


你可以拥有下列。 (它不漂亮,但你可以清理它

并给它一个漂亮的界面。)

typedef char Monkey [2 * sizeof(int)+ 1 ];

然后你有访问每个成员的函数:


void SetI(Monkey * const m,int const val)

{

*((int *)m)= val;

}


int GetI(const Monkey * const m)

{

return *((const int *)m);

}


void SetB(Monkey * const m,char const val)

{

*((char *)m + sizeof(int))= val;

}


char GetB(const Monkey * const m)

{

return *((const char * )m + sizeof(int));

}


void SetJ(Monkey * const m,int const val)

{

*((int *)((char *)m + sizeof(int)+ 1))= val;

}


int GetJ(const Monkey * const m)

{

return *((const int *)((const char *)m + sizeof(int) + 1));

}

-Tomás


"Tomás" < NU ** @ NULL.NULL>写道:

[...]

为了消除填充(即将每个成员准确存储在你想要的位置),
你可以使用指针技巧。 br />
例如,而不是:

typedef struct Monkey {
int i;
char b;
int j;
};

您可以拥有以下内容。 (它不漂亮,但你可以清理它并给它一个漂亮的界面。)

typedef char Monkey [2 * sizeof(int)+ 1];

然后你有访问每个成员的函数:
[snip] void SetJ(Monkey * const m,int const val)
{
*((int *) ((char *)m + sizeof(int)+ 1))= val;
}
int GetJ(const Monkey * const m)

返回*((const int *)((const char *)m + sizeof(int)+ 1));
}




这访问一个未对齐的int 。在许多系统中,它会导致陷阱。


-

Keith Thompson(The_Other_Keith) ks *** @ mib.org < http://www.ghoti.net/~kst>

圣地亚哥超级计算机中心< *> < http://users.sdsc.edu/~kst>

我们必须做点什么。这是事情。因此,我们必须这样做。


The size of a struct can be affected by compiler packing. Suppose you need it to be a
specific value for some reason (e.g., in firmware). How can you get the compiler to
generate an error for the wrong size rather than assert it at run-time? Here is one way,
but I don''t know if it''s guaranteed to work on any compiler:
1/(sizeof(struct my_struct) == correct_size);

For me, the above produces a compile-time divide-by-zero error for the wrong size. Is
there a better way?

DW

解决方案

David White said:

The size of a struct can be affected by compiler packing. Suppose you need
it to be a specific value for some reason (e.g., in firmware). How can you
get the compiler to generate an error for the wrong size rather than
assert it at run-time? Here is one way, but I don''t know if it''s
guaranteed to work on any compiler: 1/(sizeof(struct my_struct) ==
correct_size);

For me, the above produces a compile-time divide-by-zero error for the
wrong size. Is there a better way?



Well, I don''t know about "better", but I like this:

char DetectWrongSize[(sizeof(struct my_struct) == correct_size) * 2 - 1];

If the struct is the wrong size, this will yield a negatively sized array,
which is illegal.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)


David White posted:

The size of a struct can be affected by compiler packing. Suppose you
need it to be a specific value for some reason (e.g., in firmware). How
can you get the compiler to generate an error for the wrong size rather
than assert it at run-time? Here is one way, but I don''t know if it''s
guaranteed to work on any compiler: 1/(sizeof(struct my_struct) ==
correct_size);

For me, the above produces a compile-time divide-by-zero error for the
wrong size. Is there a better way?

DW


To eliminate the padding (i.e. store each member exactly where you want it),
you could use pointer trickery.

For example, instead of having:

typedef struct Monkey {
int i;
char b;
int j;
};

You could have the following. (It''s not pretty, but you could clean it up
and give it a nice interface).
typedef char Monkey[ 2 * sizeof(int) + 1 ];
And then you have functions to access each member:

void SetI( Monkey* const m, int const val )
{
*( (int*)m ) = val;
}

int GetI( const Monkey* const m )
{
return *( (const int*)m );
}

void SetB( Monkey* const m, char const val )
{
*( (char*)m + sizeof(int) ) = val;
}

char GetB( const Monkey* const m )
{
return *( (const char*)m + sizeof(int) );
}

void SetJ( Monkey* const m, int const val )
{
*( (int*)( (char*)m + sizeof(int) + 1 ) ) = val;
}

int GetJ( const Monkey* const m )
{
return *( (const int*)( (const char*)m + sizeof(int) + 1 ) );
}
-Tomás


"Tomás" <NU**@NULL.NULL> writes:
[...]

To eliminate the padding (i.e. store each member exactly where you want it),
you could use pointer trickery.

For example, instead of having:

typedef struct Monkey {
int i;
char b;
int j;
};

You could have the following. (It''s not pretty, but you could clean it up
and give it a nice interface).
typedef char Monkey[ 2 * sizeof(int) + 1 ];
And then you have functions to access each member: [snip] void SetJ( Monkey* const m, int const val )
{
*( (int*)( (char*)m + sizeof(int) + 1 ) ) = val;
}

int GetJ( const Monkey* const m )
{
return *( (const int*)( (const char*)m + sizeof(int) + 1 ) );
}



This access a misaligned int. On many systems, it will cause a trap.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.


这篇关于“错误”的编译器错误大小的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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