“错误”的编译器错误大小的类型 [英] Compiler error for "wrong" sized type
问题描述
结构的大小可能受编译器打包的影响。假设由于某种原因(例如,在固件中),您需要将其作为特定值的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屋!